41 #define HEUR_NAME "local" 42 #define HEUR_DESC "improvement heuristic for STP" 43 #define HEUR_DISPCHAR '-' 44 #define HEUR_PRIORITY 100 46 #define HEUR_FREQOFS 0 47 #define HEUR_MAXDEPTH -1 48 #define HEUR_TIMING (SCIP_HEURTIMING_BEFORENODE | SCIP_HEURTIMING_DURINGLPLOOP | SCIP_HEURTIMING_AFTERLPLOOP | SCIP_HEURTIMING_AFTERNODE) 50 #define HEUR_USESSUBSCIP FALSE 52 #define DEFAULT_DURINGROOT TRUE 53 #define DEFAULT_MAXFREQLOC FALSE 54 #define DEFAULT_MAXNBESTSOLS 6 55 #define DEFAULT_NBESTSOLS 3 87 int oedge = graph->
outbeg[*node];
91 if( edges[oedge] >= 0 )
93 dfsorder(graph, edges, &(graph->
head[oedge]), counter, dfst);
95 oedge = graph->
oeat[oedge];
98 dfst[*counter] = *node;
129 v = graph->
head[oedge];
130 if( steineredges[oedge] == 0 )
132 SCIP_CALL(
lca(scip, graph, v, uf, nodesmark, steineredges, lcalists, boundpaths, heapsize, vbase) );
141 for( i = 0; i < heapsize[u]; i++ )
143 oedge = uboundpaths[i];
144 v = vbase[graph->
head[oedge]];
150 if( ancestor != u && ancestor != v)
152 SCIP_CALL( SCIPallocMemory(scip, &curr) );
154 curr->
parent = lcalists[ancestor];
155 lcalists[ancestor] = curr;
161 SCIPfreeBufferArray(scip, &uboundpaths);
174 assert(graph != NULL);
175 assert(steineredges != NULL);
177 if( graph->
term[node] == -1 )
180 int e = graph->
outbeg[node];
184 if( steineredges[e] > -1 || steineredges[
flipedge(e)] > -1 )
202 SCIP_RETCODE printGraph(
205 const char* filename,
209 char label[SCIP_MAXSTRLEN];
215 SCIP_CALL( SCIPallocBufferArray(scip, &stnodes, graph->
knots ) );
217 assert(graph != NULL);
218 file = fopen((filename != NULL) ? filename :
"graphX.gml",
"w");
220 for( e = 0; e < graph->
knots; e++ )
224 for( e = 0; e < graph->
edges; e++ )
234 SCIPgmlWriteOpening(file,
FALSE);
239 for( n = 0; n < graph->
knots; ++n )
243 if( n == graph->
source[0] )
245 (void)SCIPsnprintf(label, SCIP_MAXSTRLEN,
"(%d) Root", n);
246 SCIPgmlWriteNode(file, (
unsigned int)n, label,
"rectangle",
"#666666", NULL);
249 else if( graph->
term[n] == 0 )
251 (void)SCIPsnprintf(label, SCIP_MAXSTRLEN,
"(%d) Terminal %d", n, e + 1);
252 SCIPgmlWriteNode(file, (
unsigned int)n, label,
"circle",
"#ff0000", NULL);
257 (void)SCIPsnprintf(label, SCIP_MAXSTRLEN,
"(%d) Node %d", n, n + 1 - e - m);
258 SCIPgmlWriteNode(file, (
unsigned int)n, label,
"circle",
"#336699", NULL);
265 for( e = 0; e < graph->
edges; e ++ )
269 (void)SCIPsnprintf(label, SCIP_MAXSTRLEN,
"%8.2f", graph->
cost[e]);
270 SCIPgmlWriteEdge(file, (
unsigned int)graph->
tail[e], (
unsigned int)graph->
head[e], label,
"#ff0000");
273 SCIPfreeBufferArray(scip, &stnodes);
275 SCIPgmlWriteClosing(file);
309 printf(
"local heuristic running \n");
312 assert(graph != NULL);
313 assert(cost != NULL);
314 assert(costrev != NULL);
315 assert(best_result != NULL);
323 nnodes = graph->
knots;
324 nedges = graph->
edges;
326 graphmark = graph->
mark;
336 SCIPdebugMessage(
"Local heuristic: return trivial \n");
341 SCIP_CALL( SCIPallocBufferArray(scip, &vnoi, nnodes) );
342 SCIP_CALL( SCIPallocBufferArray(scip, &vbase, nnodes) );
343 SCIP_CALL( SCIPallocBufferArray(scip, &nodes, nnodes) );
344 SCIP_CALL( SCIPallocBufferArray(scip, &steinertree, nnodes) );
349 for( i = 0; i < nnodes; i++ )
351 steinertree[i] =
FALSE;
356 for( e = 0; e < nedges; e++ )
361 if( best_result[e] ==
CONNECT )
369 assert( nodes[root].edge == -1 );
370 nodes[root].
edge = -1;
390 SCIP_CALL( SCIPallocBufferArray(scip, &insert, nnodes) );
391 SCIP_CALL( SCIPallocBufferArray(scip, &adds, nnodes) );
392 SCIP_CALL( SCIPallocBufferArray(scip, &cuts, nnodes) );
396 SCIP_CALL( SCIPallocBufferArray(scip, &cuts2, nnodes) );
397 SCIP_CALL( SCIPallocBufferArray(scip, &stdeg, nnodes) );
399 for( i = 0; i < nnodes; i++ )
422 if( !steinertree[i] && graph->
grad[i] > 1 && (!mwpc || !
Is_term(graph->
term[i])) )
428 if( steinertree[graph->
head[oedge]] && (!mwpc || !
Is_term(graph->
term[graph->
head[oedge]])) )
429 insert[insertcount++] = oedge;
435 SCIPdebugMessage(
"ADDED VERTEX \n");
441 steinertree[i] =
TRUE;
447 if( insertcount > 1 && mw ==
FALSE )
459 for( k = 1; k < insertcount; k++ )
464 w = &nodes[graph->
head[insert[k]]];
468 assert(stdeg != NULL);
469 stdeg[graph->
head[insert[k]]]++;
473 stdeg[graph->
head[insert[k]]]--;
475 if( SCIPisLT(scip, graph->
prize[l], graph->
prize[i]) )
479 printf(
"(n: %d) minfound: %d of cost %f orgcost %f\n", insertcount, l, graph->
prize[l], graph->
prize[i]);
487 if( SCIPisGT(scip, graph->
cost[max->
edge], graph->
cost[insert[k]]) )
489 diff += graph->
cost[insert[k]];
491 cuts[counter] = max->
edge;
494 assert(v->
edge == insert[k]);
495 adds[counter++] = v->
edge;
500 diff -= graph->
prize[i];
505 if( SCIPisLT(scip, diff, 0.0) )
512 steinertree[i] =
TRUE;
516 printf(
"%d connect to %d %d \n", l, graph->
tail[l], graph->
head[l]);
517 steinertree[l] =
FALSE;
523 if( !SCIPisNegative(scip, diff) )
526 for( k = counter - 1; k >= 0; k-- )
540 adds[counter] = insert[0];
542 steinertree[i] =
TRUE;
544 SCIPdebugMessage(
"ADDED VERTEX \n");
563 for( i = 0; i < nnodes; i++ )
571 steinertree[i] =
TRUE;
573 printf(
"ADDED!!! %d %f < %f \n\n", i, graph->
cost[e], graph->
prize[i]);
583 for( i = 0; i < nnodes; i++ )
591 steinertree[i] =
TRUE;
593 printf(
"in ADDED!!! %d %f < %f \n\n", i, graph->
cost[e], graph->
prize[i]);
605 SCIPfreeBufferArray(scip, &stdeg);
606 SCIPfreeBufferArray(scip, &cuts2);
608 SCIPfreeBufferArray(scip, &cuts);
609 SCIPfreeBufferArray(scip, &adds);
610 SCIPfreeBufferArray(scip, &insert);
612 for( e = 0; e < nedges; e++ )
629 for( i = 0; i < nnodes; i++ )
633 for( e = 0; e < nedges; e++ )
635 if( best_result[e] ==
CONNECT )
637 assert(steinertree[graph->
tail[e]]);
638 assert(steinertree[graph->
head[e]]);
647 for( i = 0; i < nnodes; i++ )
649 if( steinertree[i] && nodes[i].edge != -1 )
650 best_result[
flipedge(nodes[i].edge)] = 0;
656 for( e = 0; e < nedges; e++)
657 obj += (best_result[e] > -1) ? graph->
cost[e] : 0.0;
658 printf(
"ObjAfterVertexInsertion=%.12e\n", obj);
671 IDX** lvledges_start;
717 for( e = 0; e < nedges; e++)
718 obj += (best_result[e] > -1) ? graph->
cost[e] : 0.0;
719 printf(
" ObjBEFKEYVertexELimination=%.12e\n", obj);
721 for( k = 0; k < nnodes; k++ )
727 SCIP_CALL( SCIPallocBufferArray(scip, &newedges, nedges) );
728 SCIP_CALL( SCIPallocBufferArray(scip, &lvledges_start, nnodes) );
729 SCIP_CALL( SCIPallocBufferArray(scip, &boundedges, nedges) );
730 SCIP_CALL( SCIPallocBufferArray(scip, &supernodesid, nnodes) );
735 SCIP_CALL( SCIPallocBufferArray(scip, &scanned, nnodes) );
736 SCIP_CALL( SCIPallocBufferArray(scip, &heapsize, nnodes) );
737 SCIP_CALL( SCIPallocBufferArray(scip, &blists_start, nnodes) );
738 SCIP_CALL( SCIPallocBufferArray(scip, &memvbase, nnodes) );
739 SCIP_CALL( SCIPallocBufferArray(scip, &memdist, nnodes) );
740 SCIP_CALL( SCIPallocBufferArray(scip, &meminedges, nnodes) );
741 SCIP_CALL( SCIPallocBufferArray(scip, &boundpaths, nnodes) );
742 SCIP_CALL( SCIPallocBufferArray(scip, &pinned, nnodes) );
743 SCIP_CALL( SCIPallocBufferArray(scip, &dfstree, nnodes) );
744 SCIP_CALL( SCIPallocBufferArray(scip, &nodesmark, nnodes) );
746 for( nruns = 0; nruns < 3 && localmoves > 0; nruns++ )
753 BMSclearMemoryArray(blists_start, nnodes);
757 dfsorder(graph, best_result, &(root), &nstnodes, dfstree);
758 assert(root == graph->
source[0]);
760 SCIP_CALL( SCIPallocBufferArray(scip, &supernodes, nstnodes) );
761 SCIP_CALL( SCIPallocBufferArray(scip, &kpnodes, nstnodes) );
762 SCIP_CALL( SCIPallocBufferArray(scip, &kpedges, nstnodes) );
765 voronoi(scip, graph, graph->
cost, graph->
cost, steinertree, vbase, vnoi);
770 for( k = 0; k < nnodes; k++ )
773 printf(
"not conn! %d\n", k);
774 assert(graphmark[k]);
779 nodesmark[k] =
FALSE;
783 boundpaths[k] = NULL;
785 lvledges_start[k] = NULL;
788 SCIP_CALL( SCIPallocMemory(scip, &blists_curr) );
789 blists_curr->
index = k;
790 blists_curr->
parent = blists_start[vbase[k]];
791 blists_start[vbase[k]] = blists_curr;
801 graphmark[k] =
FALSE;
806 assert(graph->
head[l] != root);
814 graphmark[root] =
FALSE;
818 for( e = 0; e < nedges; e += 2 )
820 node = graph->
tail[e];
821 adjnode = graph->
head[e];
826 if( vbase[node] != vbase[adjnode] && graphmark[node] && graphmark[adjnode] )
828 edgecost = vnoi[node].
dist + graph->
cost[e] + vnoi[adjnode].
dist;
831 SCIP_CALL(
SCIPpairheapInsert(scip, &boundpaths[vbase[node]], e, edgecost, &(heapsize[vbase[node]])) );
837 SCIP_CALL(
lca(scip, graph, root, &uf, nodesmark, best_result, lvledges_start, boundpaths, heapsize, vbase) );
844 for( i = 0; dfstree[i] != root; i++ )
845 nodesmark[dfstree[i]] =
FALSE;
846 nodesmark[dfstree[i]] =
FALSE;
848 for( k = 0; k < nnodes; k++ )
849 assert(!nodesmark[k]);
852 for( i = 0; dfstree[i] != root; i++ )
854 crucnode = dfstree[i];
855 scanned[crucnode] =
TRUE;
858 printf(
"iteration %d (%d) \n", i, crucnode);
861 if( !graphmark[crucnode] )
868 printf(
"Elimination: %d \n", crucnode);
870 for( k = 0; k < nnodes; k++ )
882 if( (best_result[edge] > -1 && steinertree[graph->
head[edge]]) || (best_result[
flipedge(edge)] > -1 && steinertree[graph->
tail[edge]]) )
884 kpcost += graph->
cost[edge];
887 if( best_result[
flipedge(edge)] > -1 )
890 kpedges[nkpedges++] = k;
891 assert( edge == nodes[crucnode].edge );
895 kpedges[nkpedges++] = edge;
896 adjnode = graph->
head[edge];
900 while( !pinned[adjnode] && !
nodeIsCrucial(graph, best_result, adjnode) && steinertree[adjnode] )
903 printf(
"unite in eliminate (%d) (%d) \n ", crucnode, adjnode);
908 kpnodes[nkpnodes++] = adjnode;
912 if( best_result[e] > -1 )
914 kpcost += graph->
cost[e];
915 kpedges[nkpedges++] = e;
930 adjnode = graph->
head[e];
933 if( !steinertree[adjnode] )
935 kpcost -= graph->
cost[e];
937 adjnode = graph->
tail[e];
938 if( adjnode != crucnode )
940 supernodes[nsupernodes++] = adjnode;
942 printf(
" (art) supernode: %d \n", adjnode);
943 nodesmark[adjnode] =
TRUE;
948 supernodes[nsupernodes++] = adjnode;
950 printf(
" supernode: %d \n", adjnode);
951 nodesmark[adjnode] =
TRUE;
958 rootpathstart = nkpnodes;
963 adjnode = graph->
tail[e];
964 while( !pinned[adjnode] && !
nodeIsCrucial(graph, best_result, adjnode) && steinertree[adjnode] )
967 kpnodes[nkpnodes++] = adjnode;
971 if( best_result[e] > -1 )
973 assert(steinertree[graph->
tail[e]]);
974 kpcost += graph->
cost[e];
975 kpedges[nkpedges++] = e;
981 adjnode = graph->
tail[e];
983 supernodes[nsupernodes++] = adjnode;
985 printf(
"root supernode: %d \n", graph->
tail[e]);
989 kpnodes[nkpnodes++] = crucnode;
995 for( k = 0; k < nkpnodes; k++ )
998 blists_curr = blists_start[kpnodes[k]];
999 while( blists_curr != NULL )
1001 node = blists_curr->
index;
1002 assert(graphmark[node]);
1005 memvbase[nresnodes] = vbase[node];
1006 memdist[nresnodes] = vnoi[node].
dist;
1007 meminedges[nresnodes] = vnoi[node].
edge;
1015 blists_curr = blists_curr->
parent;
1021 for( k = 0; k < nsupernodes - 1; k++ )
1025 while( boundpaths[l] != NULL )
1033 if( node !=
UNKNOWN && !nodesmark[node] && graphmark[node] )
1035 boundedges[nboundedges++] = edge;
1037 printf(
"ADD vertical edge: %d_%d \n", graph->
tail[edge], graph->
head[edge]);
1045 lvledges_curr = lvledges_start[crucnode];
1046 while( lvledges_curr != NULL )
1048 edge = lvledges_curr->
index;
1049 k = vbase[graph->
tail[edge]];
1050 l = vbase[graph->
head[edge]];
1055 if( node !=
UNKNOWN && nodesmark[node] && adjnode !=
UNKNOWN && nodesmark[adjnode] )
1057 assert(graphmark[node]);
1058 assert(graphmark[adjnode]);
1059 boundedges[nboundedges++] = edge;
1061 lvledges_curr = lvledges_curr->
parent;
1066 for( k = 0; k < nkpnodes; k++ )
1068 blists_curr = blists_start[kpnodes[k]];
1069 assert( blists_curr != NULL );
1070 while( blists_curr != NULL )
1072 node = blists_curr->
index;
1077 adjnode = graph->
tail[edge];
1080 if( state[adjnode] ==
CONNECT && SCIPisGT(scip, vnoi[node].dist, vnoi[adjnode].dist + graph->
cost[edge])
1081 && graphmark[vbase[adjnode]] && graphmark[adjnode] )
1083 vnoi[node].
dist = vnoi[adjnode].
dist + graph->
cost[edge];
1084 vbase[node] = vbase[adjnode];
1085 vnoi[node].
edge = edge;
1091 printf(
"add to heap %d \n", node );
1094 blists_curr = blists_curr->
parent;
1099 assert(nkpnodes != 0);
1104 SCIP_CALL(
graph_init(scip, &supergraph, nsupernodes, nboundedges * 2, 1, 0) );
1108 for( k = 0; k < nsupernodes; k++ )
1110 supernodesid[supernodes[k]] = k;
1112 printf(
"adding node %d (org: %d) \n ", k , supernodes[k]);
1117 k = supernodes[nsupernodes - 1];
1120 for( l = 0; l < nboundedges; l++ )
1122 edge = boundedges[l];
1124 printf(
"boundedgeALL: %d_%d vbases: %d_%d \n ", graph->
tail[edge], graph->
head[edge], vbase[graph->
tail[edge]], vbase[graph->
head[edge]]);
1129 node = ((nodesmark[node])? node : k);
1130 adjnode = ((nodesmark[adjnode])? adjnode : k);
1133 printf(
"adding edge %d %d \n ", supernodesid[node], supernodesid[adjnode] );
1136 graph_edge_add(scip, supergraph, supernodesid[node], supernodesid[adjnode], edgecost, edgecost);
1140 SCIP_CALL( SCIPallocBufferArray(scip, &mst, nsupernodes) );
1148 for( l = 0; l < nsupernodes - 1; l++ )
1151 if( mst[l].edge % 2 == 0 )
1152 edge = boundedges[mst[l].
edge / 2 ];
1154 edge =
flipedge(boundedges[mst[l].edge / 2 ]);
1156 mstcost += graph->
cost[edge];
1157 assert( newedges[edge] != crucnode && newedges[
flipedge(edge)] != crucnode );
1160 newedges[edge] = crucnode;
1163 for( node = graph->
tail[edge]; node != vbase[node]; node = graph->
tail[vnoi[node].
edge] )
1165 e = vnoi[node].
edge;
1168 if( newedges[e] != crucnode && newedges[
flipedge(e)] != crucnode )
1170 newedges[e] = crucnode;
1171 mstcost += graph->
cost[e];
1174 for( node = graph->
head[edge]; node != vbase[node]; node = graph->
tail[vnoi[node].
edge] )
1179 if( newedges[vnoi[node].edge] != crucnode && newedges[e] != crucnode )
1181 newedges[e] = crucnode;
1182 mstcost += graph->
cost[e];
1187 if( SCIPisLT(scip, mstcost, kpcost) )
1191 printf(
"found improving solution in KEY VERTEX ELIMINATION (round: %d) \n ", nruns);
1194 for( e = 0; e < nkpedges; e++ )
1196 assert(best_result[kpedges[e]] != -1);
1197 best_result[kpedges[e]] = -1;
1201 for( k = rootpathstart; k < nkpnodes; k++ )
1203 graphmark[kpnodes[k]] =
FALSE;
1204 steinertree[kpnodes[k]] =
FALSE;
1206 printf(
"ungraphmark(rootcomp) %d \n", kpnodes[k]);
1209 for( k = 0; k < i; k++ )
1212 if( nodesmark[node] || node == crucnode )
1214 graphmark[dfstree[k]] =
FALSE;
1215 steinertree[dfstree[k]] =
FALSE;
1217 printf(
"ungraphmark %d \n", dfstree[k]);
1222 for( l = 0; l < nsupernodes - 1; l++ )
1224 if( mst[l].edge % 2 == 0 )
1225 edge = boundedges[mst[l].
edge / 2 ];
1227 edge =
flipedge(boundedges[mst[l].edge / 2 ]);
1229 printf(
"MST edge vbase tail %d vbase head: %d \n",vbase[graph->
tail[edge]], vbase[graph->
head[edge]] );
1232 if( !nodesmark[vbase[graph->
head[edge]]] )
1234 node = vbase[graph->
head[edge]];
1236 assert(nodesmark[k]);
1240 e = nodes[node].
edge;
1242 assert(best_result[e] == -1 && best_result[
flipedge(e)] != -1 );
1244 printf(
" switch : %d->%d \n ", graph->
tail[e], graph->
head[e]);
1247 node = graph->
head[e];
1255 printf(
" FINAL ADD root edgee: : %d -> %d \n", graph->
tail[edge], graph->
head[edge]);
1259 for( node = graph->
tail[edge], adjnode = graph->
head[edge]; node != vbase[node]; adjnode = node, node = graph->
tail[vnoi[node].
edge] )
1261 graphmark[node] =
FALSE;
1263 printf(
"ungraphmark %d \n", node);
1269 printf(
" FINAL delete reverse1 of : %d -> %d \n", graph->
tail[(vnoi[node].
edge)], graph->
head[(vnoi[node].
edge)]);
1272 printf(
"FINAL ADD rootedge: : %d -> %d \n", graph->
tail[(vnoi[node].
edge)], graph->
head[(vnoi[node].
edge)]);
1276 assert(!nodesmark[node] && vbase[node] == node);
1277 assert( graphmark[node] ==
TRUE );
1287 adjnode = graph->
head[edge];
1289 if( best_result[edge] ==
CONNECT && graphmark[adjnode] && steinertree[adjnode] &&
SCIPunionfindFind(&uf, adjnode) != node )
1292 assert(scanned[adjnode]);
1294 SCIPpairheapMeldheaps(scip, &boundpaths[node], &boundpaths[adjnode], &heapsize[node], &heapsize[adjnode]);
1297 printf(
"unite eli pinned (%d) (%d) \n ", node, adjnode);
1302 while( !
nodeIsCrucial(graph, best_result, adjnode) && !pinned[adjnode] )
1306 if( best_result[e] != -1 )
1312 adjnode = graph->
head[e];
1313 if( !steinertree[adjnode] )
1315 assert(scanned[adjnode]);
1318 printf(
"unite eli pinned 1 (%d) (%d) \n ", node, adjnode);
1323 SCIPpairheapMeldheaps(scip, &boundpaths[node], &boundpaths[adjnode], &heapsize[node], &heapsize[adjnode]);
1332 pinned[node] =
TRUE;
1334 printf(
"pinned node: %d \n", node);
1336 for( node = graph->
head[edge]; node != vbase[node]; node = graph->
tail[vnoi[node].
edge] )
1338 graphmark[node] =
FALSE;
1339 if( best_result[vnoi[node].edge] ==
CONNECT )
1341 best_result[vnoi[node].
edge] = -1;
1344 printf(
" FINAL delete reverse2 of : %d -> %d \n", graph->
head[(vnoi[node].edge)], graph->
tail[(vnoi[node].edge)]);
1347 printf(
"FINAL ADD rootedge: : %d -> %d \n", graph->
tail[
flipedge(vnoi[node].edge)], graph->
head[
flipedge(vnoi[node].edge)]);
1355 printf(
" FINAL ADD egde: : %d -> %d \n", graph->
tail[edge], graph->
head[edge]);
1359 for( node = graph->
tail[edge]; node != vbase[node]; node = graph->
tail[vnoi[node].
edge] )
1361 graphmark[node] =
FALSE;
1365 printf(
"FINAL ADD edge: : %d -> %d \n", graph->
tail[(vnoi[node].
edge)], graph->
head[(vnoi[node].
edge)]);
1371 for( node = graph->
head[edge]; node != vbase[node]; node = graph->
tail[vnoi[node].
edge] )
1373 graphmark[node] =
FALSE;
1375 printf(
"FINAL ADD edge: : %d -> %d \n", graph->
tail[
flipedge(vnoi[node].edge)], graph->
head[
flipedge(vnoi[node].edge)]);
1382 for( k = 0; k < nkpnodes; k++ )
1384 assert(graphmark[kpnodes[k]] ==
FALSE);
1385 assert(steinertree[kpnodes[k]] ==
FALSE);
1387 assert(!graphmark[crucnode]);
1394 for( k = 0; k < rootpathstart; k++ )
1396 SCIPpairheapMeldheaps(scip, &boundpaths[crucnode], &boundpaths[kpnodes[k]], &heapsize[crucnode], &heapsize[kpnodes[k]]);
1398 for( k = 0; k < nsupernodes - 1; k++ )
1400 SCIPpairheapMeldheaps(scip, &boundpaths[crucnode], &boundpaths[supernodes[k]], &heapsize[crucnode], &heapsize[supernodes[k]]);
1402 printf(
"unite 5 (%d) (%d) \n ", crucnode, supernodes[k]);
1411 SCIPfreeBufferArray(scip, &mst);
1414 for( k = 0; k < nsupernodes - 1; k++ )
1416 nodesmark[supernodes[k]] =
FALSE;
1420 for( k = 0; k < nnodes; k++ )
1422 assert( !nodesmark[k] );
1427 for( k = 0; k < nkpnodes; k++ )
1430 blists_curr = blists_start[kpnodes[k]];
1431 while( blists_curr != NULL )
1433 node = blists_curr->
index;
1434 vbase[node] = memvbase[l];
1435 vnoi[node].
dist = memdist[l];
1436 vnoi[node].
edge = meminedges[l];
1438 blists_curr = blists_curr->
parent;
1442 assert(l == nresnodes);
1449 if( !graphmark[crucnode] )
1452 printf(
"not marked: %d\n", crucnode);
1456 if( (!
nodeIsCrucial(graph, best_result, crucnode) && !pinned[crucnode]) )
1459 printf(
"not crucial and not pinned: %d\n", crucnode);
1462 if(
Is_term(graph->
term[crucnode]) || pinned[crucnode] )
1466 adjnode = graph->
head[edge];
1468 if( best_result[edge] ==
CONNECT && steinertree[adjnode] && graphmark[adjnode] )
1471 assert(scanned[adjnode]);
1473 SCIPpairheapMeldheaps(scip, &boundpaths[crucnode], &boundpaths[adjnode], &heapsize[crucnode], &heapsize[adjnode]);
1476 printf(
"unite exch (%d) (%d) \n ", crucnode, adjnode);
1481 while( !
nodeIsCrucial(graph, best_result, adjnode) && !pinned[adjnode] )
1485 if( best_result[e] != -1 )
1491 adjnode = graph->
head[e];
1492 if( !steinertree[adjnode] || !graphmark[adjnode] )
1494 assert(scanned[adjnode]);
1497 printf(
"unite exch 1 (%d) (%d) \n ", crucnode, adjnode);
1502 SCIPpairheapMeldheaps(scip, &boundpaths[crucnode], &boundpaths[adjnode], &heapsize[crucnode], &heapsize[adjnode]);
1512 for( k = 0; k < nnodes; k++ )
1516 kptailnode = graph->
head[nodes[crucnode].
edge];
1517 kpathcost = graph->
cost[nodes[crucnode].
edge];
1519 printf(
"kpathhead: %d \n " ,crucnode);
1521 while( !
nodeIsCrucial(graph, best_result, kptailnode) && !pinned[kptailnode] )
1523 kpathcost += graph->
cost[nodes[kptailnode].
edge];
1525 printf(
"kpathinternal: %d \n " , kptailnode);
1526 kpnodes[nkpnodes++] = kptailnode;
1527 kptailnode = graph->
head[nodes[kptailnode].
edge];
1530 printf(
"kpathtail: %d \n " , kptailnode);
1536 for( k = 0; k < nkpnodes; k++ )
1539 blists_curr = blists_start[kpnodes[k]];
1540 while( blists_curr != NULL )
1542 node = blists_curr->
index;
1543 memvbase[nresnodes] = vbase[node];
1544 memdist[nresnodes] = vnoi[node].
dist;
1545 meminedges[nresnodes] = vnoi[node].
edge;
1551 blists_curr = blists_curr->
parent;
1557 while( boundpaths[crucnode] != NULL )
1559 SCIP_CALL(
SCIPpairheapDeletemin(scip, &e, &edgecost, &boundpaths[crucnode], &(heapsize[crucnode])) );
1561 k = vbase[graph->
tail[e]];
1562 l = vbase[graph->
head[e]];
1564 assert(graphmark[k]);
1567 assert(graphmark[adjnode]);
1570 if( node !=
UNKNOWN && node != crucnode && graphmark[l] )
1574 printf(
"edge %d_%d \n ", graph->
head[e], graph->
tail[e]);
1575 printf(
"add boundedge vbase : %d %d \n", k, l);
1577 SCIP_CALL(
SCIPpairheapInsert(scip, &boundpaths[crucnode], e, edgecost, &(heapsize[crucnode])) );
1582 if( boundpaths[crucnode] == NULL )
1595 for( k = 0; k < nkpnodes; k++ )
1597 blists_curr = blists_start[kpnodes[k]];
1598 assert( blists_curr != NULL );
1599 while( blists_curr != NULL )
1601 node = blists_curr->
index;
1606 adjnode = graph->
tail[edge];
1609 if( state[adjnode] ==
CONNECT && SCIPisGT(scip, vnoi[node].dist, vnoi[adjnode].dist + graph->
cost[edge])
1610 && graphmark[vbase[adjnode]] && graphmark[adjnode] )
1612 vnoi[node].
dist = vnoi[adjnode].
dist + graph->
cost[edge];
1613 vbase[node] = vbase[adjnode];
1614 vnoi[node].
edge = edge;
1621 blists_curr = blists_curr->
parent;
1630 voronoi_repair(scip, graph, graph->
cost, &count, vbase, vnoi, &newedge, crucnode, &uf);
1632 newedge = nodes[crucnode].
edge;
1634 if( oldedge !=
UNKNOWN && newedge !=
UNKNOWN && SCIPisLT(scip, edgecost,
1641 printf(
"final edge vronoi %d_%d \n ", vbase[graph->
tail[newedge]], vbase[graph->
head[newedge]]);
1643 edgecost = vnoi[graph->
tail[newedge]].
dist + graph->
cost[newedge] + vnoi[graph->
head[newedge]].
dist;
1644 if( SCIPisLT(scip, edgecost, kpathcost) )
1648 printf(
"ADDING NEW KEY PATH (%f )\n", edgecost - kpathcost );
1655 steinertree[crucnode] =
FALSE;
1656 graphmark[crucnode] =
FALSE;
1658 printf(
"unmarkcruc %d \n", crucnode);
1661 printf(
"delete: %d->%d \n", graph->
tail[
flipedge(nodes[crucnode].edge) ], graph->
head[
flipedge(nodes[crucnode].edge) ]);
1662 for( k = 0; k < nkpnodes; k++ )
1666 steinertree[kpnodes[k]] =
FALSE;
1667 graphmark[kpnodes[k]] =
FALSE;
1669 printf(
"unmarkkp %d \n", kpnodes[k]);
1671 printf(
"delete: %d->%d \n", graph->
tail[
flipedge(nodes[kpnodes[k]].edge) ], graph->
head[
flipedge(nodes[kpnodes[k]].edge)]);
1673 assert(graphmark[kptailnode]);
1675 if( node == crucnode )
1678 printf(
"whoaa \n \n");
1682 printf(
"vbases newedge %d %d \n", vbase[graph->
tail[newedge]], vbase[graph->
head[newedge]] );
1683 for( node = graph->
tail[newedge]; node != vbase[node]; node = graph->
tail[vnoi[node].
edge] )
1686 printf(
"unmarknew %d \n", node);
1687 graphmark[node] =
FALSE;
1693 printf(
"(->X)vbase %d \n", vbase[graph->
head[
flipedge(vnoi[node].edge)] ]);
1697 for( node = graph->
head[newedge]; node != vbase[node]; node = graph->
tail[vnoi[node].
edge] )
1700 printf(
"unmarknew %d \n", node);
1701 graphmark[node] =
FALSE;
1705 printf(
"add(head) %d->%d \n", graph->
tail[ (vnoi[node].edge) ], graph->
head[ (vnoi[node].edge) ]);
1709 printf(
"add %d->%d \n", graph->
tail[ (node == crucnode)? newedge :
flipedge(newedge) ], graph->
head[ (node == crucnode)? newedge :
flipedge(newedge) ]);
1712 newpathend = vbase[graph->
tail[newedge]];
1713 assert(node == vbase[graph->
head[newedge]] );
1719 while( k != crucnode )
1721 assert(graphmark[k]);
1722 assert( best_result[
flipedge(nodes[k].edge)] != -1);
1727 printf(
"flipedge: %d->%d \n", graph->
tail[nodes[k].edge ], graph->
head[nodes[k].edge ]);
1728 k = graph->
head[nodes[k].edge];
1731 for( k = 0; k < i; k++ )
1735 graphmark[dfstree[k]] =
FALSE;
1736 steinertree[dfstree[k]] =
FALSE;
1738 printf(
"unmarkEx %d \n", dfstree[k]);
1747 adjnode = graph->
head[edge];
1749 if( best_result[edge] ==
CONNECT && steinertree[adjnode] && graphmark[adjnode] &&
SCIPunionfindFind(&uf, adjnode) != node )
1751 assert(scanned[adjnode]);
1753 SCIPpairheapMeldheaps(scip, &boundpaths[node], &boundpaths[adjnode], &heapsize[node], &heapsize[adjnode]);
1756 printf(
"unite exch pinned (%d) (%d) \n ", node, adjnode);
1762 while( !
nodeIsCrucial(graph, best_result, adjnode) && !pinned[adjnode] )
1766 if( best_result[e] != -1 )
1772 adjnode = graph->
head[e];
1773 if( !steinertree[adjnode] )
1775 assert(scanned[adjnode]);
1778 printf(
"unite exch pinned 1 (%d) (%d) \n ", node, adjnode);
1784 SCIPpairheapMeldheaps(scip, &boundpaths[node], &boundpaths[adjnode], &heapsize[node], &heapsize[adjnode]);
1790 pinned[node] =
TRUE;
1795 for( k = 0; k < nkpnodes; k++ )
1798 blists_curr = blists_start[kpnodes[k]];
1799 while( blists_curr != NULL )
1801 node = blists_curr->
index;
1802 vbase[node] = memvbase[l];
1803 vnoi[node].
dist = memdist[l];
1804 vnoi[node].
edge = meminedges[l];
1806 blists_curr = blists_curr->
parent;
1809 assert(l == nresnodes);
1816 SCIP_CALL( SCIPallocBufferArray(scip, &xvbase, nnodes) );
1817 SCIP_CALL( SCIPallocBufferArray(scip, &xvnoi, nnodes) );
1819 voronoi(graph, cost, steinertree, xvbase, xvnoi);
1821 for( e = 0; e < nnodes; e++ )
1823 assert(vbase[e] == xvbase[e] && vnoi[e].dist == xvnoi[e].dist && vnoi[e].edge == xvnoi[e].edge);
1827 SCIPfreeBufferArray(scip, &xvbase);
1828 SCIPfreeBufferArray(scip, &xvnoi);
1829 SCIP_Bool* edgemark;
1830 SCIP_CALL( SCIPallocBufferArray(scip, &edgemark, nedges / 2) );
1831 for( e = 0; e < nedges / 2; e++ ){
1832 if( best_result[2*e] == 0 || best_result[
flipedge(2*e)] == 0)
1835 edgemark[e] =
FALSE;
1839 SCIPfreeBufferArray(scip, &edgemark);
1849 SCIPfreeBufferArray(scip, &kpedges);
1850 SCIPfreeBufferArray(scip, &kpnodes);
1851 SCIPfreeBufferArray(scip, &supernodes);
1853 for( k = 0; k < nnodes; k++ )
1855 if( boundpaths[k] != NULL )
1860 blists_curr = blists_start[k];
1861 lvledges_curr = lvledges_start[k];
1862 while( lvledges_curr != NULL )
1864 lvledges_start[k] = lvledges_curr->
parent;
1865 SCIPfreeMemory(scip, &lvledges_curr);
1866 lvledges_curr = lvledges_start[k];
1869 while( blists_curr != NULL )
1871 blists_start[k] = blists_curr->
parent;
1872 SCIPfreeMemory(scip, &blists_curr);
1873 blists_curr = blists_start[k];
1878 if( localmoves > 0 )
1880 for( i = 0; i < nnodes; i++ )
1882 steinertree[i] =
FALSE;
1883 graphmark[i] =
TRUE;
1888 for( e = 0; e < nedges; e++ )
1893 if( best_result[e] != -1 )
1895 steinertree[graph->
tail[e]] =
TRUE;
1896 steinertree[graph->
head[e]] =
TRUE;
1900 assert( nodes[root].edge == -1 );
1901 nodes[root].
edge = -1;
1906 SCIPfreeBufferArray(scip, &nodesmark);
1907 SCIPfreeBufferArray(scip, &dfstree);
1908 SCIPfreeBufferArray(scip, &pinned);
1909 SCIPfreeBufferArray(scip, &boundpaths);
1910 SCIPfreeBufferArray(scip, &meminedges);
1911 SCIPfreeBufferArray(scip, &memdist);
1912 SCIPfreeBufferArray(scip, &memvbase);
1913 SCIPfreeBufferArray(scip, &blists_start);
1914 SCIPfreeBufferArray(scip, &heapsize);
1915 SCIPfreeBufferArray(scip, &scanned);
1916 SCIPfreeBufferArray(scip, &supernodesid);
1917 SCIPfreeBufferArray(scip, &boundedges);
1918 SCIPfreeBufferArray(scip, &lvledges_start);
1919 SCIPfreeBufferArray(scip, &newedges);
1926 for( e = 0; e < nedges; e++)
1927 obj += (best_result[e] > -1) ? graph->
cost[e] : 0.0;
1929 printf(
" ObjAfterHeurLocal=%.12e\n", obj);
1932 SCIPfreeBufferArray(scip, &steinertree);
1933 SCIPfreeBufferArray(scip, &nodes);
1934 SCIPfreeBufferArray(scip, &vbase);
1935 SCIPfreeBufferArray(scip, &vnoi);
1959 assert(adds != NULL);
1960 assert(scip != NULL);
1961 assert(vnoi != NULL);
1962 assert(graph != NULL);
1963 assert(stedge != NULL);
1964 assert(costrev != NULL);
1965 assert(stvertex != NULL);
1968 nnodes = graph->
knots;
1969 nedges = graph->
edges;
1974 for( i = 0; i < nnodes; i++ )
1975 stvertex[i] =
FALSE;
1979 for( e = 0; e < nedges; e++ )
1984 while( newnverts > 0)
1988 for( i = 0; i < nnodes; i++ )
1998 SCIPdebugMessage(
"add terminal %d %f < %f \n\n", i, graph->
cost[e], graph->
prize[i]);
2007 for( i = 0; i < nnodes; i++ )
2017 SCIPdebugMessage(
"add terminal %d %f head %d: \n\n", i, graph->
prize[i], graph->
head[e]);
2027 for( i = 0; i < nnodes; i++ )
2029 if( stvertex[i] && vbase[i] !=
UNKNOWN && vbase[i] != i && !
Is_term(graph->
term[i]) )
2033 if( !stvertex[vbase[i]] && SCIPisLT(scip, vnoi[i].dist, 0.0) )
2036 while( k != vbase[i] )
2045 SCIPdebugMessage(
"add vertex %d (vbase: %d, cost: %f \n", k, i, graph->
prize[k]);
2059 SCIPdebugMessage(
"\n vertices added! \n");
2060 for( e = 0; e < nedges; e++ )
2076 assert(scip != NULL);
2077 assert(heur != NULL);
2078 assert(strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0);
2090 SCIP_HEURDATA* heurdata;
2092 assert(heur != NULL);
2093 assert(strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0);
2094 assert(scip != NULL);
2097 heurdata = SCIPheurGetData(heur);
2098 assert(heurdata != NULL);
2099 SCIPfreeMemoryArray(scip, &(heurdata->lastsolindices));
2100 SCIPfreeMemory(scip, &heurdata);
2101 SCIPheurSetData(heur, NULL);
2110 SCIP_HEURDATA* heurdata;
2111 SCIP_PROBDATA* probdata;
2134 assert(heur != NULL);
2135 assert(scip != NULL);
2136 assert(strcmp(SCIPheurGetName(heur),
HEUR_NAME) == 0);
2137 assert(result != NULL);
2140 heurdata = SCIPheurGetData(heur);
2141 assert(heurdata != NULL);
2142 lastsolindices = heurdata->lastsolindices;
2143 assert(lastsolindices != NULL);
2145 probdata = SCIPgetProbData(scip);
2146 assert(probdata != NULL);
2149 assert(graph != NULL);
2151 *result = SCIP_DIDNOTRUN;
2160 if( SCIPgetSubscipDepth(scip) > 0 )
2164 if( SCIPgetBestSol(scip) == NULL )
2168 sols = SCIPgetSols(scip);
2169 nsols = SCIPgetNSols(scip);
2170 nedges = graph->
edges;
2172 assert(heurdata->maxnsols >= 0);
2174 min = MIN(heurdata->maxnsols, nsols);
2177 for( v = 0; v < min; v++ )
2179 if( SCIPsolGetIndex(sols[v]) != lastsolindices[v] )
2182 for( i = min - 1; i >= v + 1; i-- )
2183 lastsolindices[i] = lastsolindices[i - 1];
2202 fptr=fopen(
"redMW.txt",
"a");
2213 fptr=fopen(
"redStats.txt",
"a");
2230 fprintf(fptr,
"%d %d %d %d %f\n", (graph->
knots), graph->
orgknots, ((graph->
edges) / 2 ), graph->
orgedges / 2, SCIPgetReadingTime(scip));
2242 fptr=fopen(
"redtime.txt",
"a");
2251 fprintf(fptr,
"%f\n",(SCIPgetReadingTime(scip)));
2259 lastsolindices[v] = SCIPsolGetIndex(newsol);
2266 if( SCIPsolGetHeur(newsol) == heur )
2269 *result = SCIP_DIDNOTFIND;
2278 assert(vars != NULL);
2279 assert(xval != NULL);
2285 if( !
Is_term(graph->
term[graph->
head[e]]) && SCIPisEQ(scip, xval[e], 1.0) )
2292 SCIP_CALL( SCIPallocBufferArray(scip, &cost, nedges) );
2293 SCIP_CALL( SCIPallocBufferArray(scip, &costrev, nedges) );
2294 SCIP_CALL( SCIPallocBufferArray(scip, &results, nedges) );
2295 SCIP_CALL( SCIPallocBufferArray(scip, &nval, nvars) );
2298 for( e = 0; e < nedges; e++ )
2300 if( SCIPisEQ(scip, xval[e], 1.0) )
2307 for( e = 0; e < nedges; e += 2)
2309 if( SCIPvarGetUbLocal(vars[e + 1]) < 0.5 )
2316 costrev[e] = graph->
cost[e + 1];
2317 cost[e + 1] = costrev[e];
2320 if( SCIPvarGetUbLocal(vars[e]) < 0.5 )
2327 costrev[e + 1] = graph->
cost[e];
2328 cost[e] = costrev[e + 1];
2333 if( SCIPsolGetHeur(newsol) == NULL ||
2334 !(strcmp(SCIPheurGetName(SCIPsolGetHeur(newsol)),
"rec") == 0 ||
2335 strcmp(SCIPheurGetName(SCIPsolGetHeur(newsol)),
"TM") == 0) )
2338 SCIP_CALL( SCIPallocBufferArray(scip, &steinertree, graph->
knots) );
2340 for( e = 0; e < nedges; e++ )
2344 steinertree[graph->
tail[e]] =
TRUE;
2345 steinertree[graph->
head[e]] =
TRUE;
2354 SCIPfreeBufferArray(scip, &steinertree);
2361 for( v = 0; v < nvars; v++ )
2362 nval[v] = (results[v % nedges] == (v / nedges)) ? 1.0 : 0.0;
2371 for( v = 0; v < nvars; v++ )
2372 pobj += graph->
cost[v % nedges] * nval[v];
2386 *result = SCIP_FOUNDSOL;
2388 if( heurdata->nbestsols < heurdata->maxnsols && SCIPisGT(scip, SCIPgetSolOrigObj(scip, bestsol) -
SCIPprobdataGetOffset(scip), pobj) )
2390 heurdata->nfails = 0;
2391 heurdata->nbestsols++;
2393 SCIPdebugMessage(
"success in local: old: %f new: %f \n", (SCIPgetSolOrigObj(scip, bestsol) -
SCIPprobdataGetOffset(scip)), pobj);
2398 if( *result != SCIP_FOUNDSOL )
2402 heurdata->nbestsols--;
2404 SCIPdebugMessage(
"fail! %d \n", heurdata->nbestsols);
2407 SCIPfreeBufferArray(scip, &nval);
2408 SCIPfreeBufferArray(scip, &results);
2409 SCIPfreeBufferArray(scip, &costrev);
2410 SCIPfreeBufferArray(scip, &cost);
2425 SCIP_HEURDATA* heurdata;
2430 SCIP_CALL( SCIPallocMemory(scip, &heurdata) );
2432 heurdata->nfails = 1;
2436 SCIP_CALL( SCIPincludeHeurBasic(scip, &heur,
2440 assert(heur != NULL);
2443 SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyLocal) );
2444 SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeLocal) );
2447 SCIP_CALL( SCIPaddBoolParam(scip,
"stp/duringroot",
2448 "should the heuristic be called during the root node?",
2451 SCIP_CALL( SCIPaddBoolParam(scip,
"heuristics/"HEUR_NAME"/maxfreq",
2452 "should the heuristic be executed at maximum frequeny?",
2455 SCIP_CALL( SCIPaddIntParam(scip,
"heuristics/"HEUR_NAME"/maxnsols",
2456 "maximum number of best solutions to improve",
2459 SCIP_CALL( SCIPallocMemoryArray(scip, &(heurdata->lastsolindices), heurdata->maxnsols) );
2461 for( i = 0; i < heurdata->maxnsols; i++ )
2462 heurdata->lastsolindices[i] = -1;
SCIP_RETCODE graph_path_init(SCIP *, GRAPH *)
SCIP_RETCODE SCIPheurPruneSteinerTree(SCIP *scip, const GRAPH *g, SCIP_Real *cost, int layer, int *result, char *connected)
SCIP_RETCODE SCIPheurPrunePCSteinerTree(SCIP *scip, const GRAPH *g, SCIP_Real *cost, int *result, char *connected)
int graph_valid(const GRAPH *)
static char nodeIsCrucial(const GRAPH *graph, int *steineredges, int node)
void SCIPunionfindFree(SCIP *scip, UF *uf)
SCIP_RETCODE SCIPvalidateStpSol(SCIP *, const GRAPH *, const double *, SCIP_Bool *)
SCIP_VAR ** SCIPprobdataGetVars(SCIP *scip)
int SCIPunionfindFind(UF *uf, int element)
void SCIPpairheapMeldheaps(SCIP *scip, PHNODE **root1, PHNODE **root2, int *sizeroot1, int *sizeroot2)
static SCIP_DECL_HEURCOPY(heurCopyLocal)
void voronoi_repair(SCIP *, const GRAPH *, SCIP_Real *, int *, int *, PATH *, int *, int, UF *)
Problem data for stp problem.
void graph_path_exit(SCIP *, GRAPH *)
int SCIPprobdataGetNVars(SCIP *scip)
SCIP_RETCODE SCIPpairheapDeletemin(SCIP *scip, int *element, SCIP_Real *key, PHNODE **root, int *size)
static void dfsorder(const GRAPH *graph, int *edges, int *node, int *counter, int *dfst)
static int insert(const int knot, int *q_dist, int *q_head, int *q_prev, int *q_next, int dmin)
void graph_free(SCIP *, GRAPH *, SCIP_Bool)
void SCIPpairheapFree(SCIP *scip, PHNODE **root)
NODE * SCIPlinkcuttreeFindMax(SCIP *scip, const SCIP_Real *cost, NODE *v)
GRAPH * SCIPprobdataGetGraph(SCIP_PROBDATA *probdata)
#define STP_OBSTACLES_GRID
void voronoi(SCIP *scip, const GRAPH *, SCIP_Real *, SCIP_Real *, char *, int *, PATH *)
#define DEFAULT_DURINGROOT
void heap_add(int *, int *, int *, int, PATH *)
SCIP_RETCODE SCIPprobdataAddNewSol(SCIP *scip, SCIP_Real *nval, SCIP_SOL *sol, SCIP_HEUR *heur, SCIP_Bool *success)
SCIP_Real SCIPprobdataGetOffset(SCIP *scip)
#define DEFAULT_MAXFREQLOC
#define STP_MAX_NODE_WEIGHT
SCIP_RETCODE SCIPprobdataPrintGraph2(const GRAPH *graph, const char *filename, SCIP_Bool *edgemark)
SCIP_RETCODE SCIPheurImproveSteinerTree(SCIP *scip, GRAPH *graph, SCIP_Real *cost, SCIP_Real *costrev, int *best_result)
void SCIPlinkcuttreeInit(NODE *v)
Improvement heuristic for Steiner problems.
void SCIPlinkcuttreeEvert(NODE *v)
static SCIP_DECL_HEURFREE(heurFreeLocal)
void SCIPlinkcuttreeLink(NODE *v, NODE *w, int edge)
void SCIPunionfindUnion(UF *uf, int p, int q, SCIP_Bool compress)
static SCIP_DECL_HEUREXEC(heurExecLocal)
#define STP_PRIZE_COLLECTING
SCIP_RETCODE graph_init(SCIP *, GRAPH **, int, int, int, int)
NODE * SCIPlinkcuttreeFindMinMW(SCIP *scip, SCIP_Real *nodeweight, int *tail, int *stdeg, NODE *v)
SCIP_RETCODE SCIPpairheapInsert(SCIP *scip, PHNODE **root, int element, SCIP_Real key, int *size)
void voronoi_repair_mult(SCIP *, const GRAPH *, SCIP_Real *, int *, int *, int *, int *, char *, UF *, PATH *)
void SCIPlinkcuttreeCut(NODE *v)
SCIP_RETCODE extendSteinerTreePcMw(SCIP *scip, const GRAPH *graph, PATH *vnoi, SCIP_Real *costrev, int *vbase, int *stedge, char *stvertex, int *adds)
#define STP_ROOTED_PRIZE_COLLECTING
static SCIP_RETCODE lca(SCIP *scip, const GRAPH *graph, int u, UF *uf, char *nodesmark, int *steineredges, IDX **lcalists, PHNODE **boundpaths, int *heapsize, int *vbase)
SCIP_Real * SCIPprobdataGetXval(SCIP *scip, SCIP_SOL *sol)
#define DEFAULT_NBESTSOLS
shortest paths based primal heuristics for Steiner problems
SCIP_RETCODE SCIPunionfindInit(SCIP *scip, UF *uf, int length)
void graph_knot_add(GRAPH *, int)
SCIP_RETCODE SCIPpairheapBuffarr(SCIP *scip, PHNODE *root, int size, int **elements)
void voronoiSteinerTreeExt(SCIP *, const GRAPH *, SCIP_Real *, int *, char *, PATH *)
struct Int_List_Node * parent
SCIP_RETCODE SCIPincludeHeurLocal(SCIP *scip)
void graph_edge_add(SCIP *, GRAPH *, int, int, double, double)
#define DEFAULT_MAXNBESTSOLS
void graph_path_exec(SCIP *, const GRAPH *, int, int, SCIP_Real *, PATH *)