49 path[l].dist = path[k].dist + cost;
62 while( (j > 1) && path[heap[c]].dist > path[heap[j]].dist )
89 heap[1] = heap[(*count)--];
93 if (
LT(path[heap[3]].dist, path[heap[2]].dist))
96 while((c <= (*count)) &&
GT(path[heap[j]].dist, path[heap[c]].dist))
106 if ((c + 1) <= (*count))
107 if (
LT(path[heap[c + 1]].dist, path[heap[c]].dist))
129 for(
int i = 0; i <
nnodes; i++ )
165 const int*
const gOeat = g->
oeat;
166 const int*
const gHead = g->
head;
168 assert(dheap->
size > 0);
172 while( dheap->
size > 0 )
177 for(
int e = g->
outbeg[k]; e >= 0; e = gOeat[e] )
179 const int m = gHead[e];
183 const SCIP_Real newdist = nodes_dist[k] + gCost[e];
186 if(
GT(nodes_dist[m], newdist) )
190 nodes_dist[m] = newdist;
191 nodes_base[m] = nodes_base[k];
213 const int*
const gOeat = g->
oeat;
214 const int*
const gHead = g->
head;
216 assert(dheap->
size > 0);
220 while( dheap->
size > 0 )
223 const int k_predNode = (nodes_pred[k] >= 0) ? g->
tail[nodes_pred[k]] : -1;
228 for(
int e = g->
outbeg[k]; e >= 0; e = gOeat[e] )
230 const int m = gHead[e];
235 const SCIP_Real bias = MIN(gCost[e], profit);
236 const SCIP_Real newdist = k_dist + gCost[e] - MIN(k_dist, bias);
239 if(
GT(nodes_dist[m], newdist) )
243 nodes_dist[m] = newdist;
244 nodes_base[m] = nodes_base[k];
280 assert(path !=
NULL);
281 assert(cost !=
NULL);
283 if( g->
knots == 0 || nneighbterms <= 0 )
291 while( count > 0 && nneighbterms > 0 )
293 k =
nearest(heap, state, &count, path);
295 reachednodes[(*nreachednodes)++] = k;
296 distarr[k][nodenterms[k]] = path[k].
dist;
297 edgearr[k][nodenterms[k]] = path[k].
edge;
298 basearr[k][nodenterms[k]] = base;
302 if( termsmark[k] ==
TRUE )
304 termsmark[k] =
FALSE;
305 if( --nneighbterms == 0 )
308 reachednodes[(*nreachednodes)++] = heap[count--];
321 if( (state[m]) && (g->
mark[m]) && (
GT(path[m].dist, (path[k].dist + cost[i]))) )
322 correct(heap, state, &count, path, m, k, i, cost[i]);
326 assert(nneighbterms == 0);
348 assert(g && cost && basemark && vbase && path);
360 for(
int i = 0; i < g->
knots; i++ )
392 const int k =
nearest(heap, state, &count, path);
397 for(
int i = g->
outbeg[k]; i >= 0; i = g->
oeat[i] )
399 const int m = g->
head[i];
402 if( (state[m]) &&
GT(path[m].dist, path[k].dist + ((vbase[k] == root)? cost[i] : costrev[i])) )
404 assert(!basemark[m]);
405 correct(heap, state, &count, path, m, k, i, ((vbase[k] == root)? cost[i] : costrev[i]));
415 const int k =
nearest(heap, state, &count, path);
418 for(
int i = g->
outbeg[k]; i >= 0; i = g->
oeat[i] )
420 const int m = g->
head[i];
421 if( (state[m]) &&
GT(path[m].dist, path[k].dist + cost[i]) )
423 assert(!basemark[m]);
424 correct(heap, state, &count, path, m, k, i, cost[i]);
450 assert(nodes_isTerm && vbase && path);
454 assert(heap && state);
459 for(
int i = 0; i <
nnodes; i++ )
462 if( nodes_isTerm[i] && g->
mark[i] )
465 heap[++heapsize] = i;
484 while( heapsize > 0 )
487 const int k =
nearest(heap, state, &heapsize, path);
496 const int m = g->
head[e];
498 costbiased = g->
cost[e];
500 if( isPc && !nodes_isTerm[k] )
501 costbiased -= g->
prize[k];
503 assert(
GE(costbiased, 0.0) &&
LE(costbiased, g->
cost[e]));
505 if( state[m] && g->
mark[m] &&
GT(path[m].dist, path[k].dist + costbiased) )
507 correct(heap, state, &heapsize, path, m, k, e, costbiased);
535 assert(path !=
NULL);
536 assert(costrev !=
NULL);
537 assert(heap !=
NULL);
538 assert(state !=
NULL);
543 for( i = 0; i <
nnodes; i++ )
572 k =
nearest(heap, state, &count, path);
583 if( (state[m]) &&
SCIPisGT(scip, path[m].dist, path[k].dist + costrev[i]) && g->
mark[m] && !
Is_term(g->
term[m]) )
585 assert(vbase[m] != m);
586 correct(heap, state, &count, path, m, k, i, costrev[i]);
604 int* edges_isMinedgePred,
617 assert(path !=
NULL);
618 assert(cost !=
NULL);
619 assert(distance !=
NULL);
620 assert(nodes_isTerm);
630 if( distnode !=
NULL )
632 for(
int i = 0; i <
nnodes; i++ )
637 for(
int i = 0; i <
nnodes; i++ )
642 if( nodes_isTerm[i] && g->
mark[i] )
662 for(
int e = 0; e < g->
edges; e++ )
663 edges_isMinedgePred[e] =
FALSE;
665 for(
int k = 0; k < nbases; k++ )
673 edges_isMinedgePred[minarc[k]] =
TRUE;
684 const int k =
nearest(heap, state, &count, path);
685 const int prededge = path[k].
edge;
692 const int pred = g->
tail[prededge];
695 assert(vbase[pred] !=
UNKNOWN);
696 assert(vbase[pred] == vbase[k]);
697 assert(g->
head[prededge] == k);
699 if( !nodes_isTerm[pred] && g->
mark[pred] )
701 assert(path[pred].edge !=
UNKNOWN);
702 edges_isMinedgePred[prededge] = edges_isMinedgePred[path[pred].
edge];
710 const int m = g->
head[e];
712 costbiased = cost[e];
714 if( isPc && !nodes_isTerm[k] )
715 costbiased -= g->
prize[k];
717 assert(
GE(costbiased, 0.0) &&
LE(costbiased, cost[e]));
719 if( state[m] ==
CONNECT && vbase[m] != vbase[k] )
723 if( edges_isMinedgePred[e] || (prededge !=
UNKNOWN && edges_isMinedgePred[prededge] ) )
726 if( isPc && !nodes_isTerm[m] )
727 distnew -= g->
prize[m];
729 if(
SCIPisLT(scip, distnew, distance[vbase[k]]) )
731 if( distnode !=
NULL )
732 distnode[vbase[k]] = vbase[m];
734 distance[vbase[k]] = distnew;
737 if( edges_isMinedgePred[
Edge_anti(e)] || (path[m].edge !=
UNKNOWN && edges_isMinedgePred[path[m].edge] ) )
740 if( isPc && !nodes_isTerm[m] )
741 distnew -= g->
prize[m];
743 if(
SCIPisLT(scip, distnew, distance[vbase[m]]) )
745 if( distnode !=
NULL )
746 distnode[vbase[m]] = vbase[k];
748 distance[vbase[m]] = distnew;
755 if( state[m] && g->
mark[m] &&
756 (
SCIPisGT(scip, path[m].dist, path[k].dist + costbiased) ||
757 (prededge !=
UNKNOWN && edges_isMinedgePred[prededge] &&
SCIPisEQ(scip, path[m].dist, path[k].dist + costbiased))) )
760 if( isPc &&
EQ(path[m].dist, path[k].dist + costbiased) &&
EQ(costbiased, 0.0) )
763 correct(heap, state, &count, path, m, k, e, costbiased);
790 const int root = graph->
source;
795 assert(graph !=
NULL);
796 assert(heap !=
NULL);
797 assert(state !=
NULL);
798 assert(path !=
NULL);
799 assert(cost !=
NULL);
800 assert(costrev !=
NULL);
802 assert(vbase !=
NULL);
805 if( graph->
terms == 0 )
811 for(
int i = 0; i <
nnodes; i++ )
821 if( !mw && adjgraph !=
NULL )
827 nodesid[i] = nterms++;
858 const int k =
nearest(heap, state, &count, path);
866 const int m = graph->
head[i];
867 const int vbm = vbase[m];
868 const int vbk = vbase[k];
870 if( state[m] ==
CONNECT && vbm != vbk && graph->
mark[m] )
872 assert(graph->
mark[vbm]);
873 assert(graph->
mark[vbk]);
876 if(
SCIPisGT(scip, rad[vbk], path[k].dist) )
877 rad[vbk] = path[k].
dist;
878 if(
SCIPisGT(scip, rad[vbm], path[m].dist) )
879 rad[vbm] = path[m].
dist;
884 if(
SCIPisGT(scip, rad[vbk], path[k].dist + ((vbk == root) ? cost[i] : costrev[i])) )
885 rad[vbk] = path[k].
dist + ((vbk == root) ? cost[i] : costrev[i]);
887 if(
SCIPisGT(scip, rad[vbm], path[m].dist + ((vbm == root) ? costrev[i] : cost[i])) )
888 rad[vbm] = path[m].
dist + ((vbm == root) ? costrev[i] : cost[i]);
890 if( adjgraph !=
NULL )
900 c1 = path[m].
dist + costrev[i];
902 c1 = path[m].
dist + cost[i];
904 c2 = path[k].
dist + cost[i];
906 c2 = path[k].
dist + costrev[i];
915 if(
SCIPisGT(scip, path[m].dist, path[k].dist) )
916 ecost = path[k].dist + cost[i];
918 ecost = path[m].
dist + cost[i];
924 ecost = graph->
prize[vbm];
927 ecost = graph->
prize[vbk];
932 if( adjgraph->
head[ne] == nodesid[vbm] )
939 assert(adjgraph->
head[ne] == nodesid[vbm]);
940 assert(adjgraph->
tail[ne] == nodesid[vbk]);
943 adjgraph->
cost[ne] = ecost;
949 graph_edge_add(scip, adjgraph, nodesid[vbm], nodesid[vbk], ecost, ecost);
956 if( state[m] && graph->
mark[m] && !
Is_term(graph->
term[m]) &&
SCIPisGT(scip, path[m].dist, path[k].dist + ((vbk == root)? cost[i] : costrev[i])) )
958 correct(heap, state, &count, path, m, k, i, ((vbk == root)? cost[i] : costrev[i]));
994 assert(heap !=
NULL);
995 assert(state !=
NULL);
996 assert(path !=
NULL);
997 assert(cost !=
NULL);
998 assert(radius !=
NULL);
999 assert(vbase !=
NULL);
1004 nterms = g->
terms - 1;
1005 nodeweight = g->
prize;
1007 assert(nodeweight !=
NULL);
1009 if( nnodes == 0 || nterms <= 0 )
1015 for( i = 0; i <
nnodes; i++ )
1051 k =
nearest(heap, state, &count, path);
1057 assert(g->
mark[basek]);
1070 if( basem != basek && (state[m] ==
CONNECT || vbase[m] == m ||
1071 SCIPisGE(scip, path[k].dist, nodeweight[basek])) )
1073 if(
SCIPisGT(scip, radius[basek], path[k].dist) )
1074 radius[basek] = path[k].
dist;
1075 if( (state[m] ==
CONNECT || vbase[m] == m) &&
SCIPisGT(scip, radius[basem], path[m].dist) )
1077 assert(g->
mark[basem]);
1078 radius[basem] = path[m].
dist;
1083 if(
SCIPisLT(scip, path[k].dist, nodeweight[basek]) &&
SCIPisLT(scip, path[k].dist, radius[basek]) )
1086 if( (state[m]) &&
SCIPisGT(scip, path[m].dist, path[k].dist + cost[i]) )
1088 assert(vbase[m] != m);
1089 correct(heap, state, &count, path, m, k, i, cost[i]);
1117 assert(cost && scip && nheapelems && newedge && vbase && uf);
1128 assert(heap && state);
1131 while( *nheapelems > 0 )
1134 const int k =
nearest(heap, state, nheapelems, path);
1139 assert(vbase[k] >= 0);
1140 assert(g->
mark[k] && g->
mark[vbase[k]]);
1145 const int m = g->
head[e];
1148 if( (state[m]) && (
SCIPisGT(scip, path[m].dist, path[k].dist + cost[e])) )
1151 correct(heap, state, nheapelems, path, m, k, e, cost[e]);
1152 vbase[m] = vbase[k];
1160 if( (node1 == crucnode) == (node2 == crucnode) )
1163 if( !g->
mark[node1] || !g->
mark[node2] || !g->
mark[vbase[m]] )
1181 dist_new += cost_org[e];
1187 dist_new += cost[e];
1190 if( dist_new < boundarydist )
1192 boundarydist = dist_new;
1201 *newedge = boundaryedge;
1211 int* RESTRICT count,
1212 int* RESTRICT vbase,
1213 int* RESTRICT boundedges,
1214 int* RESTRICT nboundedges,
1219 assert(scip && g && cost && nodesmark && count && vbase && boundedges && nboundedges && uf && path);
1230 while( (*count) > 0 )
1233 const int k =
nearest(heap, state, count, path);
1241 const int m = g->
head[i];
1247 if( state[m] && (
SCIPisGT(scip, path[m].dist, path[k].dist + cost[i])) )
1249 correct(heap, state, count, path, m, k, i, cost[i]);
1250 vbase[m] = vbase[k];
1254 && g->
mark[node1] && g->
mark[node2] && (nodesmark[node1] || nodesmark[node2]) )
1256 boundedges[(*nboundedges)++] = i;
1284 if( useBufferArrays )
1354 assert(scip && vnoi);
static volatile int nterms
#define SCIPfreeMemoryArray(scip, ptr)
void graph_voronoi(const GRAPH *g, const SCIP_Real *cost, const SCIP_Real *costrev, const STP_Bool *basemark, int *vbase, PATH *path)
void graph_voronoiTerms(const GRAPH *g, const SCIP_Bool *nodes_isTerm, int *RESTRICT vbase, PATH *RESTRICT path)
#define SCIPallocMemoryArray(scip, ptr, num)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void vnoiInit(const GRAPH *g, DHEAP *dheap, VNOI *vnoi)
static void vnoiCompute(SCIP *scip, const GRAPH *g, DHEAP *dheap, VNOI *vnoi)
enum SCIP_Retcode SCIP_RETCODE
includes various files containing graph methods used for Steiner tree problems
SCIP_RETCODE graph_vnoiComputeImplied(SCIP *scip, const GRAPH *graph, const SDPROFIT *sdprofit, VNOI *vnoi)
SCIP_Bool graph_heap_isClean(const DHEAP *)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPfreeBufferArray(scip, ptr)
static void correct(int *RESTRICT heap, int *RESTRICT state, int *RESTRICT count, PATH *RESTRICT path, int l, int k, int e, SCIP_Real cost)
void graph_voronoiRepair(SCIP *scip, const GRAPH *g, const SCIP_Real *cost, const SCIP_Real *cost_org, int *nheapelems, int *vbase, PATH *path, int *newedge, int crucnode, UF *uf)
void graph_voronoiWithRadiusMw(SCIP *scip, const GRAPH *g, PATH *path, const SCIP_Real *cost, SCIP_Real *radius, int *vbase, int *heap, int *state)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE graph_voronoiExtend(SCIP *scip, const GRAPH *g, const SCIP_Real *cost, PATH *path, SCIP_Real **distarr, int **basearr, int **edgearr, STP_Bool *termsmark, int *reachednodes, int *nreachednodes, int *nodenterms, int nneighbterms, int base, int countex)
SCIP_Bool usingBufferArrays
void graph_edge_add(SCIP *, GRAPH *, int, int, double, double)
void graph_knot_add(GRAPH *, int)
void graph_voronoiMw(SCIP *scip, const GRAPH *g, const SCIP_Real *costrev, PATH *path, int *vbase, int *heap, int *state)
int SCIPStpunionfindFind(UF *uf, int element)
void graph_vnoiFree(SCIP *scip, VNOI **vnoi)
SCIP_RETCODE graph_vnoiCompute(SCIP *scip, const GRAPH *graph, VNOI *vnoi)
static SCIP_Real reduce_sdprofitGetProfit(const SDPROFIT *sdprofit, int node, int nonsource1, int nonsource2)
#define SCIPallocBufferArray(scip, ptr, num)
void graph_heap_free(SCIP *, SCIP_Bool, SCIP_Bool, DHEAP **)
void graph_voronoiRepairMult(SCIP *scip, const GRAPH *g, const SCIP_Real *cost, const STP_Bool *nodesmark, int *RESTRICT count, int *RESTRICT vbase, int *RESTRICT boundedges, int *RESTRICT nboundedges, UF *RESTRICT uf, PATH *RESTRICT path)
SCIP_Bool graph_pc_isPc(const GRAPH *)
#define SCIPfreeMemory(scip, ptr)
SCIP_RETCODE graph_vnoiInit(SCIP *scip, const GRAPH *graph, SCIP_Bool useBufferArrays, VNOI **vnoi)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool graph_pc_knotIsFixedTerm(const GRAPH *, int)
SCIP_Bool graph_edge_isInRange(const GRAPH *, int)
SCIP_RETCODE graph_heap_create(SCIP *, int, int *, DENTRY *, DHEAP **)
SCIP_Bool graph_pc_isPcMw(const GRAPH *)
int graph_heap_deleteMinReturnNode(DHEAP *)
int graph_get_nNodes(const GRAPH *)
SCIP_RETCODE graph_voronoiWithRadius(SCIP *scip, const GRAPH *graph, GRAPH *adjgraph, PATH *path, SCIP_Real *rad, SCIP_Real *cost, SCIP_Real *costrev, int *vbase, int *heap, int *state)
#define SCIPallocMemory(scip, ptr)
static void vnoiComputeImplied(const GRAPH *g, const SDPROFIT *sdprofit, DHEAP *dheap, VNOI *vnoi)
static int nearest(int *RESTRICT heap, int *RESTRICT state, int *RESTRICT count, const PATH *path)
includes various reduction methods for Steiner tree problems
void graph_heap_correct(int, SCIP_Real, DHEAP *)
SCIP_RETCODE graph_voronoiWithDist(SCIP *scip, const GRAPH *g, const SCIP_Bool *nodes_isTerm, const SCIP_Real *cost, SCIP_Real *distance, int *edges_isMinedgePred, int *vbase, int *minarc, int *distnode, PATH *path)