52 const int*
const tree_edges = extdata->
tree_edges;
53 const int*
const tree_leaves = extdata->
tree_leaves;
59 tree_redcost = rootToNodeDist[root];
61 for(
int i = 0; i < nleaves; i++ )
63 const int leaf = tree_leaves[i];
67 tree_redcost += nodeTo3TermsPaths[leaf].
dist;
70 for(
int i = 0; i < tree_nedges; i++ )
72 const int edge = tree_edges[i];
73 assert(edge >= 0 && edge < graph->edges);
75 tree_redcost += redcost[edge];
79 for(
int node = root; node != tree_root; node = extdata->
tree_parentNode[node] )
87 if( graph->
head[e] == parent )
92 tree_redcost += redcost[e];
93 tree_redcost -= redcost[
flipedge(e)];
106 int* RESTRICT keyArr,
112 assert(keyArr && dataArr1 && dataArr2);
113 assert(nentries >= 1);
116 for(
int i = 1; i < nentries; i++ )
119 const int currKey = keyArr[i];
123 for( j = i - 1; currKey > keyArr[j]; j-- )
126 keyArr[j + 1] = keyArr[j];
127 dataArr1[j + 1] = dataArr1[j];
128 dataArr2[j + 1] = dataArr2[j];
131 keyArr[j + 1] = currKey;
132 dataArr1[j + 1] = currData1;
133 dataArr2[j + 1] = currData2;
136 for(
int i = 0; i < nentries - 1; i++ )
140 for(
int j = i + 1; j < nentries; j++ )
142 if( keyArr[j] > keyArr[max_pos] )
151 temp_int = keyArr[max_pos];
152 keyArr[max_pos] = keyArr[i];
153 keyArr[i] = temp_int;
155 tmp_real = dataArr1[max_pos];
156 dataArr1[max_pos] = dataArr1[i];
157 dataArr1[i] = tmp_real;
159 tmp_real = dataArr2[max_pos];
160 dataArr2[max_pos] = dataArr2[i];
161 dataArr2[i] = tmp_real;
167 for(
int i = 1; i < nentries; i++ )
168 assert(keyArr[i - 1] >= keyArr[i] );
183 assert(firstTermDist && secondTermDist);
184 assert(nentries >= 1);
188 min = firstTermDist[0];
196 for( i = 0; i < nentries; i++ )
198 assert(
LE(firstTermDist[i], secondTermDist[i]));
204 secondSum += secondTermDist[i];
214 min = firstTermDist[i];
215 for(
int j = 0; j < nentries; j++ )
220 min += secondTermDist[j];
225 for( i = 0; i < nentries; i++ )
227 const SCIP_Real distCombination = secondSum + firstTermDist[i] - secondTermDist[i];
231 if( distCombination < min )
232 min = distCombination;
235 assert(
LE(min, secondSum));
256 const int*
const tree_leaves = extdata->
tree_leaves;
264 const int* tree_deg = extdata->
tree_deg;
268 SCIP_Real redcost_directed = tree_redcost + rootToNodeDist[root] + swapcost;
271 SCIP_Real redcost_debug = redcost_directed;
274 nearestTerms_x[0] = INT_MAX;
275 nearestTerms = &(nearestTerms_x[1]);
280 nearestTerms[i] = -1;
281 firstTermDist[i] = -1.0;
282 secondTermDist[i] = -1.0;
286 assert(
GE(tree_redcost, 0.0));
293 SCIPdebugMessage(
"...reduced costs without leaves: %f (treecost=%f + rootdist=%f + swap=%f) \n",
294 redcost_directed, tree_redcost, rootToNodeDist[root], swapcost);
297 for(
int j = 0; j < nleaves; j++ )
301 const int leaf = tree_leaves[j];
307 if( leaf == root || isterm[leaf] )
309 assert(leaf == root ||
EQ(0.0, nodeTo3TermsPaths[leaf].dist));
314 for( i = 0; i < 3; i++ )
316 term = next3Terms[leaf + i *
nnodes];
322 assert(term >= 0 && term < graph->knots);
323 assert(term != leaf);
326 if( tree_deg[term] == 0 )
329 if( tree_deg[term] < 0 )
343 assert(i < 3 &&
GE(nodeTo3TermsPaths[leaf + i * nnodes].dist,
FARAWAY));
351 nearestTerms[leavescount] = term;
352 firstTermDist[leavescount] = nodeTo3TermsPaths[leaf + i *
nnodes].
dist;
353 secondTermDist[leavescount] = (i < 2) ? nodeTo3TermsPaths[leaf + (i + 1) *
nnodes].
dist : firstTermDist[leavescount];
355 assert(
LE(nodeTo3TermsPaths[leaf].dist, firstTermDist[leavescount]));
356 assert(
LE(firstTermDist[leavescount], secondTermDist[leavescount]));
360 firstTermDist[leavescount], secondTermDist[leavescount], nodeTo3TermsPaths[leaf].dist);
366 redcost_debug += nodeTo3TermsPaths[leaf].
dist;
367 assert(leavescount <= STP_EXTTREE_MAXNLEAVES_GUARD);
371 if( leavescount > 0 )
377 for(
int i = 1; i < leavescount; i++ )
379 assert(nearestTerms[i] >= 0 && firstTermDist[i] >= 0.0 && secondTermDist[i] >= 0.0);
380 if( nearestTerms[i] != nearestTerms[i - 1] )
382 const int n = i - first;
388 redcost_directed +=
getMinDistCombination(firstTermDist + first, secondTermDist + first, leavescount - first);
398 assert(
GE(redcost_directed, redcost_debug));
400 return redcost_directed;
431 if(
LT(redcost_treenodeswaps[redcostlevel * graph->
knots + root],
FARAWAY) )
453 const int*
const tree_leaves = extdata->
tree_leaves;
467 for(
int i = 0; i < nleaves; i++ )
469 const int leaf = tree_leaves[i];
475 if( allowEquality ?
LT(tree_redcost_new, cutoff) :
LE(tree_redcost_new, cutoff) )
477 SCIPdebugMessage(
"NO rule-out periph (red.cost<=%f from root=%d and cutoff=%f) \n", tree_redcost_new, leaf, cutoff);
482 tree_redcost = MIN(tree_redcost, tree_redcost_new);
487 SCIPdebugMessage(
"Rule-out periph (with red.cost=%f and cutoff=%f, level=%d) \n", tree_redcost, cutoff, redcostlevel);
506 const int*
const tree_edges = extdata->
tree_edges;
510 const int nedges = graph->
edges;
517 for(
int i = 0; i < nlevels; i++ )
518 lvl_redcostsbuffer[i] = 0.0;
520 for(
int i = 0; i < tree_nedges; i++ )
522 const int edge = tree_edges[i];
523 const SCIP_Bool edgeIsDeleted = (edgedeleted && edgedeleted[edge]);
529 for(
int j = 0; j < nlevels; j++ )
531 lvl_redcostsbuffer[j] += lvl_redcosts[j * nedges + edge];
532 assert(
LT(lvl_redcostsbuffer[j],
FARAWAY));
537 for(
int i = 0; i < nlevels; i++ )
539 assert(
SCIPisEQ(scip, redcost_treecosts[i], lvl_redcostsbuffer[i]));
540 redcost_treecosts[i] = lvl_redcostsbuffer[i];
559 const int tree_root = extdata->
tree_root;
562 for(
int i = 0; i < nlevels; i++ )
583 const SCIP_Bool edgeIsDeleted = (edgedeleted && edgedeleted[edge]);
584 const int tail = graph->
tail[edge];
585 const int head = graph->
head[edge];
588 const int nedges = graph->
edges;
590 assert(!edgedeleted &&
"deprecated!");
594 for(
int i = 0; i < nlevels; i++ )
596 const int offset_node = i *
nnodes;
597 const int offset_edge = i * nedges;
599 if( redcost_noReverses[i] || (edgedeleted && edgedeleted[
flipedge(edge)]) )
601 redcost_treenodeswaps[offset_node + head] =
FARAWAY;
606 redcost_noReverses[i] =
TRUE;
611 redcost_treenodeswaps[offset_node + head] =
612 redcost_treenodeswaps[offset_node + tail] + redcosts[offset_edge +
flipedge(edge)];
615 redcost_treenodeswaps[offset_node + head] -= redcosts[offset_edge + edge];
617 assert(
LT(redcost_treenodeswaps[offset_node + head],
FARAWAY));
622 redcost_treecosts[i] += redcosts[offset_edge + edge];
623 assert(
LT(redcost_treecosts[i],
FARAWAY));
650 for(
int i = 0; i < nlevels; i++ )
652 redcost_treecosts[i] -= redcosts[i * nedges + edge];
653 assert(
LT(redcost_treecosts[i],
FARAWAY));
675 assert(nlevels >= 1);
677 for(
int i = 0; i < nlevels; i++ )
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
const STP_Bool *const edgedeleted
#define SCIPallocBlockMemoryArray(scip, ptr, num)
SCIP_Bool extreduce_treeIsFlawed(SCIP *, const GRAPH *, const EXTDATA *)
static SCIP_Bool extIsAtInitialStar(const EXTDATA *extdata)
SCIP_Real * redcosts_getRootToNodeDist(const REDCOST *redcostdata, int level)
static SCIP_Real extTreeGetDirectedRedcostProper(const GRAPH *graph, int redcostlevel, const EXTDATA *extdata, int root)
SCIP_Real *const redcost_treecosts
int redcosts_getRoot(const REDCOST *redcostdata, int level)
includes various files containing graph methods used for Steiner tree problems
const SCIP_Bool redcost_allowEquality
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_Real extTreeGetDirectedRedcost(const GRAPH *graph, int redcostlevel, const EXTDATA *extdata, const REDDATA *reddata, int root)
void extreduce_redcostRemoveEdge(int edge, const REDDATA *reddata, EXTDATA *extdata)
SCIP_Real * redcosts_getEdgeCosts(const REDCOST *redcostdata, int level)
static void sortDescendingIntRealReal(int *RESTRICT keyArr, SCIP_Real *RESTRICT dataArr1, SCIP_Real *RESTRICT dataArr2, int nentries)
int * redcosts_getNodeToTermsBases(const REDCOST *redcostdata, int level)
This file implements extended reduction techniques for several Steiner problems.
int *const tree_parentNode
int redcosts_getNnodes(const REDCOST *redcostdata)
int redcosts_getNedges(const REDCOST *redcostdata)
static SCIP_Real getTreeRedcosts_dbg(const GRAPH *graph, int redcostlevel, const EXTDATA *extdata, int root)
SCIP_Real redcosts_getCutoff(const REDCOST *redcostdata, int level)
const REDCOST *const redcostdata
#define STP_EXTTREE_MAXNLEAVES_GUARD
void extreduce_redcostTreeRecompute(SCIP *scip, const GRAPH *graph, EXTDATA *extdata)
static SCIP_Bool extTreeRedcostCutoff(const GRAPH *graph, int redcostlevel, const EXTDATA *extdata, const REDDATA *reddata)
SCIP_Real *const redcost_treenodeswaps
void extreduce_redcostAddEdge(const GRAPH *graph, int edge, REDDATA *reddata, EXTDATA *extdata)
const SCIP_Bool *const node_isterm
SCIP_Bool *const redcost_noReversedTree
static SCIP_Real getMinDistCombination(const SCIP_Real *firstTermDist, const SCIP_Real *secondTermDist, int nentries)
SCIP_Bool graph_edge_isInRange(const GRAPH *, int)
const int redcost_nlevels
static SCIP_Bool extIsAtInitialGenStar(const EXTDATA *extdata)
SCIP_Bool graph_pc_isPcMw(const GRAPH *)
PATH * redcosts_getNodeToTermsPaths(const REDCOST *redcostdata, int level)
SCIP_Bool graph_knot_isInRange(const GRAPH *, int)
SCIP_Bool extreduce_redcostRuleOutPeriph(const GRAPH *graph, EXTDATA *extdata)
static int extStackGetTopRoot(const GRAPH *graph, const EXTDATA *extdata)
#define SCIP_CALL_ABORT(x)
void extreduce_redcostInitExpansion(const GRAPH *graph, EXTDATA *extdata)
#define GE_FEAS_EPS(a, b, eps)