45 #define RESTRICT restrict 56 #define GLOBALRELABEL_ADD 10 57 #define GLOBALRELABEL_MULT 10 60 #define listdelete(node,nodedist,next,headactive)\ 63 assert(nodedist >= 0);\ 64 assert(headactive != NULL);\ 65 headactive[nodedist] = next[node];\ 69 #define listinsert(node,nodedist,next,headactive,actmin,actmax)\ 72 assert(next != NULL);\ 73 assert(headactive != NULL);\ 74 assert(nodedist >= 0);\ 75 next[node] = headactive[nodedist];\ 76 headactive[nodedist] = node;\ 77 if( nodedist < (actmin) )\ 79 if( nodedist > (actmax) )\ 84 #define listinsert(node,nodedist,next,headactive,actmin,actmax)\ 87 assert(next != NULL);\ 88 assert(headactive != NULL);\ 89 assert(nodedist >= 0);\ 90 next[node] = headactive[nodedist];\ 91 headactive[nodedist] = node;\ 92 if( nodedist < (actmin) )\ 94 if( nodedist > (actmax) )\ 101 #define activedelete(node,nodedist,next,headactive)\ 104 assert(nodedist >= 0);\ 105 assert(headactive != NULL);\ 106 headactive[nodedist] = next[node];\ 110 #define activeinsert(node,nodedist,next,headactive,actmin,actmax,glbmax)\ 113 assert(next != NULL);\ 114 assert(headactive != NULL);\ 115 assert(nodedist >= 0);\ 116 next[node] = headactive[nodedist];\ 117 headactive[nodedist] = node;\ 118 if( nodedist < (actmin) )\ 120 if( nodedist > (actmax) )\ 122 if( (actmax) > (glbmax) )\ 127 #define inactivedelete(node,nodedist,next,prev,headinactive,nextnode,prevnode)\ 130 assert(nodedist >= 0);\ 131 assert(next != NULL);\ 132 assert(prev != NULL);\ 133 assert(headinactive != NULL);\ 134 nextnode = next[node];\ 135 if( headinactive[nodedist] == node )\ 137 headinactive[nodedist] = nextnode;\ 139 prev[nextnode] = Q_NULL;\ 143 prevnode = prev[node];\ 144 assert(prevnode >= 0);\ 145 assert(next[prevnode] == node);\ 146 next[prevnode] = nextnode;\ 148 prev[nextnode] = prevnode;\ 153 #define inactiveinsert(node,nodedist,next,prev,headinactive,nextnode)\ 156 assert(nodedist >= 0);\ 157 assert(next != NULL);\ 158 assert(prev != NULL);\ 159 assert(headinactive != NULL);\ 160 nextnode = headinactive[nodedist];\ 161 next[node] = nextnode;\ 162 prev[node] = Q_NULL;\ 164 prev[nextnode] = node;\ 165 headinactive[nodedist] = node;\ 170 static int is_valid(
const GRAPH*,
const int,
const int,
const int*,
const int *);
171 static void show_flow(
const GRAPH*,
const int*,
const int*);
174 static void cut_statist(
void);
175 static void cut_sum(
const GRAPH*,
const int*,
const int*);
179 static int s_pushes = 0;
180 static int n_pushes = 0;
181 static int m_pushes = 0;
182 static int x_pushes = 0;
183 static int relabels = 0;
184 static int s_sleeps = 0;
185 static int m_sleeps = 0;
186 static int searches = 0;
187 static int cutsums = 0;
195 static int is_valid_arr(
201 const int* revedgearr,
223 for(j = 0; j < p->
knots; j++)
226 return ((
void) fprintf(stderr,
"Negativ Execess Node %d\n", j),
FALSE);
228 if( dist[j] >= p->
knots )
229 return ((
void) fprintf(stderr,
"Distance too big Node %d dist: %d\n", j, dist[j]),
FALSE);
232 for( k = startarr[j], end = startarr[j + 1]; k != end; k++ )
238 if( dist[j] > dist[head] + 1 && w[j] == 0 && w[head] == 0 )
240 printf(
"distance fail! %d->%d (%d)\n", j, head, k);
244 if( (w[j] && (w[j] < w[head])) )
246 printf(
"Extended Dormacy Violation %d %d \n", j, head);
249 if( w[j] && !w[head] )
251 printf(
"Simple Dormacy Violation %d %d \n", j, head);
254 if( (w[j] && !w[head]) || (w[j] && (w[j] < w[head])) )
256 (void) printf(
"e=%d r[e]=%d head=%d tail=%d w[h]=%d w[t]=%d\n",
257 k, r[k], head, p->
tail[k], w[head],
260 return ((
void) fprintf(stderr,
261 "Dormacy Violation Knot %d\n", j),
FALSE);
266 return ((
void) fprintf(stderr,
"Negativ Residual Edge %d\n", k),
FALSE);
284 const int* edgestart,
298 assert(temp !=
NULL);
299 assert(dist !=
NULL);
302 assert(s < p->knots);
304 assert(t < p->knots);
313 for( j = 0; j < visited; j++ )
315 assert(visited <= nnodes);
318 dplus1 = dist[i] + 1;
322 assert(dist[i] >= 0);
323 assert(dist[i] < visited);
326 for( l = edgestart[i], end = edgestart[i + 1]; l != end; l++ )
331 if( dist[k] < 0 && w[k] == 0 )
337 assert(dist[k] < nnodes);
356 assert(nnodes > 0 && nedges > 0);
378 const int nnodesreal,
380 int* RESTRICT headactive,
381 int* RESTRICT headinactive,
382 int* RESTRICT edgecurr,
385 int* RESTRICT excess,
386 int* RESTRICT residual,
388 const int* edgestart,
403 const int nnodes = nnodesreal;
404 const int end = *glbmax;
408 assert(s < nnodesreal);
410 assert(t < nnodesreal);
413 assert(headactive !=
NULL);
414 assert(headinactive !=
NULL);
415 assert(edgecurr !=
NULL);
416 assert(prev !=
NULL);
417 assert(next !=
NULL);
418 assert(residual !=
NULL);
419 assert(excess !=
NULL);
420 assert(edgearr !=
NULL);
421 assert(headarr !=
NULL);
422 assert(edgecurr !=
NULL);
423 assert(edgestart !=
NULL);
424 assert(headactive !=
NULL);
425 assert(headinactive !=
NULL);
427 assert(end < nnodes);
430 for(
int i = 0; i <= end; i++ )
439 for(
int i = 0; i <
nnodes; i++ )
440 assert(headactive[i] ==
Q_NULL && headinactive[i] ==
Q_NULL);
443 for(
int i = end + 1; i <
nnodes; i++ )
462 for( currdist = 0;
TRUE; currdist++ )
464 const int nextdist = currdist + 1;
467 if( (headactive[currdist] < 0) && (headinactive[currdist] < 0) )
471 for(
int i = headinactive[currdist]; i >= 0; i = next[i] )
473 const int edges_start = edgestart[i];
474 const int edges_end = edgestart[i + 1];
475 for(
int q = edges_start; q != edges_end; q++ )
477 if( residual[edgearr[q]] != 0 )
479 if( w[headarr[q]] < 0 )
481 const int k = headarr[q];
486 edgecurr[k] = edgestart[k];
490 activeinsert(k, nextdist, next, headactive, actminloc, actmaxloc, glbmaxloc);
502 for(
int i = headactive[currdist]; i >= 0; i = next[i] )
504 const int edges_start = edgestart[i];
505 const int edges_end = edgestart[i + 1];
506 for(
int q = edges_start; q != edges_end; q++ )
508 if( residual[edgearr[q]] != 0 )
510 const int k = headarr[q];
517 edgecurr[k] = edgestart[k];
521 activeinsert(k, nextdist, next, headactive, actminloc, actmaxloc, glbmaxloc);
533 assert((headactive[currdist] ==
Q_NULL) && (headinactive[currdist] ==
Q_NULL));
534 assert(currdist == 0 || (headactive[currdist - 1] !=
Q_NULL) || (headinactive[currdist - 1] !=
Q_NULL));
537 if( (currdist - 1) > (glbmaxloc) )
538 glbmaxloc = currdist - 1;
544 dormmaxnext = (*dormmax) + 1;
545 for(
int i = 0; i <
nnodes; i++ )
554 *dormmax = dormmaxnext;
569 const int nnodesreal,
570 const int rootcutsize,
574 int* RESTRICT headactive,
575 int* RESTRICT headinactive,
576 int* RESTRICT edgecurr,
580 int* RESTRICT excess,
581 int* RESTRICT residual,
583 const int* edgestart,
600 const int nnodes = nnodesreal;
612 assert(headactive !=
NULL);
613 assert(headinactive !=
NULL);
614 assert(prev !=
NULL);
615 assert(next !=
NULL);
616 assert(temp !=
NULL);
617 assert(residual !=
NULL);
618 assert(excess !=
NULL);
619 assert(edgearr !=
NULL);
620 assert(headarr !=
NULL);
621 assert(edgecurr !=
NULL);
622 assert(edgestart !=
NULL);
623 assert(headactive !=
NULL);
624 assert(headinactive !=
NULL);
640 for(
int i = nnodes - 1; i >= 0; i-- )
661 activeinsert(i, 1, next, headactive, actminloc, actmaxloc, glbmaxloc);
673 assert(nnodes <= p->edges);
675 for( i = 0; i <
nnodes; i++ )
679 edgecurr[i] = edgestart[i];
683 residual[i] = capa[i];
686 for( e = nnodes; e < nedges; e++ )
687 residual[e] = capa[e];
694 for( q = edgestart[s], end = edgestart[s + 1]; q != end; q++ )
698 if( residual[e] == 0 )
704 assert(residual[e] == capa[e]);
706 residual[
flipedge(e)] += residual[e];
707 excess[i] += residual[e];
712 for( i = 0; i <
nnodes; i++ )
727 assert(excess[s] == 0);
739 activeinsert(i, 1, next, headactive, actminloc, actmaxloc, glbmaxloc);
752 (void)bfs(p, s, t, dist, temp, w, capa, edgestart, edgearr, headarr);
755 for( i = 0; i <
nnodes; i++ )
758 if( (*dormmax) == 1 )
773 assert(dist[t] == 0);
776 for( q = edgestart[s], end = edgestart[s + 1]; q != end; q++ )
780 if( residual[e] == 0 )
785 assert(residual[e] == capa[e]);
787 residual[
flipedge(e)] += residual[e];
788 excess[i] += residual[e];
795 for( i = 0; i <
nnodes; i++ )
807 activeinsert(i, dist[i], next, headactive, actminloc, actmaxloc, glbmaxloc);
811 if( dist[i] > (glbmaxloc) )
827 assert(is_valid(p, s, t, capa, w));
836 const int nnodesreal,
837 const int rootcutsize,
841 int* RESTRICT headactive,
842 int* RESTRICT headinactive,
843 int* RESTRICT edgecurr,
847 int* RESTRICT excess,
848 int* RESTRICT residual,
850 const int* edgestart,
859 const int nnodes = nnodesreal;
879 assert(dist !=
NULL);
880 assert(prev !=
NULL);
881 assert(next !=
NULL);
882 assert(temp !=
NULL);
883 assert(residual !=
NULL);
884 assert(excess !=
NULL);
885 assert(edgearr !=
NULL);
886 assert(headarr !=
NULL);
887 assert(edgecurr !=
NULL);
888 assert(edgestart !=
NULL);
889 assert(headactive !=
NULL);
890 assert(headinactive !=
NULL);
904 for(
int i = nnodes - 1; i >= 0; i-- )
913 edgecurr[i] = edgestart[i];
915 else if( w[i] > (dormmaxloc) )
924 for(
int i = nnodes - 1; i >= 0; i-- )
930 if( (w[i] == 0) || (w[i] >= wt) )
934 edgecurr[i] = edgestart[i];
936 else if( w[i] > (dormmaxloc) )
953 for(
int j = 0; j < visited; j++ )
955 const int i = temp[j];
957 assert(visited <= nnodes);
960 assert(dist[i] >= 0);
961 assert(dist[i] < visited);
964 for(
int outedge = edgestart[i], end = edgestart[i + 1]; outedge != end; outedge++ )
966 const int k = headarr[outedge];
969 if( dist[k] < 0 && w[k] == 0 )
971 if( residual[edgearr[outedge]] > 0 )
973 dist[k] = dist[i] + 1;
975 assert(dist[k] < nnodes);
980 activeinsert(k, dist[k], next, headactive, actminloc, actmaxloc, glbmaxloc);
984 if( dist[k] > (glbmaxloc) )
996 dormmaxlocp1 = dormmaxloc + 1;
997 for(
int i = nnodes - 1; i >= 0; i-- )
1000 if( dist[i] < 0 && w[i] == 0 )
1003 w[i] = dormmaxlocp1;
1011 for( i = nnodes - 1; i >= 0; i-- )
1023 for( j = edgestart[i], end = edgestart[i + 1]; j != end; j++ )
1025 headnode = headarr[j];
1030 assert(residual[
flipedge(a)] == 0);
1035 residual[
a] = capa[
a];
1042 assert(dist[t] == 0);
1043 assert(temp[0] == t);
1046 for( i = 1; i < visited && 0; i++ )
1056 activeinsert(k, dist[k], next, headactive, actminloc, actmaxloc, glbmaxloc);
1060 if( dist[k] > (glbmaxloc) )
1061 glbmaxloc = dist[k];
1068 *dormmax = dormmaxloc;
1069 *actmin = actminloc;
1070 *actmax = actmaxloc;
1071 *glbmax = glbmaxloc;
1074 assert(is_valid(p, s, t, capa, w));
1086 int* RESTRICT excess = g->
mincut_e;
1090 assert(g && excess && headactive && headinactive);
1093 for(
int k = 0; k <
nnodes; k++ )
1096 for(
int k = 0; k <
nnodes; k++ )
1097 headinactive[k] =
Q_NULL;
1099 for(
int k = 0; k <
nnodes; k++ )
1206 const int nnodesreal,
1207 const int nedgesreal,
1208 const int rootcutsize,
1212 const int* edgestart,
1233 int* RESTRICT edgecurr;
1234 int* RESTRICT headactive;
1235 int* RESTRICT headinactive;
1246 int relabelupdatebnd;
1250 assert(s < p->knots);
1252 assert(t < p->knots);
1283 initialise(s, t, nnodesreal, rootcutsize, rootcut, capa, dist, headactive, headinactive, edgecurr, next, prev, temp, e, r, w, edgestart,
1284 edgearr, headarr, &dormmax, &actmin, &actmax, &glbmax);
1288 reinitialise(s, t, nnodesreal, rootcutsize, rootcut, capa, dist, headactive, headinactive, edgecurr, next, prev, temp, e, r, w, edgestart,
1289 edgearr, headarr, &dormmax, &actmin, &actmax, &glbmax);
1293 while( actmax >= actmin )
1295 const int i = headactive[actmax];
1305 assert(actmax <= glbmax);
1306 assert(dist[i] == actmax);
1315 end = edgestart[i + 1];
1317 assert(end > edgestart[i]);
1323 for( j = edgecurr[i]; j != end; j++ )
1329 if( w[headarr[j]] == 0 )
1331 headnode = headarr[j];
1333 assert(w[headnode] == 0);
1334 assert(headnode != s);
1336 dminus1 = dist[i] - 1;
1339 if( dist[headnode] == dminus1 )
1341 assert(
Min(e[i], r[j]) > 0);
1344 if( e[headnode] == 0 )
1349 inactivedelete(headnode, dminus1, next, prev, headinactive, nextnode, prevnode);
1352 activeinsert(headnode, dminus1, next, headactive, actmin, actmax, glbmax);
1360 e[headnode] += r[j];
1361 r[edgearr[j]] += r[j];
1369 r[edgearr[j]] += e[i];
1371 e[headnode] += e[i];
1392 if( (headactive[dist[i]] < 0) && (headinactive[dist[i]] < 0) )
1397 assert(dormmax <= nnodes);
1398 assert(dist[i] < nnodes);
1401 for( j = dist[i] + 1; j <= glbmax; j++ )
1403 assert(headactive[j] ==
Q_NULL);
1405 for( l = headinactive[j]; l >= 0; l = next[l] )
1410 headinactive[j] =
Q_NULL;
1413 actmax = dist[i] - 1;
1422 assert(end == edgestart[i + 1]);
1434 for( ; j != end; j++ )
1440 if( w[headarr[j]] == 0 )
1443 if( dist[headarr[j]] < mindist )
1445 mindist = dist[headarr[j]];
1449 if( dist[headarr[j]] <= mindist )
1451 if( dist[headarr[j]] < mindist )
1453 mindist = dist[headarr[j]];
1457 minnode = headarr[j];
1458 maxresnode = headarr[j];
1460 else if( r[j] > maxresval )
1464 maxresnode = headarr[j];
1471 if( (++mindist) <
nnodes )
1473 assert(minedgestart >= 0);
1474 assert(r[minedgestart] > 0);
1479 if( glbmax < mindist )
1482 assert(maxresnode >= 0);
1483 assert(maxresnode == headarr[maxresedge]);
1486 if( r[minedgestart] >= e[i] )
1489 if( e[minnode] == 0 )
1493 inactivedelete(minnode, dist[minnode], next, prev, headinactive, nextnode, prevnode);
1494 activeinsert(minnode, dist[minnode], next, headactive, actmin, actmax, glbmax);
1498 r[edgearr[minedgestart]] += e[i];
1499 r[minedgestart] -= e[i];
1505 edgecurr[i] = minedgestart;
1512 if( e[minnode] == 0 )
1516 inactivedelete(minnode, dist[minnode], next, prev, headinactive, nextnode, prevnode);
1517 activeinsert(minnode, dist[minnode], next, headactive, actmin, actmax, glbmax);
1521 e[i] -= r[minedgestart];
1522 e[minnode] += r[minedgestart];
1523 r[edgearr[minedgestart]] += r[minedgestart];
1524 r[minedgestart] = 0;
1528 if( maxresval >= e[i] && minedgestart != maxresedge )
1531 if( e[maxresnode] == 0 )
1533 if( maxresnode != t )
1536 inactivedelete(maxresnode, dist[maxresnode], next, prev, headinactive, nextnode, prevnode);
1539 activeinsert(maxresnode, dist[maxresnode], next, headactive, actmin, actmax, glbmax);
1543 r[edgearr[maxresedge]] += e[i];
1544 r[maxresedge] -= e[i];
1545 e[maxresnode] += e[i];
1550 edgecurr[i] = minedgestart;
1555 edgecurr[i] = minedgestart + 1;
1566 assert(dormmax <= nnodes);
1568 assert(!((headactive[dist[i]] ==
Q_NULL) && (headinactive[dist[i]] ==
Q_NULL)));
1570 if( relabeltrigger > relabelupdatebnd )
1572 if( actmax < actmin )
1576 globalrelabel(s, t, nnodesreal, dist, headactive, headinactive, edgecurr, next, prev,
1577 e, r, w, edgestart, edgearr, headarr, &actmin, &actmax, &glbmax, &dormmax);
1598 if( relabeltrigger > relabelupdatebnd )
1600 if( actmax < actmin )
1604 globalrelabel(s, t, nnodesreal, dist, headactive, headinactive, edgecurr, next, prev,
1605 e, r, w, edgestart, edgearr, headarr, &actmin, &actmax, &glbmax, &dormmax);
1615 if( !is_valid_arr(p, s, t, edgestart, headarr, edgearr, r, capa, w) )
1616 printf(
"flow is not valid \n");
1617 assert(is_valid_arr(p, s, t, edgestart, headarr, edgearr, r, capa, w));
1623 cut_sum(p, capa, w);
1627 assert(is_valid(p, s, t, capa, w));
1632 static void cut_statist(
void)
1634 (void)printf(
"Mincut Statistics:\n");
1635 (void)printf(
"Node-Searches=%d, Cut Sums=%d\n",
1637 (void)printf(
"S-Pushes=%d, N-Pushes=%d, X-Pushes=%d, M-Pushes=%d\n",
1638 s_pushes, n_pushes, x_pushes, m_pushes);
1639 (void)printf(
"Relabels=%d, S-Sleeps=%d, M-Sleeps=%d\n\n",
1640 relabels, s_sleeps, m_sleeps);
1653 static void cut_sum(
1664 assert(capa !=
NULL);
1667 for(k = 0; k < p->
edges; k++)
1672 if ((w[i] && !w[j]) || (!w[i] && w[j]))
1676 (void)printf(
"Cut Sum=%d\n", sum);
1686 static int is_valid(
1715 for (j = 0; j < p->
knots; j++)
1721 if( dist[j] > dist[p->
head[k]] + 1 )
1723 printf(
"distance fail! %d->%d (%d)\n", j, p->
head[k], k);
1731 for(j = 0; j < p->
knots; j++)
1734 if ((q[j] >= 0) && (
a[q[j]] != j))
1735 return((
void)fprintf(stderr,
"Queue Error 1 Knot %d\n", j),
FALSE);
1737 if (!w[j] && (q[j] < 0) && (e[j] > 0) && (j != t))
1738 return((
void)fprintf(stderr,
"Queue Error 2 Knot %d\n", j),
FALSE);
1740 if (!w[j] && (q[j] >= 0) && (e[j] == 0))
1741 return((
void)fprintf(stderr,
"Queue Error 3 Knot %d\n", j),
FALSE);
1743 if (w[j] && (q[j] >= 0))
1744 return((
void)fprintf(stderr,
"Queue Error 4 Knot %d\n", j),
FALSE);
1747 return((
void)fprintf(stderr,
"Negativ Execess Knot %d\n", j),
FALSE);
1750 return((
void)fprintf(stderr,
"Distance too big Knot %d\n", j),
FALSE);
1759 if( dist[j] > dist[p->
head[k]] + 1 && w[j] == 0 && w[p->
head[k]] == 0 )
1761 printf(
"distance fail! %d->%d (%d)\n", j, p->
head[k], k);
1766 if((w[j] && (w[j] < w[p->
head[k]])))
1768 printf(
"fail %d %d\n", j, p->
head[k]);
1771 if( w[j] && !w[p->
head[k]] )
1773 printf(
"fail2 %d -> %d\n", j, p->
head[k]);
1774 printf(
"w: %d -> w: %d \n", w[j], w[p->
head[k]]);
1775 printf(
"edge %d \n", k);
1778 if ((w[j] && !w[p->
head[k]]) || (w[j] && (w[j] < w[p->
head[k]])))
1780 (void)printf(
"k=%d r[k]=%d head=%d tail=%d w[h]=%d w[t]=%d\n",
1783 return((
void)fprintf(stderr,
"Extended Dormacy Violation Knot %d\n", j),
FALSE);
1788 for(j = 0; j < p->
edges; j++)
1791 return((
void)fprintf(stderr,
"Negativ Residual Edge %d\n", j),
FALSE);
1794 return((
void)fprintf(stderr,
"Wrong Capacity Equation Edge %d\n", j),
FALSE);
1797 return((
void)fprintf(stderr,
"Negativ Flow Edge %d\n", j),
FALSE);
1799 if (r[j] != capa[j] - x[j] + x[
Edge_anti(j)])
1800 return((
void)fprintf(stderr,
"Wrong Residual Equation Edge %d\n", j),
FALSE);
1806 static void show_flow(
1841 for(j = 0; j < p->
edges; j++)
1842 (
void)printf(
"%6d ", j);
1843 (void)fputc(
'\n', stdout);
1845 (void)printf(
"ta:");
1846 for(j = 0; j < p->
edges; j++)
1847 (
void)printf(
"%6d ", p->
tail[j]);
1848 (void)fputc(
'\n', stdout);
1850 (void)printf(
"he:");
1851 for(j = 0; j < p->
edges; j++)
1852 (
void)printf(
"%6d ", p->
head[j]);
1853 (void)fputc(
'\n', stdout);
1855 (void)printf(
"x: ");
1856 for(j = 0; j < p->
edges; j++)
1857 (
void)printf(
"%6d ", x[j]);
1858 (void)fputc(
'\n', stdout);
1860 (void)printf(
"r: ");
1861 for(j = 0; j < p->
edges; j++)
1862 (
void)printf(
"%6d ", r[j]);
1863 (void)fputc(
'\n', stdout);
1865 (void)printf(
"ca:");
1866 for(j = 0; j < p->
edges; j++)
1867 (
void)printf(
"%6d ", capa[j]);
1868 (void)fputc(
'\n', stdout);
1870 (void)printf(
"w: ");
1871 for(j = 0; j < p->
knots; j++)
1872 (
void)printf(
"%2d ", w[j]);
1873 (void)fputc(
'\n', stdout);
1875 (void)printf(
"d: ");
1876 for(j = 0; j < p->
knots; j++)
1878 (void)fputc(
'\n', stdout);
1880 (void)printf(
"n: ");
1881 for(j = 0; j < p->
knots; j++)
1882 (
void)printf(
"%2d ", numb[j]);
1883 (void)fputc(
'\n', stdout);
1885 (void)printf(
"h: ");
1886 for(j = 0; j < p->
knots; j++)
1887 (
void)printf(
"%2d ", head[j]);
1888 (void)fputc(
'\n', stdout);
1890 (void)printf(
"p: ");
1891 for(j = 0; j < p->
knots; j++)
1892 (
void)printf(
"%2d ", prev[j]);
1893 (void)fputc(
'\n', stdout);
1895 (void)printf(
"n: ");
1896 for(j = 0; j < p->
knots; j++)
1897 (
void)printf(
"%2d ", next[j]);
1898 (void)fputc(
'\n', stdout);
1900 (void)printf(
"e: ");
1901 for(j = 0; j < p->
knots; j++)
1902 (
void)printf(
"%2d ", e[j]);
1903 (void)fputc(
'\n', stdout);
2010 inline static void delete(
2018 assert(q_dist !=
NULL);
2019 assert(q_head !=
NULL);
2020 assert(q_prev !=
NULL);
2021 assert(q_next !=
NULL);
2022 assert(q_dist[knot] > 0);
2024 if (q_next[knot] != Q_NM)
2028 if (q_prev[knot] ==
Q_NULL)
2030 assert(q_dist[knot] >= 0);
2031 assert(q_head[q_dist[knot]] == knot);
2033 q_head[q_dist[knot]] = q_next[knot];
2037 assert(q_prev[knot] >= 0);
2038 assert(q_next[q_prev[knot]] == knot);
2040 q_next[q_prev[knot]] = q_next[knot];
2045 if (q_next[knot] !=
Q_NULL)
2047 assert(q_next[knot] >= 0);
2048 assert(q_prev[q_next[knot]] == knot);
2050 q_prev[q_next[knot]] = q_prev[knot];
2052 q_next[knot] = Q_NM;
2053 q_prev[knot] = Q_NM;
2055 assert(q_next[knot] == Q_NM);
2056 assert(q_prev[knot] == Q_NM);
2059 inline static int insert(
2069 assert(q_dist !=
NULL);
2070 assert(q_head !=
NULL);
2071 assert(q_prev !=
NULL);
2072 assert(q_next !=
NULL);
2073 assert(q_dist[knot] > 0);
2076 if( q_prev[knot] == Q_NM )
2079 q_next[knot] = q_head[q_dist[knot]];
2081 if( q_next[knot] !=
Q_NULL )
2082 q_prev[q_next[knot]] = knot;
2084 q_head[q_dist[knot]] = knot;
2086 if( q_dist[knot] < dmin )
2087 dmin = q_dist[knot];
2088 if( q_dist[knot] > (*dlmax) )
2089 *dlmax = q_dist[knot];
2091 assert(q_next[knot] != Q_NM);
2092 assert(q_prev[knot] != Q_NM);
2093 assert(q_dist[knot] >= dmin);
2107 const int* edgestart,
2118 assert(q_temp !=
NULL);
2119 assert(q_dist !=
NULL);
2120 assert(q_numb !=
NULL);
2123 assert(s < p->knots);
2125 assert(t < p->knots);
2128 q_temp[visited++] = t;
2134 for(j = 0; (j < visited) && (visited < p->knots); j++)
2136 assert(visited < p->knots);
2137 assert(j < visited);
2142 assert(i < p->knots);
2143 assert(q_dist[i] >= 0);
2144 assert(q_dist[i] < visited);
2147 assert((j == 0) || (q_dist[i] >= q_dist[q_temp[j - 1]]));
2148 assert((j == visited - 1) || (q_dist[i] <= q_dist[q_temp[j + 1]]));
2152 for( k = edgestart[i], end = edgestart[i + 1]; k != end; k++ )
2158 assert(!w[l] || (q_dist[l] >= 0));
2162 q_dist[l] = q_dist[i] + 1;
2163 q_temp[visited++] = l;
2164 q_numb[q_dist[l]]++;
2166 assert(q_dist[l] < p->
knots);
2205 assert(s < p->knots);
2207 assert(t < p->knots);
2210 assert(q_head !=
NULL);
2211 assert(q_dist !=
NULL);
2212 assert(q_numb !=
NULL);
2213 assert(q_prev !=
NULL);
2214 assert(q_next !=
NULL);
2215 assert(q_temp !=
NULL);
2216 assert(excess !=
NULL);
2217 assert(transx !=
NULL);
2218 assert(residual !=
NULL);
2226 for( i = 0; i <
nnodes; i++ )
2241 q_temp[visited++] = t;
2245 for( j = 0; (j < visited) && (visited < nnodes); j++ )
2247 assert(visited < nnodes);
2248 assert(j < visited);
2254 assert(q_dist[i] < nnodes);
2257 dist1 = q_dist[i] + 1;
2259 assert(dist1 < nnodes);
2267 if( (w[l] < 0) && (residual[
flipedge(k)] > 0) )
2271 q_temp[visited++] = l;
2274 q_numb[q_dist[l]]++;
2279 listinsert(l, dist1, q_next, q_head, (*dmin), (*dlmax));
2281 assert(q_dist[l] < nnodes);
2288 for( i = 0; i <
nnodes; i++ )
2292 w[i] = *dormmax + 1;
2296 *dormmax = (*dormmax) + 1;
2329 const int* edgestart,
2345 assert(s < p->knots);
2347 assert(t < p->knots);
2349 assert(capa !=
NULL);
2351 assert(q_head !=
NULL);
2352 assert(q_dist !=
NULL);
2353 assert(q_numb !=
NULL);
2354 assert(q_prev !=
NULL);
2355 assert(q_next !=
NULL);
2356 assert(q_temp !=
NULL);
2357 assert(excess !=
NULL);
2358 assert(transx !=
NULL);
2359 assert(residual !=
NULL);
2367 actminloc = p->
knots;
2369 for(i = 0; i < p->
knots; i++)
2380 for(k = 0; k < p->
edges; k++)
2383 residual[k] = capa[k];
2387 (void)bfs(p, s, t, q_dist, q_numb, q_temp, w, edgestart, edgearr, headarr);
2391 for(i = 0; i < p->
knots; i++)
2393 w[i] = *dormmax + 1;
2404 assert(q_dist[s] > 0);
2406 assert(q_dist[t] == 0);
2410 q_numb[q_dist[s]]--;
2414 for( q = edgestart[s], end = edgestart[s + 1]; q != end; q++ )
2423 transx[k] = capa[k];
2427 excess[j] += transx[k];
2431 listinsert(j, q_dist[j], q_next, q_head, actminloc, (*dlmax));
2435 assert(excess[j] > 0);
2439 assert((p->
mincut_x)[k] <= capa[k]);
2443 show_flow(p, capa, w);
2446 assert(is_valid(p, s, t, capa, w));
2465 const int* edgestart,
2480 assert(s < p->knots);
2482 assert(t < p->knots);
2484 assert(capa !=
NULL);
2486 assert(q_head !=
NULL);
2487 assert(q_dist !=
NULL);
2488 assert(q_numb !=
NULL);
2489 assert(q_prev !=
NULL);
2490 assert(q_next !=
NULL);
2491 assert(q_temp !=
NULL);
2492 assert(excess !=
NULL);
2493 assert(transx !=
NULL);
2494 assert(residual !=
NULL);
2499 wt = (w[t] == 0) ? p->
knots + 1 : w[t];
2500 actminloc = p->
knots;
2504 for( i = 0; i < p->knots; i++ )
2511 if( (w[i] == 0) || (w[i] >= wt) )
2516 else if( w[i] > *dormmax )
2521 visited = bfs(p, s, t, q_dist, q_numb, q_temp, w, edgestart, edgearr, headarr);
2525 for( i = 0; i < p->
knots; i++ )
2528 w[i] = *dormmax + 1;
2529 else if( (w[i] == 0) && (q_dist[i] > *dlmax) )
2535 for( k = 0; k < p->
edges; k += 2 )
2545 excess[i] += transx[k + 1] - transx[k];
2546 excess[j] += transx[k] - transx[k + 1];
2548 residual[k] = capa[k];
2550 residual[k + 1] = capa[k + 1];
2555 assert(q_dist[t] == 0);
2556 assert(q_temp[0] == t);
2560 for( i = 1; i < visited; i++ )
2562 assert(w[q_temp[i]] == 0);
2563 assert(q_temp[i] != s);
2564 assert(q_temp[i] != t);
2566 if (excess[q_temp[i]] > 0)
2568 listinsert(q_temp[i], q_dist[q_temp[i]], q_next, q_head, actminloc, *dlmax);
2572 show_flow(p, capa, w);
2575 assert(is_valid(p, s, t, capa, w));
2594 const int rootcutsize,
2598 const int* edgestart,
2628 int relabelupdatebnd;
2633 assert(s < p->knots);
2635 assert(t < p->knots);
2637 assert(capa !=
NULL);
2664 initialise(p, s, t, capa, dist, numb, head, prev, next, temp, e, x, r, w, edgestart,
2665 edgearr, headarr, &dormmax, &dlmax);
2667 reinitialise(p, s, t, capa, dist, numb, head, prev, next, temp, e, x, r, w, edgestart,
2668 edgearr, headarr, &dormmax, &dlmax);
2671 while( dlmax >= dmin )
2673 if( (head[dlmax] ==
Q_NULL) )
2684 assert(dist[i] == dlmax);
2686 startind = edgestart[i];
2687 end = edgestart[i + 1];
2688 glbadd = (end - startind);
2706 for( j = startind; j != end; j++ )
2709 if( r[edgearr[j]] > 0 )
2712 if( w[headarr[j]] == 0 )
2715 headnode = headarr[j];
2718 if( di1 != dist[headnode] )
2720 assert(dist[i] <= dist[headnode]);
2722 if( (dist[headnode] < min_dist) || ((dist[headnode] == min_dist) && (r[k] > min_capa)) )
2724 min_knot = headnode;
2725 min_dist = dist[min_knot];
2732 assert(
Min(e[i], r[k]) > 0);
2734 assert(headnode == p->
head[k]);
2736 if( e[headnode] == 0 && headnode != t )
2738 listinsert(headnode, dist[headnode], next, head, dmin, (dlmax));
2744 (e[i] == r[k]) ? x_pushes++ : n_pushes++;
2749 e[headnode] += e[i];
2752 assert(e[headnode] > 0);
2753 assert(w[headnode] == 0);
2756 assert(r[k] == capa[k] - x[k] + x[
Edge_anti(k)]);
2763 e[headnode] += r[k];
2769 assert(r[k] == capa[k] - x[k] + x[
Edge_anti(k)]);
2792 assert(numb[dist[i]] > 0);
2794 if( numb[dist[i]] == 1 )
2801 assert(dormmax <= nnodes);
2803 for( k = 0; k <
nnodes; k++ )
2806 if (!w[k] && (dist[i] < dist[k]))
2825 assert(dormmax <= nnodes);
2835 assert(min_dist < nnodes);
2836 assert(min_capa > 0);
2837 assert(min_knot >= 0);
2838 assert(min_arc >= 0);
2844 dist[i] = min_dist + 1;
2848 assert(dist[i] < nnodes);
2850 assert(min_capa > 0);
2851 assert(min_capa == r[min_arc]);
2852 assert(p->
head[min_arc] == min_knot);
2853 assert(p->
tail[min_arc] == i);
2854 assert(dist[i] == dist[min_knot] + 1);
2855 assert(w[min_knot] == 0);
2857 if (e[i] <= min_capa)
2859 if( (e[p->
head[min_arc]] == 0) && (p->
head[min_arc] != t) )
2867 e[min_knot] += e[i];
2870 assert(r[min_arc] + r[
Edge_anti(min_arc)] == capa[min_arc] + capa[
Edge_anti(min_arc)]);
2871 assert(r[min_arc] >= 0);
2872 assert(r[min_arc] == capa[min_arc] - x[min_arc] + x[
Edge_anti(min_arc)]);
2877 if( relabeltrigger > relabelupdatebnd )
2880 globalrelabel(p, s, t, dist, numb, head, prev, next, temp, e, x, r, w, &dormmax, &dlmax, &dmin);
2889 if( relabeltrigger > relabelupdatebnd )
2892 globalrelabel(p, s, t, dist, numb, head, prev, next, temp, e, x, r, w, &dormmax, &dlmax, &dmin);
2903 fptr = fopen(
"f2",
"a");
2905 fprintf(fptr,
"t: %d flow %d \n", t, e[t]);
2914 cut_sum(p, capa, w);
2917 show_flow(p, capa, w);
2920 assert(is_valid(p, s, t, capa, w));
2925 static void cut_statist(
void)
2927 (void)printf(
"Mincut Statistics:\n");
2928 (void)printf(
"Node-Searches=%d, Cut Sums=%d\n",
2930 (void)printf(
"S-Pushes=%d, N-Pushes=%d, X-Pushes=%d, M-Pushes=%d\n",
2931 s_pushes, n_pushes, x_pushes, m_pushes);
2932 (void)printf(
"Relabels=%d, S-Sleeps=%d, M-Sleeps=%d\n\n",
2933 relabels, s_sleeps, m_sleeps);
2946 static void cut_sum(
2957 assert(capa !=
NULL);
2960 for(k = 0; k < p->
edges; k++)
2965 if ((w[i] && !w[j]) || (!w[i] && w[j]))
2969 (void)printf(
"Cut Sum=%d\n", sum);
2976 static int is_valid(
2998 for(j = 0; j < p->
knots; j++)
3001 if ((q[j] >= 0) && (
a[q[j]] != j))
3002 return((
void)fprintf(stderr,
"Queue Error 1 Knot %d\n", j),
FALSE);
3004 if (!w[j] && (q[j] < 0) && (e[j] > 0) && (j != t))
3005 return((
void)fprintf(stderr,
"Queue Error 2 Knot %d\n", j),
FALSE);
3007 if (!w[j] && (q[j] >= 0) && (e[j] == 0))
3008 return((
void)fprintf(stderr,
"Queue Error 3 Knot %d\n", j),
FALSE);
3010 if (w[j] && (q[j] >= 0))
3011 return((
void)fprintf(stderr,
"Queue Error 4 Knot %d\n", j),
FALSE);
3014 return((
void)fprintf(stderr,
"Negativ Execess Knot %d\n", j),
FALSE);
3017 return((
void)fprintf(stderr,
"Distance too big Knot %d\n", j),
FALSE);
3025 if ((w[j] && !w[p->
head[k]]) || (w[j] && (w[j] < w[p->
head[k]])))
3027 (void)printf(
"k=%d r[k]=%d head=%d tail=%d w[h]=%d w[t]=%d\n",
3030 return((
void)fprintf(stderr,
"Extended Dormacy Violation Knot %d\n", j),
FALSE);
3035 for(j = 0; j < p->
edges; j++)
3038 return((
void)fprintf(stderr,
"Negativ Residual Edge %d\n", j),
FALSE);
3041 return((
void)fprintf(stderr,
"Negativ Flow Edge %d\n", j),
FALSE);
3044 return((
void)fprintf(stderr,
"Wrong Capacity Equation Edge %d\n", j),
FALSE);
3046 if (r[j] != capa[j] - x[j] + x[
Edge_anti(j)])
3047 return((
void)fprintf(stderr,
"Wrong Residual Equation Edge %d\n", j),
FALSE);
3052 static void show_flow(
3087 for(j = 0; j < p->
edges; j++)
3088 (
void)printf(
"%6d ", j);
3089 (void)fputc(
'\n', stdout);
3091 (void)printf(
"ta:");
3092 for(j = 0; j < p->
edges; j++)
3093 (
void)printf(
"%6d ", p->
tail[j]);
3094 (void)fputc(
'\n', stdout);
3096 (void)printf(
"he:");
3097 for(j = 0; j < p->
edges; j++)
3098 (
void)printf(
"%6d ", p->
head[j]);
3099 (void)fputc(
'\n', stdout);
3101 (void)printf(
"x: ");
3102 for(j = 0; j < p->
edges; j++)
3103 (
void)printf(
"%6d ", x[j]);
3104 (void)fputc(
'\n', stdout);
3106 (void)printf(
"r: ");
3107 for(j = 0; j < p->
edges; j++)
3108 (
void)printf(
"%6d ", r[j]);
3109 (void)fputc(
'\n', stdout);
3111 (void)printf(
"ca:");
3112 for(j = 0; j < p->
edges; j++)
3113 (
void)printf(
"%6d ", capa[j]);
3114 (void)fputc(
'\n', stdout);
3116 (void)printf(
"w: ");
3117 for(j = 0; j < p->
knots; j++)
3118 (
void)printf(
"%2d ", w[j]);
3119 (void)fputc(
'\n', stdout);
3121 (void)printf(
"d: ");
3122 for(j = 0; j < p->
knots; j++)
3124 (void)fputc(
'\n', stdout);
3126 (void)printf(
"n: ");
3127 for(j = 0; j < p->
knots; j++)
3128 (
void)printf(
"%2d ", numb[j]);
3129 (void)fputc(
'\n', stdout);
3131 (void)printf(
"h: ");
3132 for(j = 0; j < p->
knots; j++)
3133 (
void)printf(
"%2d ", head[j]);
3134 (void)fputc(
'\n', stdout);
3136 (void)printf(
"p: ");
3137 for(j = 0; j < p->
knots; j++)
3138 (
void)printf(
"%2d ", prev[j]);
3139 (void)fputc(
'\n', stdout);
3141 (void)printf(
"n: ");
3142 for(j = 0; j < p->
knots; j++)
3143 (
void)printf(
"%2d ", next[j]);
3144 (void)fputc(
'\n', stdout);
3146 (void)printf(
"e: ");
3147 for(j = 0; j < p->
knots; j++)
3148 (
void)printf(
"%2d ", e[j]);
3149 (void)fputc(
'\n', stdout);
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
#define SCIPfreeMemoryArray(scip, ptr)
SCIP_RETCODE graph_mincut_init(SCIP *scip, GRAPH *p)
static void initialise(const int s, const int t, const int nnodesreal, const int rootcutsize, const int *rootcut, const int *capa, int *RESTRICT dist, int *RESTRICT headactive, int *RESTRICT headinactive, int *RESTRICT edgecurr, int *RESTRICT next, int *RESTRICT prev, int *RESTRICT temp, int *RESTRICT excess, int *RESTRICT residual, int *RESTRICT w, const int *edgestart, const int *edgearr, const int *headarr, int *dormmax, int *actmin, int *actmax, int *glbmax)
#define inactivedelete(node, nodedist, next, prev, headinactive, nextnode, prevnode)
#define SCIPallocMemoryArray(scip, ptr, num)
int *RESTRICT mincut_temp
enum SCIP_Retcode SCIP_RETCODE
includes various files containing graph methods used for Steiner tree problems
static SCIP_RETCODE mincutInit(SCIP *scip, int nnodes, int nedges, GRAPH *p)
#define activedelete(node, nodedist, next, headactive)
SCIP_RETCODE graph_mincut_reInit(SCIP *scip, int nnodes, int nedges, GRAPH *p)
int *RESTRICT mincut_dist
void graph_mincut_setDefaultVals(GRAPH *g)
static void reinitialise(const int s, const int t, const int nnodesreal, const int rootcutsize, const int *rootcut, const int *capa, int *RESTRICT dist, int *RESTRICT headactive, int *RESTRICT headinactive, int *RESTRICT edgecurr, int *RESTRICT next, int *RESTRICT prev, int *RESTRICT temp, int *RESTRICT excess, int *RESTRICT residual, int *RESTRICT w, const int *edgestart, const int *edgearr, const int *headarr, int *dormmax, int *actmin, int *actmax, int *glbmax)
#define GLOBALRELABEL_MULT
int *RESTRICT mincut_head_inact
#define listdelete(node, nodedist, next, headactive)
#define listinsert(node, nodedist, next, headactive, actmin, actmax)
static void globalrelabel(const int s, const int t, const int nnodesreal, int *RESTRICT dist, int *RESTRICT headactive, int *RESTRICT headinactive, int *RESTRICT edgecurr, int *RESTRICT next, int *RESTRICT prev, int *RESTRICT excess, int *RESTRICT residual, int *RESTRICT w, const int *edgestart, const int *edgearr, const int *headarr, int *actmin, int *actmax, int *glbmax, int *dormmax)
int *RESTRICT mincut_head
int *RESTRICT mincut_prev
int *RESTRICT mincut_numb
#define activeinsert(node, nodedist, next, headactive, actmin, actmax, glbmax)
void graph_mincut_exit(SCIP *scip, GRAPH *p)
#define inactiveinsert(node, nodedist, next, prev, headinactive, nextnode)
SCIP_Bool graph_mincut_isInitialized(const GRAPH *p)
void graph_mincut_exec(const GRAPH *p, const int s, const int t, const int nnodesreal, const int nedgesreal, const int rootcutsize, const int *rootcut, const int *capa, int *RESTRICT w, const int *edgestart, const int *edgearr, const int *headarr, const SCIP_Bool isRerun)
#define GLOBALRELABEL_ADD
int *RESTRICT mincut_next