43 assert(levelstart <= levelend);
45 for(
int i = levelstart; i != levelend; i++ )
47 const int start = dpborder->global_partstarts[i];
48 const int end = dpborder->global_partstarts[i + 1];
51 if( size != end - start )
78 assert(partition[size] == delimiter);
82 for(
int iter = 1; iter <
size; iter++ )
84 if( partition[iter - 1] == delimiter )
86 substarts[++nsubsets] = iter;
90 if( partition[iter - 1] >= partition[iter] )
96 substarts[++nsubsets] = size + 1;
98 for(
int iter = 1; iter < nsubsets; iter++ )
100 const int start_curr = substarts[iter];
101 const int start_prev = substarts[iter - 1];
102 const int start_next = substarts[iter + 1];
104 assert(start_prev < start_curr && start_curr < start_next);
106 if( (start_curr - start_prev) < (start_next - start_curr) )
109 if( (start_curr - start_prev) > (start_next - start_curr) )
115 if( memcmp(&partition[start_prev], &partition[start_curr], start_curr - start_prev) >= 0 )
139 int* subsizes = &dummy[1];
145 for(
int iter = 0; iter <
size; iter++ )
148 for( iter2 = iter + 1; iter2 <
size; iter2++ )
150 if( partition[iter2] == delimiter )
154 subsizes[nsubsets++] = (iter2 - iter) + 1;
157 for(
int i = iter + 1; i < iter2; i++ )
162 for( j = i - 1; curr < partition[j] && j >= 0; j-- )
165 partition[j + 1] = partition[j];
167 partition[j + 1] = curr;
174 for(
int iter = 1; iter <
size; iter++ )
176 if( partition[iter - 1] == delimiter )
179 assert(partition[iter - 1] < partition[iter]);
183 assert(nsubsets >= 1);
188 partition[
size] = delimiter;
190 for(
int i = 1, curr_pos = subsizes[0]; i < nsubsets; i++ )
192 const int curr_size = subsizes[i];
195 assert(curr_size > 0);
197 memcpy(subbuffer, &partition[curr_pos], curr_size *
sizeof(partition[0]));
199 for( j = i - 1, j_pos = curr_pos - subsizes[i - 1];
200 curr_size < subsizes[j] ||
201 (curr_size == subsizes[j] && memcmp(&partition[curr_pos], &partition[j_pos], curr_size) < 0 );
204 assert(j >= 0 && j_pos >= 0);
205 j_pos -= subsizes[j - 1];
206 subsizes[j + 1] = subsizes[j];
208 j_pos += subsizes[j];
209 memmove(&partition[j_pos + curr_size], &partition[j_pos], (curr_pos - j_pos) *
sizeof(partition[0]));
210 memcpy(&partition[j_pos], subbuffer, curr_size *
sizeof(partition[0]));
211 subsizes[j + 1] = curr_size;
212 curr_pos += curr_size;
215 assert(partition[size] == delimiter);
232 const int partsize = borderpartition->
partsize;
234 assert(partsize > 0);
236 if( partitionchars[0] == delimiter )
242 if( partitionchars[partsize - 1] == delimiter )
248 for(
int i = 1; i < partsize; i++ )
250 if( partitionchars[i] == delimiter && partitionchars[i - 1] == delimiter )
257 for(
int i = 0; i < partsize; i++ )
259 const DPB_Ptype borderchar = partitionchars[i];
260 if( borderchar > delimiter )
266 if( borderchar == delimiter )
269 for(
int j = 0; j < partsize; j++ )
271 const DPB_Ptype borderchar2 = partitionchars[j];
273 if( i != j && borderchar == borderchar2 )
292 const int partsize = borderpartition->
partsize;
294 for(
int i = 0; i < partsize; i++ )
296 const DPB_Ptype borderchar = partitionchars[i];
298 if( borderchar == delimiter )
304 printf(
"%d ", borderchar);
316 const DPBPART* borderpartition,
323 const int partsize = borderpartition->
partsize;
328 for(
int i = 0; i < partsize; i++ )
330 const DPB_Ptype borderchar = partitionchars[i];
331 assert(0 <= borderchar && borderchar <= delimiter);
333 if( borderchar == delimiter )
336 if(
LT(borderchardists[(
unsigned char)borderchar],
FARAWAY) )
339 for( startpos = i; startpos > 0; startpos-- )
341 if( partitionchars[startpos] == delimiter )
345 if( partitionchars[startpos] == delimiter )
351 for( ; i < partsize && partitionchars[i] != delimiter; i++ )
353 assert(partitionchars[i] < delimiter);
370 const int globalstart = dpborder->global_partstarts[globalindex];
371 const int globalend = dpborder->global_partstarts[globalindex + 1];
374 assert(0 <= globalindex && globalindex < dpborder->global_npartitions);
375 assert(0 <= delimiter);
376 assert(globalstart < globalend);
378 for(
int i = globalstart; i != globalend; i++ )
380 if( global_partitions[i] == delimiter )
391 const DPBPART* borderpartition,
392 const int* candstarts_sub,
400 const int partsize = borderpartition->
partsize;
404 for(
int i = 0; i < ncandstarts_sub; i++ )
407 const int candstart = candstarts_sub[i];
408 assert(0 <= candstart && candstart < partsize);
410 for(
int j = candstart; j < partsize; j++ )
412 const DPB_Ptype partchar = partitionchars[j];
413 assert(0 <= partchar && partchar <= delimiter_prev);
415 if( partchar == delimiter_prev )
418 if(
LT(borderchardists[(
unsigned char)partchar], minedgecost) )
419 minedgecost = borderchardists[(
unsigned char)partchar];
422 costsum += minedgecost;
427 assert(
GE(costsum, 0.0));
437 const DPBPART* borderpartition,
438 const int* candstarts_sub,
445 int globalend = globalstart;
451 const int partsize = borderpartition->
partsize;
459 assert(globalstart >= 1);
462 for( i = 0; i < ncandstarts_sub; i++ )
464 const int candstart = candstarts_sub[i];
465 assert(0 <= candstart && candstart < partsize);
467 for(
int j = candstart; j < partsize; j++ )
469 const DPB_Ptype partchar = partitionchars[j];
470 assert(0 <= partchar && partchar <= delimiter_prev);
472 if( partchar == delimiter_prev )
475 if( bordercharmap[(
unsigned char)partchar] != -1 )
476 global_partitions[globalend++] = bordercharmap[(
unsigned char)partchar];
479 assert(partitionchars[candstart] < delimiter_prev);
482 partitionchars[candstart] = -partitionchars[candstart] - 1;
483 assert(partitionchars[candstart] < 0);
492 if( globalend == globalstart )
495 for(
int j = 0; j < partsize; j++ )
497 if( partitionchars[j] < 0 )
498 partitionchars[j] = -(partitionchars[j] + 1);
502 for(
int j = 0; j < partsize; j++ )
503 assert(0 <= partitionchars[j] && partitionchars[j] <= delimiter_prev);
511 if( partitionchars[0] >= 0 )
513 assert(delimiter_prev != partitionchars[0]);
514 global_partitions[globalend++] = delimiter_new;
518 for( i = 0; i < partsize; i++ )
520 const DPB_Ptype partchar = partitionchars[i];
523 partitionchars[i] = -(partitionchars[i] + 1);
528 if( partchar == delimiter_prev )
530 assert(i < partsize);
532 if( partitionchars[i + 1] >= 0 )
535 if( delimiter_new == global_partitions[globalend - 1] )
541 global_partitions[globalend++] = delimiter_new;
550 if( bordercharmap[(
unsigned char)partchar] != -1 )
551 global_partitions[globalend++] = bordercharmap[(
unsigned char)partchar];
554 if( delimiter_new == global_partitions[globalend - 1] )
557 if( globalstart == -1 )
559 for(
int j = i + 1; j < partsize; j++ )
561 if( partitionchars[j] < 0 )
562 partitionchars[j] = -(partitionchars[j] + 1);
567 for(
int j = 0; j < partsize; j++ )
568 assert(0 <= partitionchars[j] && partitionchars[j] <= delimiter_prev);
571 if( globalstart != -1 )
574 const int partition_length = globalend - globalstart;
577 partition.
partchars = &(global_partitions[globalstart]);
578 partition.
partsize = (globalend - globalstart);
580 printf(
"new (sub) partition \n");
587 printf(
"sorted: \n");
609 assert(
LT(dpborder->global_partcosts[position],
FARAWAY));
610 assert(0 == memcmp(&global_partitions[globalstart], &global_partitions[dpborder->global_partstarts[position]], partition_length));
614 printf(
"final new (sub) partition glbpos=%d \n", position);
617 assert(1 <= position && position < dpborder->global_npartitions);
635 const DPBPART* borderpartition,
640 int partition_length;
642 int globalend = globalstart;
647 const int partsize = borderpartition->
partsize;
653 assert(globalstart + partsize < dpborder->global_partcap);
654 assert(globalstart >= 1);
656 for(
int i = 0; i < partsize; i++ )
658 const DPB_Ptype partchar = partitionchars[i];
659 assert(0 <= partchar && partchar <= borderpartition->delimiter);
660 assert(partchar != borderpartition->
delimiter || bordercharmap[(
unsigned char)partchar] == delimiter_new);
662 if( bordercharmap[(
unsigned char)partchar] != -1 )
663 global_partitions[globalend++] = bordercharmap[(
unsigned char)partchar];
666 if( globalstart == globalend
667 || global_partitions[globalstart] == delimiter_new
668 || global_partitions[globalend - 1] == delimiter_new )
674 for(
int i = globalstart + 1; i != globalend; i++ )
676 if( global_partitions[i] == delimiter_new && global_partitions[i - 1] == delimiter_new )
683 partition_length = (globalend - globalstart);
686 partition.
partchars = &(global_partitions[globalstart]);
687 partition.
partsize = partition_length;
689 printf(
"new (exclusive sub) partition \n");
695 printf(
"sorted: \n");
717 assert(
LT(dpborder->global_partcosts[position],
FARAWAY));
718 assert(0 == memcmp(&global_partitions[globalstart], &global_partitions[dpborder->global_partstarts[position]], partition_length));
722 printf(
"final new (sub) partition glbpos=%d \n", position);
724 assert(1 <= position && position < dpborder->global_npartitions);
743 const STP_Vectype(
int) global_partstarts = dpborder->global_partstarts;
748 assert(dpborder && nodes_isSol);
753 for(
int pos = optposition; pos != 0; pos = dpborder->global_predparts[pos] )
756 for(
int pos = optposition, level = nlevels; pos != 0; pos = dpborder->global_predparts[pos], level-- )
758 const int globalend = global_partstarts[pos + 1];
759 const STP_Vectype(
int) nodemap = dpborder->borderlevels[level]->bordernodesMapToOrg;
763 assert(0 <= pos && pos < dpborder->global_npartitions);
764 assert(global_partstarts[pos + 1] > global_partstarts[pos]);
769 global_partstarts[pos + 1] - global_partstarts[pos], global_partstarts[pos], globalend);
771 if( dpborder->global_partsUseExt[pos] )
773 const int extnode = dpborder->borderlevels[level]->extnode;
774 assert(0 <= extnode && extnode < nnodes);
777 nodes_isSol[extnode] =
TRUE;
780 for(
int i = global_partstarts[pos]; i != globalend; i++ )
782 const DPB_Ptype borderchar = global_partitions[i];
783 assert(0 <= borderchar && borderchar <= delimiter);
785 if( borderchar != delimiter )
787 const int node = nodemap[(
unsigned char)borderchar];
789 assert(0 <= node && node < nnodes);
791 nodes_isSol[node] =
TRUE;
796 SCIPdebugMessage(
"final solnode=%d \n", dpborder->borderlevels[0]->extnode);
797 nodes_isSol[dpborder->borderlevels[0]->extnode] =
TRUE;
#define StpVecGetSize(vec)
int dpborder_partGetIdxNew(SCIP *scip, const DPBPART *borderpartition, const int *candstarts_sub, int ncandstarts_sub, DPBORDER *dpborder)
static SCIP_Bool partitionIsSorted(const DPB_Ptype *partition, DPB_Ptype delimiter, int size)
static SCIP_RETCODE doCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *suffix, SCIP_VAR **fixedvars, SCIP_Real *fixedvals, int nfixedvars, SCIP_Bool useconscompression, SCIP_Bool global, SCIP_Bool original, SCIP_Bool enablepricing, SCIP_Bool threadsafe, SCIP_Bool passmessagehdlr, SCIP_Bool *valid)
static SCIP_Bool partitionIsIncluded(const DPBORDER *dpborder, const DPB_Ptype *partition, int size)
static DPBLEVEL * dpborder_getTopLevel(const DPBORDER *dpborder)
static int dpborder_getTopDelimiter(const DPBORDER *dpborder)
void dpborder_markSolNodes(const DPBORDER *dpborder, STP_Bool *RESTRICT nodes_isSol)
DPB_Ptype * global_partitions
SCIP_Real dpborder_partGetConnectionCost(const DPBORDER *dpborder, const DPBPART *borderpartition, const int *candstarts_sub, int ncandstarts_sub)
static int hashmap_get(const struct hashmap_s *const hashmap, int position, const unsigned len) HASHMAP_USED
Get an element from the hashmap.
void dpborder_partPrint(const DPBPART *borderpartition)
int dpborder_partglobalGetCard(int globalindex, int delimiter, const DPBORDER *dpborder)
#define BPBORDER_MAXBORDERSIZE
static int dpborder_getDelimiter(const DPBORDER *dpborder, int iteration)
static void hashmap_put(struct hashmap_s *const hashmap, int position, const unsigned len, int value) HASHMAP_USED
SCIP_Real * borderchardists
Dynamic programming solver for Steiner tree (sub-) problems with small border.
Dynamic programming internals for Steiner tree (sub-) problems with small number of terminals...
#define StpVecPushBack(scip, vec, value)
static void partitionSortSubsets(DPB_Ptype *RESTRICT partition, DPB_Ptype delimiter, int size)
#define BMSclearMemoryArray(ptr, num)
SCIP_Bool dpborder_partIsValid(const DPBPART *borderpartition)
int dpborder_partGetIdxNewExclusive(SCIP *scip, const DPBPART *borderpartition, DPBORDER *dpborder)