59 assert(scip && cliquepaths);
79 assert(scip && cliquepaths);
94 const int* nprevedges,
102 const int nprevs = nprevedges[k];
106 if( nprevs != maxnprevs + 1 )
109 const int e2 = e / 2;
110 assert(nprevs <= maxnprevs);
113 for( i = 0; i < nprevs; i++ )
115 const int prevedge = prevedges[maxnprevs * k + i];
124 assert(e2 == prevedges[maxnprevs * k + i]);
128 dist_e = dist[k] + cost[e];
132 dist_e = dist[k] + cost[e];
141 const int* prevNPterms,
142 const int* nprevNPterms,
154 assert(termmark[m] == 1 || termmark[m] == 2 );
156 if( termmark[m] == 2 || !visited[m] )
158 distnewP =
MAX(0.0, distnewP - prize[m]);
162 const int nprevs = nprevNPterms[k];
165 if( nprevs != maxnprevs + 1 )
168 assert(nprevs <= maxnprevs);
171 for( i = 0; i < nprevs; i++ )
173 const int prevterm = prevNPterms[maxnprevs * k + i];
181 distnewP =
MAX(0.0, distnewP - prize[m]);
196 const int* prevterms,
197 const int* nprevterms,
201 const int nprevs = nprevterms[prednode];
209 if( nprevs > maxnprevs )
211 assert(nprevs == maxnprevs + 1);
215 for(
int i = 0; i < nprevs; i++ )
217 const int prevterm = prevterms[maxnprevs * prednode + i];
218 assert(prevterm >= 0);
220 if( prevterm == node )
241 const int predsize = nprevterms[prednode];
244 assert(predsize <= maxnprevs + 1);
246 if( predsize == maxnprevs + 1 || (isterm && predsize == maxnprevs) )
248 nprevterms[node] = maxnprevs + 1;
253 for(
int j = 0; j < predsize; j++ )
254 assert(prevterms[maxnprevs * prednode + j] != node);
257 for(
int i = 0; i < predsize; i++ )
258 prevterms[maxnprevs * node + i] = prevterms[maxnprevs * prednode + i];
260 nprevterms[node] = predsize;
264 assert(predsize < maxnprevs);
265 prevterms[maxnprevs * node + predsize] = node;
269 assert(nprevterms[node] <= maxnprevs);
283 const int predsize = nprev[prednode];
285 assert(predsize <= maxnprevs);
288 for(
int i = 0; i < predsize; i++ )
289 prev[maxnprevs * node + i] = prev[maxnprevs * prednode + i];
291 nprev[node] = predsize;
311 int predsize = nprevterms[prednode];
316 if( predsize == maxnprevs + 1 || (termmark[node] == 2 && predsize == maxnprevs) )
318 nprevterms[node] = maxnprevs + 1;
323 for(
int j = 0; j < predsize; j++ )
324 assert(prevterms[maxnprevs * prednode + j] != node);
329 if( termmark[node] == 2 )
331 assert(predsize < maxnprevs);
332 prevterms[maxnprevs * node + predsize] = node;
336 assert(nprevterms[node] <= maxnprevs);
344 nprevNPterms[node] = 0;
345 nprevedges[node] = 0;
349 predsize = nprevedges[prednode];
351 if( predsize >= maxnprevs )
353 assert(predsize == maxnprevs || predsize == maxnprevs + 1);
355 nprevedges[node] = maxnprevs + 1;
356 nprevNPterms[node] = maxnprevs + 1;
359 assert(predsize < maxnprevs);
363 prevedges[maxnprevs * node + predsize] = edge / 2;
366 assert(nprevedges[node] <= maxnprevs);
371 predsize = nprevNPterms[prednode];
373 if( predsize == maxnprevs + 1 || (termmark[node] == 1 && predsize == maxnprevs) )
375 nprevNPterms[node] = maxnprevs + 1;
381 if( termmark[node] == 1 )
383 assert(predsize < maxnprevs);
384 prevNPterms[maxnprevs * node + predsize] = node;
385 nprevNPterms[node]++;
388 assert(nprevNPterms[node] <= maxnprevs);
396 const int* visitlist,
402 for(
int k = 0; k < nvisits; k++ )
404 const int node = visitlist[k];
407 visited[node] =
FALSE;
428 pathdist[node] = newcost;
432 heap[++(*count)] = node;
433 state[node] = (*count);
441 while( (j > 1) && pathdist[heap[c]] > pathdist[heap[j]] )
443 const int t = heap[c];
463 const int* baseToClique
466 const int base_new = nodes_base[newnode];
467 const int base_pred = nodes_base[prednode];
468 const int id_new = baseToClique[base_new];
469 const int id_pred = baseToClique[base_pred];
470 const int id_min = MIN(id_new, id_pred);
471 const int id_max =
MAX(id_new, id_pred);
475 assert(id_max <= ncliquenodes);
476 assert(id_min < id_max);
478 for(
int k = 1; k <= id_min; k++ )
480 pos += (ncliquenodes - k);
483 pos += (id_max - id_min - 1);
484 assert(pos < ((ncliquenodes) * (ncliquenodes - 1)) / 2);
503 assert(newnode >= 0 && prednode >= 0);
504 assert(newnode != prednode);
505 assert(
GE(nodes_distBaseToMax[prednode], 0.0));
506 assert(
GE(nodes_maxpathprofit[prednode], 0.0));
507 assert(
GE(newprofit, 0.0));
508 assert(
GE(newedgecost, 0.0));
510 if( newprofit > nodes_maxpathprofit[prednode] )
512 nodes_distBaseToMax[newnode] = nodes_dist[prednode];
513 nodes_distFromMax[newnode] = newedgecost;
514 nodes_maxpathprofit[newnode] = newprofit;
518 SCIP_Real bias = MIN(newedgecost, newprofit);
519 bias = MIN(nodes_distFromMax[prednode], bias);
521 nodes_distBaseToMax[newnode] = nodes_distBaseToMax[prednode];
522 nodes_distFromMax[newnode] = nodes_distFromMax[prednode] + newedgecost - bias;
523 nodes_maxpathprofit[newnode] = nodes_maxpathprofit[prednode];
534 DHEAP* RESTRICT dheap,
540 assert(newnode >= 0 && prednode >= 0);
541 assert(newnode != prednode);
546 nodes_pred[newnode] = prednode;
547 nodes_dist[newnode] = newdist;
548 nodes_base[newnode] = nodes_base[prednode];
562 const SCIP_Real distProfitToProfit = distBaseToBase - distBaseToProfit1 - distBaseToProfit2;
563 const SCIP_Real sdAll = distBaseToBase - profit1 - profit2;
564 const SCIP_Real sdProfit1 = distBaseToBase - distBaseToProfit2 - profit1;
565 const SCIP_Real sdProfit2 = distBaseToBase - distBaseToProfit1 - profit2;
568 sdProfit1, sdProfit2,
570 distBaseToProfit1, distBaseToProfit2
574 assert(
GE(distBaseToProfit1, 0.0));
575 assert(
GE(distBaseToProfit2, 0.0));
576 assert(
GE(distProfitToProfit, 0.0));
577 assert(
LE(sd_final, distBaseToBase));
591 const SCIP_Real sdAll = distBaseToBase - profit;
592 const SCIP_Real distBaseToProfit2 = distBaseToBase - distBaseToProfit;
593 SCIP_Real sd_final =
MAX(distBaseToProfit, distBaseToProfit2);
595 if( sdAll > sd_final )
598 assert(
GE(distBaseToProfit, 0.0));
599 assert(
GE(distBaseToProfit2, 0.0));
600 assert(
GE(sd_final, 0.0));
601 assert(
LE(sd_final, distBaseToBase));
618 if( node == prevnode )
625 bias = MIN(edgecost, profit);
631 assert(
GE(bias, 0.0));
642 void sdCliqueStarGetPathSd(
655 int prevnode = startnode;
659 printf(
"go from %d \n", startnode);
661 for(
int node = startnode; node != endnode; node =
nodes_pred[node] )
668 assert(nextnode != node);
672 if( g->
head[e] == nextnode )
680 printf(
"check node %d, profit=%f, edgecost=%f \n", node, profit, g->
cost[e]);
682 offset = MIN(profit, g->
cost[e]);
683 offset = MIN(offset, dist);
685 dist += g->
cost[e] - offset;
687 if( node != startnode && profit - offset > *maxprofit )
689 *maxprofit = profit - offset;
690 *endToMaxDist = dist;
696 assert(
LE(*endToMaxDist, dist));
697 *endToMaxDist = dist - *endToMaxDist;
699 *startToEndDist = dist;
722 const int tail = g->
tail[edge];
723 const int head = g->
head[edge];
727 printf(
"\n tail=%d, head=%d, edgecost=%f \n", tail, head, g->
cost[edge]);
729 sdCliqueStarGetPathSd(sdprofit, g, tail,
nodes_pred, nodes_base, &distBaseToMax_tail, &distBaseToTail, &maxprofit_tail);
730 sdCliqueStarGetPathSd(sdprofit, g, head,
nodes_pred, nodes_base, &distBaseToMax_head, &distBaseToHead, &maxprofit_head);
738 if( bias_tail > bias_head )
740 profit_tail -= bias_tail;
741 distBaseToBase = distBaseToTail + distBaseToHead + edgecost - bias_tail;
745 profit_head -= bias_head;
746 distBaseToBase = distBaseToTail + distBaseToHead + edgecost - bias_head;
749 assert(
GE(profit_tail, 0.0));
750 assert(
GE(profit_head, 0.0));
752 if(
GE(profit_head, maxprofit_head) ||
Is_term(g->
term[head]) )
754 maxprofit_head = profit_head;
755 distBaseToMax_head = distBaseToHead;
758 if(
GE(profit_tail, maxprofit_tail) ||
Is_term(g->
term[tail]) )
760 maxprofit_tail = profit_tail;
761 distBaseToMax_tail = distBaseToTail;
765 printf(
"maxprofit_tail=%f, maxprofit_head=%f \n", maxprofit_tail, maxprofit_head);
767 if(
GT(maxprofit_head, 0.0) &&
GT(maxprofit_tail, 0.0) )
769 sd_final =
sdGet2ProfitsDist(distBaseToBase, distBaseToMax_tail, distBaseToMax_head, maxprofit_tail, maxprofit_head);
771 else if(
GT(maxprofit_tail, 0.0) )
773 sd_final =
sdGet1ProfitDist(distBaseToBase, distBaseToMax_tail, maxprofit_tail);
775 else if(
GT(maxprofit_head, 0.0) )
777 sd_final =
sdGet1ProfitDist(distBaseToBase, distBaseToMax_head, maxprofit_head);
781 sd_final = distBaseToBase;
784 printf(
"sd_final=%f \n", sd_final);
809 if( node == nodes_pred[node] || centernode == node )
811 *maxprofit_node = 0.0;
812 assert(centernode == node ||
EQ(nodes_distBaseToMax[node], 0.0));
813 assert(centernode == node ||
EQ(nodes_maxpathprofit[node], 0.0));
814 assert(centernode == node ||
EQ(nodes_distFromMax[node], 0.0));
822 if( *maxprofit_node < nodes_maxpathprofit[node] )
824 *distToMax = nodes_distBaseToMax[node];
825 *maxprofit_node = nodes_maxpathprofit[node];
826 *distFromMax = nodes_distFromMax[node];
827 *nodeHasMaxProfit =
FALSE;
831 *distToMax = nodes_dist[node];
833 *nodeHasMaxProfit =
TRUE;
854 const int* baseToClique,
859 newnode, prednode, nodes_dist, nodes_base, baseToClique);
861 SCIP_Real sdist = nodes_dist[newnode] + newdist;
863 if( sdprofit !=
NULL )
877 nodes_distFromMax, nodes_maxpathprofit, &distToMax_new, &distFromMax_new, &maxprofit_new, &nodeHasMaxProfit_new);
880 nodes_distFromMax, nodes_maxpathprofit, &distToMax_pred, &distFromMax_pred, &maxprofit_pred, &nodeHasMaxProfit_pred);
882 distBaseToBase = distToMax_pred + distToMax_new + distFromMax_pred + distFromMax_new + edgecost;
884 if( !nodeHasMaxProfit_pred )
887 distBaseToBase -= bias;
889 else if( !nodeHasMaxProfit_new )
892 distBaseToBase -= bias;
895 if(
GT(maxprofit_new, 0.0) &&
GT(maxprofit_pred, 0.0) )
897 sd_final =
sdGet2ProfitsDist(distBaseToBase, distToMax_pred, distToMax_new, maxprofit_pred, maxprofit_new);
899 else if(
GT(maxprofit_pred, 0.0) )
901 sd_final =
sdGet1ProfitDist(distBaseToBase, distToMax_pred, maxprofit_pred);
903 else if(
GT(maxprofit_new, 0.0) )
909 sd_final = distBaseToBase;
912 assert(
LE(sd_final, sdist));
916 assert(nodes_base[newnode] != nodes_base[prednode]);
920 if( sdist < sds[sdposition] )
922 sds[sdposition] = sdist;
936 SCIP_Real* RESTRICT nodes_dist = dijkdata->node_distance;
937 int* RESTRICT visitlist = dijkdata->visitlist;
938 DHEAP* RESTRICT dheap = dijkdata->dheap;
939 const int*
const cliquenodes = cliquedata->
cliquenodes;
947 STP_Bool* RESTRICT visited = dijkdata->node_visited;
949 assert(nodes_dist && nodes_base && dheap && cliquenodes);
950 assert(nodes_distBaseToMax && nodes_maxprofit && nodes_distFromMax);
952 assert(ncliquenodes >= 2);
953 assert(dijkdata->edgelimit >= 0 && dijkdata->edgelimit < 20000);
956 for(
int i = 0; i < g->
knots; i++ )
958 assert(
UNKNOWN == dheap->position[i]);
965 for(
int i = 0; i < ncliquenodes; i++ )
967 const int node = cliquenodes[i];
969 assert(0 <= node && node < g->knots);
972 visited[node] =
TRUE;
973 nodes_base[node] = node;
974 nodes_pred[node] = node;
975 nodes_dist[node] = 0.0;
976 nodes_baseToClique[node] = i;
977 nodes_distBaseToMax[node] = 0.0;
978 nodes_maxprofit[node] = 0.0;
979 nodes_distFromMax[node] = 0.0;
984 dijkdata->nvisits = ncliquenodes;
985 assert(dheap->size == ncliquenodes);
997 const int nsds = (ncliquenodes * (ncliquenodes - 1)) / 2;
1002 for(
int i = 0; i < nsds; i++ )
1006 if( sds[i] > limit )
1010 assert(
GT(limit, 0.0));
1027 SCIP_Real* RESTRICT nodes_dist = dijkdata->node_distance;
1028 DHEAP* RESTRICT dheap = dijkdata->dheap;
1029 STP_Bool* RESTRICT visited = dijkdata->node_visited;
1030 int* RESTRICT visitlist = dijkdata->visitlist;
1031 int*
const state = dheap->
position;
1033 const int*
const gOeat = g->
oeat;
1034 const int*
const gHead = g->
head;
1042 int nvisits = dijkdata->nvisits;
1045 const int centernode = cliquedata->
centernode;
1047 const int limit = dijkdata->edgelimit;
1049 assert(g->
knots > 1);
1050 assert(dheap->size > 1);
1053 while( dheap->size > 0 && nchecks <= limit )
1056 const int k_base = nodes_base[k];
1057 const int k_predNode = nodes_pred[k];
1060 assert(0 <= k_base && k_base < g->knots);
1062 assert(
CONNECT == state[k_base]);
1064 for(
int e = g->
outbeg[k]; e >= 0; e = gOeat[e] )
1066 const int m = gHead[e];
1075 if( useProfit && k != centernode && k != k_predNode && m != k_predNode && m != centernode )
1078 bias = MIN(gCost[e], profit);
1079 bias = MIN(k_dist, bias);
1082 assert(k != k_base ||
EQ(MIN(k_dist, bias), 0.0));
1083 assert(
GE(newdist, 0.0));
1087 if(
GT(newdist, distlimit) )
1093 assert(!visited[m]);
1097 nodes_distFromMax, nodes_maxprofit);
1099 visitlist[nvisits++] = m;
1102 assert(k_base == nodes_base[m]);
1109 if( nodes_base[m] != k_base )
1111 sdCliqueStarUpdateSd(sdprofit, nodes_pred, nodes_distBaseToMax, nodes_distFromMax, nodes_maxprofit,
1112 ncliquenodes, centernode, m, k, newdist, gCost[e], nodes_dist, nodes_base, nodes_baseToClique, sds);
1118 if( nodes_dist[m] > newdist )
1122 nodes_distFromMax, nodes_maxprofit);
1128 dijkdata->nvisits = nvisits;
1154 int*
const state = dheap->
position;
1156 const RANGE*
const RESTRICT range_csr = dcsr->
range;
1157 const int*
const RESTRICT head_csr = dcsr->
head;
1159 const int star_degree = range_csr[star_root].end - range_csr[star_root].start;
1164 assert(dcsr && g && dist && visitlist && nvisits && visited && dheap && success);
1167 assert(g->
mark[star_root] && star_degree >= 1);
1168 assert(dheap->
size == 0);
1169 assert(edgelimit >= 1);
1175 for(
int k = 0; k < g->
knots; k++ )
1184 dist[star_root] = 0.0;
1186 visitlist[(*nvisits)++] = star_root;
1188 for(
int e = range_csr[star_root].start, end = range_csr[star_root].end; e < end; e++ )
1190 const int m = head_csr[e];
1193 assert(!visited[m]);
1195 visitlist[(*nvisits)++] = m;
1197 dist[m] = cost_csr[e];
1203 if( cost_csr[e] > distlimit )
1204 distlimit = cost_csr[e];
1211 while( dheap->
size > 0 && nchecks <= edgelimit )
1215 const int k_start = range_csr[k].start;
1216 const int k_end = range_csr[k].end;
1218 assert(k != star_root);
1220 assert(
LE(dist[k], distlimit));
1222 if( with_zero_edges && k == star_base[k] )
1226 for(
int e = k_start; e < k_end; e++ )
1228 const int m = head_csr[e];
1230 assert(g->
mark[m] && star_base[k] >= 0);
1234 const SCIP_Real distnew = dist[k] + cost_csr[e];
1236 if(
GT(distnew, distlimit) )
1239 if(
LT(distnew, dist[m]) )
1243 visitlist[(*nvisits)++] = m;
1247 if( star_base[m] == m )
1251 star_base[m] = star_base[k];
1254 assert(star_base[m] != m);
1256 else if(
EQ(distnew, dist[m]) && star_base[m] == m )
1258 if( with_zero_edges && star_base[k] == star_base[m] )
1264 assert(star_base[m] != star_base[k]);
1267 star_base[m] = star_base[k];
1270 assert(star_base[m] != m);
1274 if( nstarhits == star_degree )
1276 nchecks = edgelimit + 1;
1284 *success = (nstarhits > 0);
1303 int* RESTRICT visitlist = dijkdata->
visitlist;
1307 int*
const state = dheap->
position;
1309 const RANGE*
const RESTRICT range_csr = dcsr->
range;
1310 const int*
const RESTRICT head_csr = dcsr->
head;
1312 const int star_degree = range_csr[star_root].end - range_csr[star_root].start;
1315 const int edgelimit = dijkdata->
edgelimit;
1319 assert(dcsr && dist && visitlist && visited && dheap && success && sdprofit);
1321 assert(g->
mark[star_root] && star_degree >= 1);
1322 assert(dheap->
size == 0);
1323 assert(edgelimit >= 1);
1331 for(
int k = 0; k <
nnodes; k++ )
1341 dist[star_root] = 0.0;
1343 visitlist[(nvisits)++] = star_root;
1345 for(
int e = range_csr[star_root].start, end = range_csr[star_root].end; e < end; e++ )
1347 const int m = head_csr[e];
1350 assert(!visited[m]);
1352 visitlist[(nvisits)++] = m;
1354 dist[m] = cost_csr[e];
1356 node_predNode[m] = star_root;
1361 if( cost_csr[e] > distlimit )
1362 distlimit = cost_csr[e];
1368 while( dheap->
size > 0 && nchecks <= edgelimit )
1372 const int k_start = range_csr[k].start;
1373 const int k_end = range_csr[k].end;
1374 const int k_pred = node_predNode[k];
1376 assert(k != star_root);
1377 assert(k_pred >= 0 && k_pred < nnodes);
1379 assert(
LE(dist[k], distlimit));
1381 if( k == star_base[k] )
1385 for(
int e = k_start; e < k_end; e++ )
1387 const int m = head_csr[e];
1388 assert(g->
mark[m] && star_base[k] >= 0);
1392 SCIP_Real distnew = dist[k] + cost_csr[e];
1396 profitBias = MIN(profitBias, cost_csr[e]);
1397 profitBias = MIN(profitBias, dist[k]);
1398 distnew -= profitBias;
1401 if(
GT(distnew, distlimit) )
1404 if(
LT(distnew, dist[m]) )
1408 visitlist[(nvisits)++] = m;
1412 if( star_base[m] == m )
1415 node_predNode[m] = k;
1417 star_base[m] = star_base[k];
1420 assert(star_base[m] != m && m != star_root);
1422 else if(
EQ(distnew, dist[m]) && star_base[m] == m )
1424 if( star_base[k] == star_base[m] )
1430 assert(star_base[m] != star_base[k]);
1432 node_predNode[m] = k;
1434 star_base[m] = star_base[k];
1437 assert(star_base[m] != m && m != star_root);
1441 if( nstarhits == star_degree )
1443 nchecks = edgelimit + 1;
1452 *success = (nstarhits > 0);
1472 int* RESTRICT visitlist = dijkdata->
visitlist;
1474 int* RESTRICT node_predNode;
1476 int*
const state = dheap->
position;
1478 const RANGE*
const RESTRICT range_csr = dcsr->
range;
1479 const int*
const RESTRICT head_csr = dcsr->
head;
1482 const int edgelimit = dijkdata->
edgelimit;
1484 assert(dcsr && dist && visitlist && visited && dheap);
1486 assert(dheap->
size == 0);
1487 assert(edgelimit >= 1);
1494 for(
int k = 0; k <
nnodes; k++ )
1501 dist[sourcenode] = 0.0;
1502 visitlist[(nvisits)++] = sourcenode;
1504 node_predNode[sourcenode] = -1;
1508 while( dheap->
size > 0 && nchecks <= edgelimit )
1512 const int k_start = range_csr[k].start;
1513 const int k_end = range_csr[k].end;
1514 const int k_pred = node_predNode[k];
1519 for(
int e = k_start; e < k_end; e++ )
1521 const int m = head_csr[e];
1525 SCIP_Real distnew = dist[k] + cost_csr[e];
1526 if( sdprofit && m != k_pred && k != sourcenode )
1529 profitBias = MIN(profitBias, cost_csr[e]);
1530 profitBias = MIN(profitBias, dist[k]);
1531 distnew -= profitBias;
1534 if(
LT(distnew, dist[m]) )
1538 visitlist[(nvisits)++] = m;
1542 node_predNode[m] = k;
1568 const int* termmark,
1584 const int edgelimit1 = edgelimit / 2;
1587 assert(heap !=
NULL);
1588 assert(dist !=
NULL);
1589 assert(cost !=
NULL);
1590 assert(visitlist !=
NULL);
1591 assert(nvisits !=
NULL);
1592 assert(visited !=
NULL);
1598 if( g->
grad[start] == 0 || g->
grad[end] == 0 )
1601 assert(g->
mark[start] && g->
mark[end]);
1607 visitlist[(*nvisits)++] = start;
1614 const int m = g->
head[e];
1618 assert(!visited[m]);
1620 visitlist[(*nvisits)++] = m;
1623 if( termmark[m] != 0 )
1633 if( ++nchecks > edgelimit1 )
1639 while( count > 0 && nchecks <= edgelimit )
1642 const int k =
nearestX(heap, state, &count, dist);
1643 assert(k != end && k != start);
1644 assert(
SCIPisLE(scip, dist[k], distlimit));
1646 if( termmark[k] == 2 )
1654 const int m = g->
head[e];
1660 if(
SCIPisGT(scip, distnew, distlimit) )
1663 if( termmark[m] != 0 )
1664 distnew =
MAX(distnew - g->
prize[m], 0.0);
1666 if( distnew < dist[m] )
1670 visitlist[(*nvisits)++] = m;
1677 nchecks = edgelimit + 1;
1699 const int* termmark,
1713 const int edgelimit1 = edgelimit / 2;
1714 int*
const state = dheap->
position;
1716 RANGE*
const RESTRICT range_csr = dcsr->
range;
1717 int*
const RESTRICT head_csr = dcsr->
head;
1720 assert(dcsr && g && dist && visitlist && nvisits && visited && dheap);
1723 assert(g->
grad[start] != 0 && g->
grad[end] != 0);
1724 assert(g->
mark[start] && g->
mark[end]);
1725 assert(dheap->
size == 0);
1730 for(
int k = 0; k < g->
knots; k++ )
1737 visitlist[(*nvisits)++] = start;
1739 for(
int e = range_csr[start].start; e < range_csr[start].end; e++ )
1741 const int m = head_csr[e];
1744 if(
SCIPisLE(scip, cost_csr[e], distlimit) && m != end )
1746 assert(!visited[m]);
1748 visitlist[(*nvisits)++] = m;
1751 if( termmark[m] != 0 )
1760 dist[m] = cost_csr[e];
1764 if( ++nchecks > edgelimit1 )
1769 while( dheap->
size > 0 && nchecks <= edgelimit )
1773 const int k_start = range_csr[k].start;
1774 const int k_end = range_csr[k].end;
1776 assert(k != end && k != start);
1777 assert(
SCIPisLE(scip, dist[k], distlimit));
1779 if( termmark[k] == 2 )
1785 for(
int e = k_start; e < k_end; e++ )
1787 const int m = head_csr[e];
1789 if( state[m] !=
CONNECT && m != start )
1791 SCIP_Real distnew = dist[k] + cost_csr[e];
1795 if(
SCIPisGT(scip, distnew, distlimit) )
1798 if( termmark[m] != 0 )
1799 distnew =
MAX(distnew - g->
prize[m], 0.0);
1801 if(
LT(distnew, dist[m]) )
1805 visitlist[(*nvisits)++] = m;
1812 nchecks = edgelimit + 1;
1833 const int* termmark,
1834 const int* stateprev,
1849 const int edgelimit1 = edgelimit / 2;
1850 int*
const state = dheap->
position;
1852 RANGE*
const RESTRICT range_csr = dcsr->
range;
1853 int*
const RESTRICT head_csr = dcsr->
head;
1856 assert(dcsr && g && dist && visitlist && visited && dheap);
1859 assert(g->
grad[start] != 0 && g->
grad[end] != 0);
1860 assert(g->
mark[start] && g->
mark[end]);
1861 assert(dheap->
size == 0);
1866 for(
int k = 0; k < g->
knots; k++ )
1873 visitlist[(*nvisits)++] = start;
1875 for(
int e = range_csr[start].start; e < range_csr[start].end; e++ )
1877 const int m = head_csr[e];
1880 if(
SCIPisLE(scip, cost_csr[e], distlimit) && m != end )
1882 assert(!visited[m]);
1884 if( stateprev && stateprev[m] ==
CONNECT )
1887 visitlist[(*nvisits)++] = m;
1890 if( termmark[m] != 0 )
1899 if( g->
prize[m] > cost_csr[e] )
1901 prizeoffset[m] = cost_csr[e];
1905 prizeoffset[m] = g->
prize[m];
1910 dist[m] = cost_csr[e];
1914 if( ++nchecks > edgelimit1 )
1919 while( dheap->
size > 0 && nchecks <= edgelimit )
1923 const int k_start = range_csr[k].start;
1924 const int k_end = range_csr[k].end;
1926 assert(k != end && k != start);
1927 assert(
SCIPisLE(scip, dist[k], distlimit));
1929 if( termmark[k] == 2 )
1935 for(
int e = k_start; e < k_end; e++ )
1937 const int m = head_csr[e];
1945 if( stateprev && stateprev[m] ==
CONNECT )
1948 distnew = dist[k] + cost_csr[e];
1952 if( distnew > distlimit )
1955 if( termmark[m] != 0 )
1956 distnew =
MAX(distnew - g->
prize[m], 0.0);
1958 if(
LT(distnew, dist[m]) )
1960 if( prizeoffset && termmark[m] != 0 )
1962 const SCIP_Real distnew0 = dist[k] + cost_csr[e];
1964 if( g->
prize[m] > distnew0 )
1966 prizeoffset[m] = distnew0;
1970 prizeoffset[m] = g->
prize[m];
1975 visitlist[(*nvisits)++] = m;
1982 nchecks = edgelimit + 1;
2021 const int edgelimit1 = edgelimit / 2;
2024 assert(heap !=
NULL);
2025 assert(dist !=
NULL);
2026 assert(cost !=
NULL);
2027 assert(visitlist !=
NULL);
2028 assert(nvisits !=
NULL);
2029 assert(visited !=
NULL);
2035 if( g->
grad[start] == 0 || g->
grad[end] == 0 )
2038 assert(g->
mark[start] && g->
mark[end]);
2044 visitlist[(*nvisits)++] = start;
2051 const int m = g->
head[e];
2055 assert(!visited[m]);
2057 visitlist[(*nvisits)++] = m;
2059 sdwalkUpdate(g, m, start, maxnprevs, prevterms, nprevterms);
2071 if( ++nchecks > edgelimit1 )
2075 assert(nprevterms[start] == 0);
2079 while( count > 0 && nchecks <= edgelimit )
2082 const int k =
nearestX(heap, state, &count, dist);
2083 assert(k != end && k != start);
2084 assert(
SCIPisLE(scip, dist[k], distlimit));
2091 const int m = g->
head[e];
2099 if(
SCIPisGT(scip, distnew, distlimit) )
2103 distnew =
MAX(distnew - g->
prize[m], 0.0);
2105 if( distnew < dist[m] )
2110 visitlist[(*nvisits)++] = m;
2117 nchecks = edgelimit + 1;
2125 sdwalkUpdate(g, m, k, maxnprevs, prevterms, nprevterms);
2144 const int* termmark,
2167 const int edgelimit1 = edgelimit / 2;
2170 assert(heap !=
NULL);
2171 assert(dist !=
NULL);
2172 assert(cost !=
NULL);
2173 assert(visitlist !=
NULL);
2174 assert(nvisits !=
NULL);
2175 assert(visited !=
NULL);
2181 if( g->
grad[start] == 0 || g->
grad[end] == 0 )
2184 assert(g->
mark[start] && g->
mark[end]);
2190 visitlist[(*nvisits)++] = start;
2197 const int m = g->
head[e];
2203 assert(!visited[m]);
2205 visitlist[(*nvisits)++] = m;
2208 if( termmark[m] != 0 )
2209 distnew =
MAX(distnew - g->
prize[m], 0.0);
2212 prevterms, nprevterms, prevNPterms, nprevNPterms, prevedges, nprevedges);
2215 if( ++nchecks > edgelimit1 )
2219 assert(nprevterms[start] == 0);
2223 while( count > 0 && nchecks <= edgelimit )
2226 const int k =
nearestX(heap, state, &count, dist);
2227 assert(k != end && k != start);
2228 assert(
SCIPisLE(scip, dist[k], distlimit));
2235 const int m = g->
head[e];
2243 if(
SCIPisGT(scip, distnew, distlimit) )
2246 if( termmark[m] != 0 )
2249 if(
SCIPisLT(scip, distnew, dist[m]) )
2254 visitlist[(*nvisits)++] = m;
2261 nchecks = edgelimit + 1;
2267 if( termmark[m] == 2 &&
sdwalkHasConflict(g, m, k, maxnprevs, prevterms, nprevterms, mvisited) )
2271 prevterms, nprevterms, prevNPterms, nprevNPterms, prevedges, nprevedges);
2288 const int* termmark,
2306 assert(heap !=
NULL);
2307 assert(state !=
NULL);
2308 assert(dist !=
NULL);
2309 assert(cost !=
NULL);
2310 assert(visitlist !=
NULL);
2311 assert(nvisits !=
NULL);
2312 assert(visited !=
NULL);
2316 assert(g->
grad[start] > 0);
2317 assert(g->
mark[start]);
2320 for(
int k = 0; k < g->
knots; k++ )
2323 assert(visited[k] ==
FALSE);
2331 heap[count] = start;
2332 state[start] = count;
2334 visitlist[(*nvisits)++] = start;
2337 while( count > 0 && nchecks <= edgelimit )
2340 const int k =
nearestX(heap, state, &count, dist);
2341 assert(
SCIPisLE(scip, dist[k], prize));
2343 if( termmark[k] == 2 )
2351 const int m = g->
head[e];
2357 if(
SCIPisGT(scip, distnew, prize) )
2360 if( termmark[m] != 0 )
2361 distnew -= g->
prize[m];
2363 if( distnew < dist[m] )
2367 visitlist[(*nvisits)++] = m;
2372 if( endpoint !=
NULL && endpoint[m] )
2376 sdwalkReset(*nvisits, visitlist, dist, state, visited);
2391 sdwalkReset(*nvisits, visitlist, dist, state, visited);
2408 assert(scip && g && cliquedata);
SCIP_RETCODE graph_sdStarBiased(SCIP *scip, const GRAPH *g, const SDPROFIT *sdprofit, int star_root, int *star_base, DIJK *dijkdata, SCIP_Bool *success)
SCIP_Bool graph_sdWalksExt(SCIP *scip, const GRAPH *g, const SCIP_Real *cost, SCIP_Real distlimit, int start, int end, int edgelimit, int maxnprevs, SCIP_Real *dist, int *prevterms, int *nprevterms, int *heap, int *state, int *visitlist, int *nvisits, STP_Bool *visited)
static void sdwalkReset(int nvisits, const int *visitlist, SCIP_Real *dist, int *state, STP_Bool *visited)
static SCIP_Real sdwalkGetdistnewPrize(const int *prevNPterms, const int *nprevNPterms, const int *termmark, const STP_Bool *visited, const SCIP_Real *prize, int k, int m, SCIP_Real distnew, int maxnprevs)
SCIP_Bool graph_sdWalksTriangle(SCIP *scip, const GRAPH *g, const int *termmark, const int *stateprev, SCIP_Real distlimit, int start, int end, int edgelimit, SCIP_Real *prizeoffset, SCIP_Real *dist, int *visitlist, int *nvisits, DHEAP *dheap, STP_Bool *visited)
SCIP_Bool graph_sdWalksExt2(SCIP *scip, const GRAPH *g, const SCIP_Real *cost, const int *termmark, SCIP_Real distlimit, int start, int end, int edgelimit, int maxnprevs, SCIP_Real *dist, int *prevterms, int *nprevterms, int *prevNPterms, int *nprevNPterms, int *prevedges, int *nprevedges, int *heap, int *state, int *visitlist, int *nvisits, STP_Bool *visited)
struct special_distance_clique_paths CLIQUEPATHS
#define SDSTAR_BASE_UNSET
enum SCIP_Retcode SCIP_RETCODE
includes various files containing graph methods used for Steiner tree problems
static void sdCliqueStarUpdateSd(const SDPROFIT *sdprofit, const int *nodes_pred, const SCIP_Real *nodes_baseToMaxDist, const SCIP_Real *nodes_distFromMax, const SCIP_Real *nodes_maxpathprofit, int ncliquenodes, int centernode, int newnode, int prednode, SCIP_Real newdist, SCIP_Real edgecost, const SCIP_Real *nodes_dist, const int *nodes_base, const int *baseToClique, SCIP_Real *RESTRICT sds)
static SCIP_Real sdwalkGetdistnewEdge(const int *prevedges, const int *nprevedges, const SCIP_Real *cost, const SCIP_Real *dist, int k, int e, int maxnprevs)
SCIP_Bool graph_heap_isClean(const DHEAP *)
static int nearestX(int *RESTRICT heap, int *RESTRICT state, int *RESTRICT count, const SCIP_Real *pathdist)
static SCIP_Real sdCliqueStarGetDistLimit(const SDCLIQUE *cliquedata, const SCIP_Real *sds)
#define SCIPfreeBufferArray(scip, ptr)
static void sdCliqueStarInit(const GRAPH *g, SDCLIQUE *cliquedata, CLIQUEPATHS *cliquepaths)
static SCIP_Bool sdwalkHasConflict(const GRAPH *g, int node, int prednode, int maxnprevs, const int *prevterms, const int *nprevterms, const SCIP_Bool nodevisited)
SCIP_Real * node_distance
SCIP_Real miscstp_maxReal(const SCIP_Real *realarr, unsigned nreals)
SCIP_Real SCIPepsilon(SCIP *scip)
static void cliquePathsFreeData(SCIP *scip, CLIQUEPATHS *cliquepaths)
static void sdwalkUpdate(const GRAPH *g, int node, int prednode, int maxnprevs, int *prevterms, int *nprevterms)
static void sdwalkCorrectHeap(int *RESTRICT heap, int *RESTRICT state, int *RESTRICT count, SCIP_Real *RESTRICT pathdist, int node, SCIP_Real newcost)
SCIP_RETCODE graph_sdCloseNodesBiased(SCIP *scip, const GRAPH *g, const SDPROFIT *sdprofit, int sourcenode, DIJK *dijkdata)
SCIP_Real * nodes_maxprofit
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static int sdCliqueStarGetSdPosition(int ncliquenodes, int newnode, int prednode, const SCIP_Real *nodes_dist, const int *nodes_base, const int *baseToClique)
static SCIP_Real reduce_sdprofitGetProfit(const SDPROFIT *sdprofit, int node, int nonsource1, int nonsource2)
#define SCIPallocBufferArray(scip, ptr, num)
static void sdCliqueStarUpdateNodeMaxDist(int newnode, int prednode, const SCIP_Real *nodes_dist, SCIP_Real newprofit, SCIP_Real newedgecost, SCIP_Real *RESTRICT nodes_distBaseToMax, SCIP_Real *RESTRICT nodes_distFromMax, SCIP_Real *RESTRICT nodes_maxpathprofit)
static void sdCliqueStarComputeSds(const GRAPH *g, const SDPROFIT *sdprofit, SDCLIQUE *cliquedata, CLIQUEPATHS *cliquepaths, SCIP_Real *RESTRICT sds)
static SCIP_RETCODE cliquePathsInitData(SCIP *scip, const GRAPH *g, CLIQUEPATHS *cliquepaths)
SCIP_RETCODE graph_sdComputeCliqueStar(SCIP *scip, const GRAPH *g, const SDPROFIT *sdprofit, SDCLIQUE *cliquedata)
static void sdwalkUpdateCopy(int node, int prednode, int maxnprevs, int *prev, int *nprev)
static SCIP_Real sdCliqueStarGetNodeBias(const SDPROFIT *sdprofit, int node, int nextnode, int prevnode, SCIP_Real edgecost, SCIP_Real dist)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void sdCliqueStarUpdateNodeDist(int newnode, int prednode, SCIP_Real newdist, DHEAP *RESTRICT dheap, SCIP_Real *RESTRICT nodes_dist, int *RESTRICT nodes_base, int *RESTRICT nodes_pred)
SCIP_Bool graph_sdWalks_csr(SCIP *scip, const GRAPH *g, const int *termmark, SCIP_Real distlimit, int start, int end, int edgelimit, SCIP_Real *dist, int *visitlist, int *nvisits, DHEAP *dheap, STP_Bool *visited)
SCIP_Bool graph_pc_isPcMw(const GRAPH *)
int graph_heap_deleteMinReturnNode(DHEAP *)
static SCIP_Real sdGet2ProfitsDist(SCIP_Real distBaseToBase, SCIP_Real distBaseToProfit1, SCIP_Real distBaseToProfit2, SCIP_Real profit1, SCIP_Real profit2)
static void sdCliqueStarGetFinalProfitData(const SDPROFIT *sdprofit, int centernode, int node, int neighbor, const SCIP_Real *nodes_dist, const int *nodes_pred, const SCIP_Real *nodes_distBaseToMax, const SCIP_Real *nodes_distFromMax, const SCIP_Real *nodes_maxpathprofit, SCIP_Real *distToMax, SCIP_Real *distFromMax, SCIP_Real *maxprofit_node, SCIP_Bool *nodeHasMaxProfit)
static void sdwalkUpdate2(const int *termmark, int node, int prednode, int edge, int maxnprevs, SCIP_Bool clear, int *prevterms, int *nprevterms, int *prevNPterms, int *nprevNPterms, int *prevedges, int *nprevedges)
int graph_get_nNodes(const GRAPH *)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool graph_sdWalksConnected(SCIP *scip, const GRAPH *g, const int *termmark, const SCIP_Real *cost, const STP_Bool *endpoint, int start, int edgelimit, SCIP_Real *dist, int *visitlist, int *nvisits, STP_Bool *visited, SCIP_Bool resetarrays)
SCIP_Real * nodes_distFromMax
includes (inline) graph heap methods used for Steiner tree problems
void graph_sdStar(SCIP *scip, const GRAPH *g, SCIP_Bool with_zero_edges, int star_root, int edgelimit, int *star_base, SCIP_Real *dist, int *visitlist, int *nvisits, DHEAP *dheap, STP_Bool *visited, SCIP_Bool *success)
includes various reduction methods for Steiner tree problems
void graph_heap_correct(int, SCIP_Real, DHEAP *)
SCIP_Real * nodes_distBaseToMax
static SCIP_Real sdGet1ProfitDist(SCIP_Real distBaseToBase, SCIP_Real distBaseToProfit, SCIP_Real profit)
SCIP_Bool graph_sdWalks(SCIP *scip, const GRAPH *g, const SCIP_Real *cost, const int *termmark, SCIP_Real distlimit, int start, int end, int edgelimit, SCIP_Real *dist, int *heap, int *state, int *visitlist, int *nvisits, STP_Bool *visited)