47 #define BETTERWEIGHTFORDEMANDNODES
57 #define SEPA_NAME "mcf"
58 #define SEPA_DESC "multi-commodity-flow network cut separator"
59 #define SEPA_PRIORITY -10000
61 #define SEPA_MAXBOUNDDIST 0.0
62 #define SEPA_USESSUBSCIP FALSE
63 #define SEPA_DELAY FALSE
66 #define DEFAULT_NCLUSTERS 5
67 #define DEFAULT_MAXWEIGHTRANGE 1e+06
68 #define DEFAULT_MAXTESTDELTA 20
69 #define DEFAULT_TRYNEGSCALING FALSE
70 #define DEFAULT_FIXINTEGRALRHS TRUE
71 #define DEFAULT_DYNAMICCUTS TRUE
72 #define DEFAULT_MODELTYPE 0
73 #define DEFAULT_MAXSEPACUTS 100
74 #define DEFAULT_MAXSEPACUTSROOT 200
75 #define DEFAULT_MAXINCONSISTENCYRATIO 0.02
76 #define DEFAULT_MAXARCINCONSISTENCYRATIO 0.5
77 #define DEFAULT_CHECKCUTSHORECONNECTIVITY TRUE
78 #define DEFAULT_SEPARATESINGLENODECUTS TRUE
79 #define DEFAULT_SEPARATEFLOWCUTSET TRUE
80 #define DEFAULT_SEPARATEKNAPSACK TRUE
83 #define BOUNDSWITCH 0.5
85 #define ALLOWLOCAL TRUE
89 #define MAXCOLS 2000000
90 #define MAXAGGRLEN(nvars) (0.1*(nvars)+1000)
91 #define MINCOLROWRATIO 0.01
92 #define MAXCOLROWRATIO 100.0
93 #define MAXFLOWVARFLOWROWRATIO 100.0
94 #define MAXARCNODERATIO 100.0
96 #define MAXFLOWCANDDENSITY 0.1
97 #define MINCOMNODESFRACTION 0.5
100 #define MAXCAPACITYSLACK 0.1
101 #define UNCAPACITATEDARCSTRESHOLD 0.8
102 #define HASHSIZE_NODEPAIRS 131101
114 #define MCFdebugMessage printf
118 #define MCFdebugMessage while(FALSE) printf
192 unsigned char* flowrowsigns;
195 unsigned char* capacityrowsigns;
204 int nemptycommodities;
206 int commoditysignssize;
227 int capacityrowssize;
254 int* representatives;
266 #define LHSPOSSIBLE 1u
267 #define RHSPOSSIBLE 2u
268 #define LHSASSIGNED 4u
269 #define RHSASSIGNED 8u
271 #define DISCARDED 32u
272 #define UNDIRECTED 64u
282 assert(mcfnetwork !=
NULL);
285 (*mcfnetwork)->nodeflowrows =
NULL;
286 (*mcfnetwork)->nodeflowscales =
NULL;
287 (*mcfnetwork)->nodeflowinverted =
NULL;
288 (*mcfnetwork)->arccapacityrows =
NULL;
289 (*mcfnetwork)->arccapacityscales =
NULL;
290 (*mcfnetwork)->arcsources =
NULL;
291 (*mcfnetwork)->arctargets =
NULL;
292 (*mcfnetwork)->colcommodity =
NULL;
293 (*mcfnetwork)->nnodes = 0;
294 (*mcfnetwork)->nuncapacitatedarcs = 0;
295 (*mcfnetwork)->narcs = 0;
296 (*mcfnetwork)->ncommodities = 0;
308 assert(mcfnetwork !=
NULL);
310 if( *mcfnetwork !=
NULL )
315 for( v = 0; v < (*mcfnetwork)->nnodes; v++ )
319 for( k = 0; k < (*mcfnetwork)->ncommodities; k++ )
321 if( (*mcfnetwork)->nodeflowrows[v][k] !=
NULL )
330 for( a = 0; a < (*mcfnetwork)->narcs; a++ )
332 if( (*mcfnetwork)->arccapacityrows[a] !=
NULL )
365 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
366 SCIP_Real* flowrowscalars = mcfdata->flowrowscalars;
367 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
368 int* flowcands = mcfdata->flowcands;
369 int nflowcands = mcfdata->nflowcands;
370 int ncommodities = mcfdata->ncommodities;
371 int* commoditysigns = mcfdata->commoditysigns;
372 int* colcommodity = mcfdata->colcommodity;
373 int* rowcommodity = mcfdata->rowcommodity;
374 int* rownodeid = mcfdata->rownodeid;
375 SCIP_ROW** capacityrows = mcfdata->capacityrows;
384 int ncompcommodities;
391 assert(mcfnetwork !=
NULL);
393 assert(2 <= ncompnodes && ncompnodes <= mcfdata->nnodes);
394 assert(1 <= ncomparcs && ncomparcs <= mcfdata->narcs);
395 assert(ncommodities > 0);
399 for( v = 0; v < mcfdata->nnodes; v++ )
400 assert(compnodeid[v] == -1);
411 for( k = 0; k < ncommodities; k++ )
412 compcommodity[k] = -1;
419 for( i = 0; i < ncompnodes; i++ )
422 assert(0 <= v && v < mcfdata->nnodes);
427 ncompcommodities = 0;
428 for( i = 0; i < nflowcands; i++ )
434 assert(0 <= r && r < nrows);
437 if( rv >= 0 && compnodeid[rv] >= 0 )
440 assert(0 <= k && k < ncommodities);
441 if( compcommodity[k] == -1 )
443 compcommodity[k] = ncompcommodities;
454 mcfnetwork->
nnodes = ncompnodes;
455 mcfnetwork->
narcs = ncomparcs;
463 for( v = 0; v < mcfnetwork->
nnodes; v++ )
481 for( a = 0; a < mcfnetwork->
narcs; a++ )
491 for( i = 0; i < nflowcands; i++ )
497 assert(0 <= r && r < nrows);
500 if( rv >= 0 && compnodeid[rv] >= 0 )
506 rk = rowcommodity[r];
507 assert(v < mcfnetwork->nnodes);
508 assert(0 <= rk && rk < ncommodities);
511 k = compcommodity[rk];
512 assert(0 <= k && k < mcfnetwork->ncommodities);
517 scale = flowrowscalars[r];
520 if( commoditysigns[rk] == -1 )
528 for( a = 0; a < mcfnetwork->
narcs; a++ )
538 globala = comparcs[a];
539 capacityrow = capacityrows[globala];
544 if( capacityrow !=
NULL)
547 assert(0 <= r && r < nrows);
549 assert((capacityrowsigns[r] &
INVERTED) == 0);
550 assert(mcfdata->rowarcid[r] == globala);
568 for( j = 0; j < rowlen; j++ )
575 if( comdemands[k] != 0.0 )
590 for( j = 0; j < rowlen; j++ )
595 if( k >= 0 && comdemands[k] == 0.0 )
607 if( mcfdata->arcsources[globala] >= 0 )
609 assert(mcfdata->arcsources[globala] < mcfdata->nnodes);
610 assert(0 <= compnodeid[mcfdata->arcsources[globala]] && compnodeid[mcfdata->arcsources[globala]] < mcfnetwork->
nnodes);
611 mcfnetwork->
arcsources[a] = compnodeid[mcfdata->arcsources[globala]];
613 if( mcfdata->arctargets[globala] >= 0 )
615 assert(mcfdata->arctargets[globala] < mcfdata->nnodes);
616 assert(0 <= compnodeid[mcfdata->arctargets[globala]] && compnodeid[mcfdata->arctargets[globala]] < mcfnetwork->
nnodes);
617 mcfnetwork->
arctargets[a] = compnodeid[mcfdata->arctargets[globala]];
622 for( c = 0; c < ncols; c++ )
632 for( i = 0; i < ncompnodes; i++ )
634 assert(0 <= compnodes[i] && compnodes[i] < mcfdata->nnodes);
635 assert(compnodeid[compnodes[i]] == i);
636 compnodeid[compnodes[i]] = -1;
649 void mcfnetworkPrint(
653 if( mcfnetwork ==
NULL )
660 for( v = 0; v < mcfnetwork->
nnodes; v++ )
679 for( a = 0; a < mcfnetwork->
narcs; a++ )
695 void printCommodities(
700 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
701 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
702 int ncommodities = mcfdata->ncommodities;
703 int* commoditysigns = mcfdata->commoditysigns;
704 int* colcommodity = mcfdata->colcommodity;
705 int* rowcommodity = mcfdata->rowcommodity;
706 int* colarcid = mcfdata->colarcid;
707 int* rownodeid = mcfdata->rownodeid;
708 int nnodes = mcfdata->nnodes;
709 SCIP_ROW** capacityrows = mcfdata->capacityrows;
725 for( k = 0; k < ncommodities; k++ )
729 for( c = 0; c < ncols; c++ )
731 if( colcommodity[c] == k )
734 for( r = 0; r < nrows; r++ )
736 if( rowcommodity[r] == k )
739 (flowrowsigns[r] &
INVERTED) != 0 ? -1 : +1);
744 if( rownodeid !=
NULL )
748 for( v = 0; v < nnodes; v++ )
751 for( r = 0; r < nrows; r++ )
753 if( rownodeid[r] == v )
756 (flowrowsigns[r] &
INVERTED) != 0 ? -1 : +1);
762 assert(capacityrows !=
NULL || mcfdata->narcs == 0);
765 for( a = 0; a < mcfdata->narcs; a++ )
768 if( capacityrows[a] !=
NULL )
771 assert(0 <= r && r < nrows);
774 else if( (capacityrowsigns[r] &
RHSASSIGNED) != 0 )
782 assert(colcommodity !=
NULL || ncols == 0);
785 for( c = 0; c < ncols; c++ )
787 if( colcommodity[c] == -1 )
796 for( r = 0; r < nrows; r++ )
798 assert(rowcommodity !=
NULL);
800 if( rowcommodity[r] == -1 && (capacityrowsigns ==
NULL || (capacityrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) == 0) )
816 if( rowscores[ind2] < rowscores[ind1] )
818 else if( rowscores[ind2] > rowscores[ind1] )
831 unsigned char* flowrowsigns;
851 flowrowsigns = mcfdata->flowrowsigns;
852 flowrowscalars = mcfdata->flowrowscalars;
853 flowrowscores = mcfdata->flowrowscores;
854 flowcands = mcfdata->flowcands;
856 assert(mcfdata->nflowcands == 0);
859 for( r = 0; r < nrows; r++ )
884 absdualsol = ABS(absdualsol);
887 flowrowscalars[r] = 0.0;
888 flowrowscores[r] = 0.0;
909 coef = ABS(rowvals[0]);
916 for( i = 0; i < rowlen; i++ )
922 hasposcoef = hasposcoef || (rowvals[i] > 0.0);
923 hasnegcoef = hasnegcoef || (rowvals[i] < 0.0);
953 flowrowscalars[r] = 1.0/coef;
954 flowcands[mcfdata->nflowcands] = r;
955 mcfdata->nflowcands++;
962 if(
SCIPisEQ(scip, flowrowscalars[r], 1.0) )
963 flowrowscores[r] += 1000.0;
966 if( hasposcoef && hasnegcoef )
967 flowrowscores[r] += 500.0;
974 if( ncontvars == rowlen )
975 flowrowscores[r] += 1000.0;
976 else if( nintvars + nimplintvars == rowlen )
977 flowrowscores[r] += 500.0;
978 else if( nbinvars == rowlen )
979 flowrowscores[r] += 100.0;
983 flowrowscores[r] += 10.0*rowlen/(rowlen+10.0);
987 flowrowscores[r] += 50.0;
989 assert(flowrowscores[r] > 0.0);
992 maxdualflow =
MAX(maxdualflow, absdualsol);
1005 for( i = 0; i < mcfdata->nflowcands; i++ )
1010 assert(0 <= r && r < nrows);
1015 dualsol = ABS(dualsol);
1018 assert(maxdualflow > 0.0);
1019 flowrowscores[r] += dualsol/maxdualflow + 1.0;
1020 assert(flowrowscores[r] > 0.0);
1025 SCIPsortInd(mcfdata->flowcands, compCands, (
void*)flowrowscores, mcfdata->nflowcands);
1027 MCFdebugMessage(
"flow conservation candidates [%d]\n", mcfdata->nflowcands);
1029 for( r = 0; r < mcfdata->nflowcands; r++ )
1032 SCIPdebugMessage(
"%4d [score: %2g]: %s\n", mcfdata->flowcands[r], flowrowscores[mcfdata->flowcands[r]],
1047 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1048 int* colcommodity = mcfdata->colcommodity;
1049 int ncommodities = mcfdata->ncommodities;
1050 int nactivecommodities = mcfdata->ncommodities - mcfdata->nemptycommodities;
1053 unsigned char* capacityrowsigns;
1062 int maxcolspercommoditylimit;
1063 int *ncolspercommodity;
1064 int *maxcolspercommodity;
1074 capacityrowsigns = mcfdata->capacityrowsigns;
1075 capacityrowscores = mcfdata->capacityrowscores;
1076 capacitycands = mcfdata->capacitycands;
1078 assert(mcfdata->ncapacitycands == 0);
1088 maxcolspercommoditylimit = 2;
1091 maxcolspercommoditylimit = 1;
1094 maxcolspercommoditylimit = 2;
1097 SCIPerrorMessage(
"invalid parameter value %d for model type\n", modeltype);
1101 maxdualcapacity = 0.0;
1102 directedcandsscore = 0.0;
1103 undirectedcandsscore = 0.0;
1104 for( r = 0; r < nrows; r++ )
1114 int nposcapacitycoefs;
1115 int nnegcapacitycoefs;
1117 int ncoveredcommodities;
1122 unsigned char rowsign;
1128 capacityrowsigns[r] = 0;
1129 capacityrowscores[r] = 0.0;
1141 if( (flowrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) != 0 )
1148 absdualsol = ABS(absdualsol);
1157 maxcolspercommodity[r] = 0;
1162 nposcapacitycoefs = 0;
1163 nnegcapacitycoefs = 0;
1165 ncoveredcommodities = 0;
1167 sameabsflowcoef = 0.0;
1168 maxabscapacitycoef = 0.0;
1175 for( i = 0; i < rowlen; i++ )
1184 k = colcommodity[c];
1185 assert(-1 <= k && k < ncommodities);
1190 abscoef = ABS(rowvals[i]);
1191 if( sameflowcoef == 0.0 )
1192 sameflowcoef = rowvals[i];
1193 else if( !
SCIPisEQ(scip, sameflowcoef, rowvals[i]) )
1195 if( sameabsflowcoef == 0.0 )
1196 sameabsflowcoef = abscoef;
1197 else if( !
SCIPisEQ(scip, sameabsflowcoef, abscoef) )
1200 if( rowvals[i] > 0.0 )
1206 if( ncolspercommodity[k] == 0 )
1207 ncoveredcommodities++;
1208 ncolspercommodity[k]++;
1209 maxcolspercommodity[r] =
MAX(maxcolspercommodity[r], ncolspercommodity[k]);
1211 if( ncolspercommodity[k] >= 2 )
1220 abscoef = ABS(rowvals[i]);
1221 if( abscoef > maxabscapacitycoef )
1222 maxabscapacitycoef = abscoef;
1225 if( rowvals[i] > 0.0 )
1226 nposcapacitycoefs++;
1228 nnegcapacitycoefs++;
1238 if( rowsign != 0 && nposflowcoefs + nnegflowcoefs > 0 )
1242 capacityrowsigns[r] |= rowsign;
1243 capacitycands[mcfdata->ncapacitycands] = r;
1244 mcfdata->ncapacitycands++;
1247 capacityrowscores[r] = 1.0;
1251 assert(ncoveredcommodities > 0);
1252 commodityexcessratio =
1253 ABS((nposflowcoefs + nnegflowcoefs)/(
SCIP_Real)ncoveredcommodities - maxcolspercommoditylimit);
1255 capacityrowscores[r] += 1000.0 *
MAX(0.0, 2.0 - commodityexcessratio);
1262 if( (capacityrowsigns[r] &
RHSPOSSIBLE) != 0 && nnegflowcoefs == 0 && nposcapacitycoefs == 0 && nnegcapacitycoefs > 0 )
1263 capacityrowscores[r] += 1000.0;
1264 if( (capacityrowsigns[r] &
LHSPOSSIBLE) != 0 && nposflowcoefs == 0 && nposcapacitycoefs > 0 && nnegcapacitycoefs == 0 )
1265 capacityrowscores[r] += 1000.0;
1274 assert(nactivecommodities + 3 > 0);
1275 capacityrowscores[r] += 2000.0 * ncoveredcommodities/(
SCIP_Real)(nactivecommodities + 3);
1278 if(
SCIPisEQ(scip, ABS(sameflowcoef), 1.0) )
1279 capacityrowscores[r] += 500.0;
1283 capacityrowscores[r] += 250.0;
1286 if(
SCIPisEQ(scip, sameabsflowcoef, 1.0) )
1287 capacityrowscores[r] += 100.0;
1290 if( maxabscapacitycoef > 0.0 && !
SCIPisEQ(scip, maxabscapacitycoef, 1.0) )
1291 capacityrowscores[r] += 100.0;
1294 capacityrowscores[r] += 20.0 *
MAX(nposflowcoefs, nnegflowcoefs)/
MAX(1.0,(
SCIP_Real)(nposflowcoefs + nnegflowcoefs));
1297 capacityrowscores[r] += 10.0 *
MAX(nposcapacitycoefs, nnegcapacitycoefs)/(
SCIP_Real)(nposcapacitycoefs+nnegcapacitycoefs+1.0);
1300 if( (capacityrowsigns[r] & RHSPOSSIBLE) != 0 && !
SCIPisNegative(scip, rowrhs) )
1301 capacityrowscores[r] += 10.0;
1305 capacityrowscores[r] += 10.0;
1307 assert(capacityrowscores[r] > 0.0);
1308 SCIPdebugMessage(
"row <%s>: maxcolspercommodity=%d capacityrowsign=%d nposflowcoefs=%d nnegflowcoefs=%d nposcapacitycoefs=%d nnegcapacitycoefs=%d nbadcoefs=%d nactivecommodities=%d sameflowcoef=%g -> score=%g\n",
1309 SCIProwGetName(row), maxcolspercommodity[r], capacityrowsigns[r], nposflowcoefs, nnegflowcoefs, nposcapacitycoefs, nnegcapacitycoefs, nbadcoefs, nactivecommodities, sameflowcoef, capacityrowscores[r]);
1312 maxdualcapacity =
MAX(maxdualcapacity, absdualsol);
1317 assert(maxcolspercommoditylimit == 2);
1318 if( (capacityrowsigns[r] &
UNDIRECTED) != 0 )
1319 undirectedcandsscore += capacityrowscores[r];
1321 directedcandsscore += capacityrowscores[r];
1326 SCIPdebugMessage(
"row <%s>: rowsign = %d nposflowcoefs = %d nnegflowcoefs = %d -> discard\n",
1334 if( directedcandsscore > undirectedcandsscore )
1339 MCFdebugMessage(
"detected model type: %s (%g directed score, %g undirected score)\n",
1347 for( i = 0; i < mcfdata->ncapacitycands; i++ )
1349 r = capacitycands[i];
1350 assert(0 <= r && r < nrows);
1351 if( (capacityrowsigns[r] &
UNDIRECTED) != 0 )
1354 if( maxcolspercommodity[r] <= maxcolspercommoditylimit )
1355 capacityrowscores[r] -= 1000.0;
1361 mcfdata->modeltype = modeltype;
1369 for( i = 0; i < mcfdata->ncapacitycands; i++ )
1373 r = capacitycands[i];
1374 assert(0 <= r && r < nrows);
1379 dualsol = ABS(dualsol);
1382 assert(maxdualcapacity > 0.0);
1383 capacityrowscores[r] +=
MAX(dualsol, 0.0)/maxdualcapacity;
1384 assert(capacityrowscores[r] > 0.0);
1389 SCIPsortInd(mcfdata->capacitycands, compCands, (
void*)capacityrowscores, mcfdata->ncapacitycands);
1391 MCFdebugMessage(
"capacity candidates [%d]\n", mcfdata->ncapacitycands);
1393 for( r = 0; r < mcfdata->ncapacitycands; r++ )
1396 capacityrowscores[mcfdata->capacitycands[r]],
SCIProwGetName(rows[mcfdata->capacitycands[r]]));
1416 assert(mcfdata->ncommodities <= mcfdata->commoditysignssize);
1417 if( mcfdata->ncommodities == mcfdata->commoditysignssize )
1419 mcfdata->commoditysignssize =
MAX(2*mcfdata->commoditysignssize, mcfdata->ncommodities+1);
1422 assert(mcfdata->ncommodities < mcfdata->commoditysignssize);
1425 SCIPdebugMessage(
"**** creating new commodity %d ****\n", mcfdata->ncommodities);
1426 mcfdata->commoditysigns[mcfdata->ncommodities] = 0;
1427 mcfdata->ncommodities++;
1442 assert(source != target );
1443 assert(0 <= source && source < mcfdata->nnodes);
1444 assert(0 <= target && target < mcfdata->nnodes);
1445 assert(newarcid !=
NULL);
1447 *newarcid = mcfdata->narcs;
1450 assert(mcfdata->narcs <= mcfdata->arcarraysize);
1451 if( mcfdata->narcs == mcfdata->arcarraysize )
1453 mcfdata->arcarraysize =
MAX(2*mcfdata->arcarraysize, mcfdata->narcs+1);
1459 assert(mcfdata->narcs < mcfdata->arcarraysize);
1462 if( mcfdata->capacityrowssize < mcfdata->arcarraysize )
1464 mcfdata->capacityrowssize = mcfdata->arcarraysize;
1467 assert(mcfdata->narcs < mcfdata->capacityrowssize);
1470 SCIPdebugMessage(
"**** creating new arc %d: %d -> %d ****\n", mcfdata->narcs, source, target);
1472 mcfdata->arcsources[*newarcid] = source;
1473 mcfdata->arctargets[*newarcid] = target;
1474 mcfdata->nextoutarcs[*newarcid] = mcfdata->firstoutarcs[source];
1475 mcfdata->firstoutarcs[source] = *newarcid;
1476 mcfdata->nextinarcs[*newarcid] = mcfdata->firstinarcs[target];
1477 mcfdata->firstinarcs[target] = *newarcid;
1478 mcfdata->capacityrows[*newarcid] =
NULL;
1491 unsigned char rowsign,
1496 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1497 SCIP_Bool* plusflow = mcfdata->plusflow;
1498 SCIP_Bool* minusflow = mcfdata->minusflow;
1499 int ncommodities = mcfdata->ncommodities;
1500 int* commoditysigns = mcfdata->commoditysigns;
1501 int* colcommodity = mcfdata->colcommodity;
1502 int* rowcommodity = mcfdata->rowcommodity;
1503 int* newcols = mcfdata->newcols;
1514 assert(comcolids !=
NULL);
1515 assert(ncomcolids !=
NULL);
1524 invertrow = ((rowsign &
INVERTED) != 0);
1527 assert(rowcommodity[r] == -1);
1528 assert((flowrowsigns[r] | rowsign) == flowrowsigns[r]);
1530 assert(rowsign != 0);
1536 commoditysigns[k] = +1;
1565 else if( rowlhs > 0.0 )
1582 flowrowsigns[r] |= rowsign;
1584 SCIPdebugMessage(
"adding flow row %d <%s> with sign %+d%s to commodity %d [score:%g]\n",
1586 k, mcfdata->flowrowscores[r]);
1590 rowcommodity[r] = k;
1594 for( i = 0; i < rowlen; i++ )
1603 if( colcommodity[c] == -1 )
1605 assert(!plusflow[c]);
1606 assert(!minusflow[c]);
1608 colcommodity[c] = k;
1609 newcols[mcfdata->nnewcols] = c;
1610 mcfdata->nnewcols++;
1611 comcolids[*ncomcolids] = c;
1614 assert(colcommodity[c] == k);
1617 val = rowscale * rowvals[i];
1620 assert(!plusflow[c]);
1625 assert(!minusflow[c]);
1626 minusflow[c] =
TRUE;
1643 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1644 SCIP_Bool* plusflow = mcfdata->plusflow;
1645 SCIP_Bool* minusflow = mcfdata->minusflow;
1649 assert(mcfdata->commoditysigns[k] == 0);
1650 assert(comrows !=
NULL || ncomrows == 0);
1651 assert(comcolids !=
NULL);
1654 for( i = 0; i < ncomrows; i++ )
1658 unsigned char rowsign;
1660 assert(comrows !=
NULL);
1662 assert( row !=
NULL );
1665 assert(mcfdata->rowcommodity[r] == k);
1669 rowsign = flowrowsigns[r];
1670 assert((rowsign & (LHSASSIGNED |
RHSASSIGNED)) != 0);
1674 if( (rowsign & LHSASSIGNED) != 0 )
1681 for( i = 0; i < ncomcolids; i++ )
1688 assert(mcfdata->colcommodity[c] == k);
1691 plusflow[c] = minusflow[c];
1708 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1709 SCIP_Bool* plusflow = mcfdata->plusflow;
1710 SCIP_Bool* minusflow = mcfdata->minusflow;
1711 int ncommodities = mcfdata->ncommodities;
1712 int* colcommodity = mcfdata->colcommodity;
1713 int* rowcommodity = mcfdata->rowcommodity;
1717 assert(0 <= k && k < ncommodities);
1719 assert( ndelflowrows !=
NULL );
1720 assert( ndelflowvars !=
NULL );
1722 SCIPdebugMessage(
"deleting commodity %d (%d total commodities) with %d flow rows\n", k, ncommodities, nrows);
1727 for( n = 0; n < nrows; n++ )
1738 assert(rowcommodity[r] == k);
1739 assert((flowrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) != 0);
1747 rowcommodity[r] = -1;
1750 for( i = 0; i < rowlen; i++ )
1758 assert(colcommodity[c] == k || colcommodity[c] == -1);
1759 if(colcommodity[c] == k)
1761 colcommodity[c] = -1;
1764 plusflow[c] =
FALSE;
1765 minusflow[c] =
FALSE;
1774 if( k == ncommodities-1 )
1775 mcfdata->ncommodities--;
1777 mcfdata->nemptycommodities++;
1787 unsigned char* rowsign,
1791 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1792 SCIP_Bool* plusflow = mcfdata->plusflow;
1793 SCIP_Bool* minusflow = mcfdata->minusflow;
1794 int* colcommodity = mcfdata->colcommodity;
1795 int* rowcommodity = mcfdata->rowcommodity;
1796 int* commoditysigns = mcfdata->commoditysigns;
1801 unsigned char flowrowsign;
1802 unsigned char invflowrowsign;
1806 assert(invertcommodity !=
NULL);
1809 *invertcommodity =
FALSE;
1815 if( rowcommodity[r] != -1 )
1819 flowrowsign = flowrowsigns[r];
1825 invflowrowsign = flowrowsign;
1831 for( j = 0; j < rowlen && (flowrowsign != 0 || invflowrowsign != 0); j++ )
1839 if( colcommodity[rowc] == k )
1842 if( plusflow[rowc] )
1845 if( rowvals[j] > 0.0 )
1856 if( minusflow[rowc] )
1859 if( rowvals[j] > 0.0 )
1871 else if( colcommodity[rowc] != -1 )
1879 if( flowrowsign != 0 )
1882 *rowsign = flowrowsign;
1883 *invertcommodity =
FALSE;
1885 else if( invflowrowsign != 0 )
1891 if( commoditysigns ==
NULL || commoditysigns[k] == 0 )
1894 *rowsign = invflowrowsign;
1895 *invertcommodity =
TRUE;
1900 *rowsign = (invflowrowsign |
INVERTED);
1901 *invertcommodity =
FALSE;
1918 unsigned char* nextrowsign,
1922 SCIP_Real* flowrowscores = mcfdata->flowrowscores;
1923 SCIP_Bool* plusflow = mcfdata->plusflow;
1924 SCIP_Bool* minusflow = mcfdata->minusflow;
1925 int* newcols = mcfdata->newcols;
1926 int ncommodities = mcfdata->ncommodities;
1931 assert(nextrow !=
NULL);
1932 assert(nextrowsign !=
NULL);
1936 *nextinvertcommodity =
FALSE;
1941 assert(cols !=
NULL);
1944 while( mcfdata->nnewcols > 0 )
1950 unsigned char bestrowsign;
1957 c = newcols[mcfdata->nnewcols-1];
1958 mcfdata->nnewcols--;
1962 assert(plusflow[c] || minusflow[c]);
1963 if( plusflow[c] && minusflow[c] )
1969 bestinvertcommodity =
FALSE;
1974 for( i = 0; i < collen; i++ )
1977 unsigned char flowrowsign;
1983 getFlowrowFit(scip, mcfdata, row, k, &flowrowsign, &invertcommodity);
1986 if( flowrowsign != 0 )
1993 score = flowrowscores[r];
1994 assert(score > 0.0);
2000 if( (flowrowsign &
INVERTED) != 0 )
2003 if( score > bestscore )
2006 bestrowsign = flowrowsign;
2007 bestinvertcommodity = invertcommodity;
2017 if( bestrow !=
NULL )
2019 assert(bestscore > 0.0);
2020 assert(bestrowsign != 0);
2022 *nextrowsign = bestrowsign;
2023 *nextinvertcommodity = bestinvertcommodity;
2038 int* flowcands = mcfdata->flowcands;
2065 assert(failed !=
NULL);
2074 plusflow = mcfdata->plusflow;
2075 minusflow = mcfdata->minusflow;
2076 colcommodity = mcfdata->colcommodity;
2077 rowcommodity = mcfdata->rowcommodity;
2089 for( c = 0; c < ncols; c++ )
2090 colcommodity[c] = -1;
2091 for( r = 0; r < nrows; r++ )
2092 rowcommodity[r] = -1;
2094 assert(flowcands !=
NULL || mcfdata->nflowcands == 0);
2105 for( i = 0; i < mcfdata->nflowcands; i++ )
2108 unsigned char newrowsign;
2112 assert(flowcands !=
NULL);
2114 assert(0 <= r && r < nrows);
2118 getFlowrowFit(scip, mcfdata, newrow, mcfdata->ncommodities, &newrowsign, &newinvertcommodity);
2119 if( newrowsign == 0 )
2121 assert(!newinvertcommodity);
2122 assert((newrowsign &
INVERTED) == 0);
2125 SCIPdebugMessage(
" -------------------start new commodity %d--------------------- \n", mcfdata->ncommodities );
2134 if( newinvertcommodity )
2135 invertCommodity(scip, mcfdata, mcfdata->ncommodities-1, comrows, nnodes, comcolids, ncomcolids);
2140 comrows[nnodes] = newrow;
2145 getNextFlowrow(scip, mcfdata, &newrow, &newrowsign, &newinvertcommodity);
2147 while( newrow !=
NULL );
2149 ncomnodes[mcfdata->ncommodities-1] = nnodes;
2150 maxnnodes =
MAX(maxnnodes, nnodes);
2151 nflowvars += ncomcolids;
2152 SCIPdebugMessage(
" -> finished commodity %d: identified %d nodes, maxnnodes=%d\n", mcfdata->ncommodities-1, nnodes, maxnnodes);
2160 deleteCommodity(scip, mcfdata, mcfdata->ncommodities-1, comrows, nnodes, &ndelflowrows, &ndelflowvars);
2161 nflowrows -= ndelflowrows;
2162 nflowvars -= ndelflowvars;
2163 assert(nflowvars >= 0);
2164 assert(nflowrows >= 0);
2168 for( k = 0; k < mcfdata->ncommodities; k++ )
2180 for( i = 0; i < mcfdata->nflowcands; i++ )
2182 assert(flowcands !=
NULL);
2184 if( rowcommodity[r] == k )
2186 comrows[nnodes] = rows[r];
2189 if( nnodes == ncomnodes[k] )
2194 assert(nnodes == ncomnodes[k]);
2195 deleteCommodity(scip, mcfdata, k, comrows, nnodes, &ndelflowrows, &ndelflowvars);
2196 nflowrows -= ndelflowrows;
2197 nflowvars -= ndelflowvars;
2198 assert(nflowvars >= 0);
2199 assert(nflowrows >= 0);
2208 MCFdebugMessage(
"identified %d commodities (%d empty) with a maximum of %d nodes and %d flowrows, %d flowvars \n",
2209 mcfdata->ncommodities, mcfdata->nemptycommodities, maxnnodes, nflowrows, nflowvars);
2211 assert(nflowvars >= 0);
2212 assert(nflowrows >= 0);
2231 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
2232 int* colcommodity = mcfdata->colcommodity;
2234 unsigned char* flowrowsigns = mcfdata->capacityrowsigns;
2235 int* rowcommodity = mcfdata->rowcommodity;
2251 SCIP_Real* capacityrowscores = mcfdata->capacityrowscores;
2253 int *capacitycands = mcfdata->capacitycands;
2254 int ncapacitycands = mcfdata->ncapacitycands;
2256 assert(mcfdata->narcs == 0);
2257 assert(capacitycands !=
NULL || ncapacitycands == 0);
2266 colarcid = mcfdata->colarcid;
2267 rowarcid = mcfdata->rowarcid;
2270 for( c = 0; c < ncols; c++ )
2272 for( r = 0; r < nrows; r++ )
2276 for( i = 0; i < ncapacitycands; i++ )
2282 int nassignedflowvars;
2283 int nunassignedflowvars;
2286 assert(capacitycands !=
NULL);
2287 r = capacitycands[i];
2288 assert(0 <= r && r < nrows );
2289 capacityrow = rows[r];
2293 assert((capacityrowsigns[r] &
DISCARDED) == 0);
2294 assert(capacityrowscores[r] > 0.0);
2297 assert((capacityrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) == 0);
2298 assert(rowarcid[r] == -1);
2301 assert( rowcommodity[r] == -1 );
2302 assert( (flowrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) == 0 );
2307 nassignedflowvars = 0;
2308 nunassignedflowvars = 0;
2309 for( k = 0; k < rowlen; k++ )
2312 assert(0 <= c && c < ncols);
2314 assert(-1 <= colcommodity[c] && colcommodity[c] < mcfdata->ncommodities);
2315 assert(-1 <= colarcid[c] && colarcid[c] < mcfdata->narcs);
2318 if( colcommodity[c] == -1 )
2322 if( colarcid[c] >= 0 )
2323 nassignedflowvars++;
2325 nunassignedflowvars++;
2332 if( nunassignedflowvars == 0 || nassignedflowvars >= nunassignedflowvars * 2 )
2334 SCIPdebugMessage(
"discarding capacity candidate row %d <%s> [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2335 r,
SCIProwGetName(capacityrow), mcfdata->capacityrowscores[r], nassignedflowvars, nunassignedflowvars);
2341 assert(mcfdata->narcs <= mcfdata->capacityrowssize);
2342 if( mcfdata->narcs == mcfdata->capacityrowssize )
2344 mcfdata->capacityrowssize =
MAX(2*mcfdata->capacityrowssize, mcfdata->narcs+1);
2347 assert(mcfdata->narcs < mcfdata->capacityrowssize);
2348 assert(mcfdata->narcs < nrows);
2350 mcfdata->capacityrows[mcfdata->narcs] = capacityrow;
2353 assert(0 <= r && r < nrows);
2354 rowarcid[r] = mcfdata->narcs;
2365 SCIPdebugMessage(
"assigning capacity row %d <%s> with sign %+d to arc %d [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2367 mcfdata->capacityrowscores[r], nassignedflowvars, nunassignedflowvars);
2370 for( k = 0; k < rowlen; k++ )
2373 assert(0 <= rowc && rowc < ncols);
2378 if( colcommodity[rowc] >= 0 && colarcid[rowc] == -1 )
2379 colarcid[rowc] = mcfdata->narcs;
2398 int* colcommodity = mcfdata->colcommodity;
2399 int* colarcid = mcfdata->colarcid;
2400 int* newcols = mcfdata->newcols;
2401 SCIP_ROW** capacityrows = mcfdata->capacityrows;
2402 SCIP_Bool* colisincident = mcfdata->colisincident;
2411 assert(!colisincident[i]);
2417 mcfdata->nnewcols = 0;
2419 for( i = 0; i < rowlen; i++ )
2432 arcid = colarcid[c];
2435 assert(arcid < mcfdata->narcs);
2438 assert(capacityrows[arcid] !=
NULL);
2442 for( j = 0; j < capacityrowlen; j++ )
2450 if( colcommodity[caprowc] == -1 )
2452 assert(colarcid[caprowc] == -1);
2455 assert(colarcid[caprowc] <= arcid);
2458 if( colcommodity[caprowc] == basecommodity )
2462 if( !colisincident[caprowc] )
2464 assert(mcfdata->nnewcols < SCIPgetNLPCols(scip));
2465 colisincident[caprowc] =
TRUE;
2466 newcols[mcfdata->nnewcols] = caprowc;
2467 mcfdata->nnewcols++;
2481 int* basearcpattern,
2490 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2491 int* commoditysigns = mcfdata->commoditysigns;
2492 int narcs = mcfdata->narcs;
2493 int* rowcommodity = mcfdata->rowcommodity;
2494 int* colarcid = mcfdata->colarcid;
2495 int* arcpattern = mcfdata->zeroarcarray;
2508 int* overlappingarcs;
2509 int noverlappingarcs;
2514 *invertcommodity =
FALSE;
2517 for( i = 0; i < narcs; i++ )
2518 assert(arcpattern[i] == 0);
2526 assert((flowrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) != 0);
2527 rowcom = rowcommodity[r];
2528 assert(0 <= rowcom && rowcom < mcfdata->ncommodities);
2529 rowcomsign = commoditysigns[rowcom];
2530 assert(-1 <= rowcomsign && rowcomsign <= +1);
2535 incompatible =
FALSE;
2536 noverlappingarcs = 0;
2540 for( i = 0; i < rowlen; i++ )
2550 valsign = (rowvals[i] > 0.0 ? +1 : -1);
2551 if( (flowrowsigns[r] & LHSASSIGNED) != 0 )
2553 if( (flowrowsigns[r] &
INVERTED) != 0 )
2556 arcid = colarcid[c];
2565 assert(arcid < narcs);
2568 if( basearcpattern[arcid] != 0 )
2575 if( ( valsign * basearcpattern[arcid] ) > 0 )
2580 if( rowcomsign == 0 )
2583 rowcomsign = validcomsign;
2585 else if( rowcomsign != validcomsign )
2588 incompatible =
TRUE;
2599 if( arcpattern[arcid] == 0 )
2601 overlappingarcs[noverlappingarcs] = arcid;
2604 arcpattern[arcid] += valsign;
2610 for( i = 0; i < noverlappingarcs; i++ )
2616 arcid = overlappingarcs[i];
2617 assert(0 <= arcid && arcid < narcs);
2620 basenum = ABS(basearcpattern[arcid]);
2621 arcnum = ABS(arcpattern[arcid]);
2622 assert(basenum != 0.0);
2623 assert(arcnum != 0.0);
2625 if( basenum > arcnum )
2626 overlap += arcnum/basenum;
2628 overlap += basenum/arcnum;
2630 arcpattern[arcid] = 0;
2634 if( !incompatible && overlap > 0.0 )
2637 int rowarcs = rowlen - nposuncap - nneguncap;
2638 int baserowarcs = baserowlen - basenposuncap - basenneguncap;
2641 assert(overlap <= (
SCIP_Real) baserowlen);
2642 assert(noverlappingarcs >= 1);
2644 *invertcommodity = (rowcomsign == -1);
2648 if( noverlappingarcs >= 2 )
2651 assert(rowarcs >= 0 && baserowarcs >= 0 );
2654 *score = overlap - (rowarcs + baserowarcs - 2.0 * overlap)/(2.0 * ncols + 1.0);
2656 *score = overlap - (rowarcs + baserowarcs - 4.0 * overlap)/(2.0 * ncols + 1.0);
2659 if(*invertcommodity)
2660 *score += 1.0 - (ABS(nneguncap - basenposuncap) + ABS(nposuncap - basenneguncap))/(2.0 * ncols + 1.0);
2662 *score += 1.0 - (ABS(nposuncap - basenposuncap) + ABS(nneguncap - basenneguncap))/(2.0 * ncols + 1.0);
2664 *score =
MAX(*score, 1e-6);
2668 SCIPdebugMessage(
" -> node similarity: row <%s>: incompatible=%u overlap=%g rowlen=%d baserowlen=%d score=%g\n",
2669 SCIProwGetName(row), incompatible, overlap, rowlen, baserowlen, *score);
2684 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2685 int ncommodities = mcfdata->ncommodities;
2686 int* commoditysigns = mcfdata->commoditysigns;
2687 int narcs = mcfdata->narcs;
2688 int* flowcands = mcfdata->flowcands;
2689 int nflowcands = mcfdata->nflowcands;
2690 int* rowcommodity = mcfdata->rowcommodity;
2691 int* colarcid = mcfdata->colarcid;
2692 int* newcols = mcfdata->newcols;
2713 assert(mcfdata->nnodes == 0);
2725 rownodeid = mcfdata->rownodeid;
2726 colisincident = mcfdata->colisincident;
2736 for( r = 0; r < nrows; r++ )
2738 for( c = 0; c < ncols; c++ )
2739 colisincident[c] =
FALSE;
2741 assert(flowcands !=
NULL || nflowcands == 0);
2744 for( n = 0; n < nflowcands; n++ )
2753 assert(flowcands !=
NULL);
2755 assert(0 <= r && r < nrows);
2758 basecommodity = rowcommodity[r];
2759 if( basecommodity == -1 )
2761 assert((flowrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) != 0);
2762 assert(mcfdata->rowarcid[r] == -1);
2765 if( rownodeid[r] >= 0 )
2769 SCIPdebugMessage(
"assigning row %d <%s> of commodity %d to node %d [score: %g]\n",
2770 r,
SCIProwGetName(rows[r]), basecommodity, mcfdata->nnodes, mcfdata->flowrowscores[r]);
2771 rownodeid[r] = mcfdata->nnodes;
2779 if(ncommodities == 1)
2794 if( (flowrowsigns[r] &
INVERTED) != 0 )
2796 if( commoditysigns[basecommodity] == -1 )
2799 for( i = 0; i < rowlen; i++ )
2804 assert(0 <= c && c < ncols);
2805 arcid = colarcid[c];
2810 arcpattern[arcid]++;
2812 arcpattern[arcid]--;
2825 for( i = 0; i < ncommodities; i++ )
2827 bestflowrows[i] =
NULL;
2828 bestscores[i] = 0.0;
2829 bestinverted[i] =
FALSE;
2841 for( i = 0; i < mcfdata->nnewcols; i++ )
2848 assert(0 <= c && c < ncols);
2849 assert(mcfdata->colcommodity[c] >= 0);
2850 assert(mcfdata->colcommodity[c] != basecommodity);
2853 assert(colisincident[c]);
2854 colisincident[c] =
FALSE;
2860 for( j = 0; j < collen; j++ )
2868 assert(0 <= colr && colr < nrows);
2871 if( rowprocessed[colr] )
2873 rowprocessed[colr] =
TRUE;
2876 rowcom = rowcommodity[colr];
2877 assert(rowcom != basecommodity);
2881 assert(rowcom == mcfdata->colcommodity[c]);
2882 assert((flowrowsigns[colr] & (LHSASSIGNED | RHSASSIGNED)) != 0);
2883 assert(mcfdata->rowarcid[colr] == -1);
2886 if( rownodeid[colr] >= 0 )
2891 nposuncap, nneguncap, colrows[j], &score, &invertcommodity) );
2894 if( score > bestscores[rowcom] )
2896 bestflowrows[rowcom] = colrows[j];
2897 bestscores[rowcom] = score;
2898 bestinverted[rowcom] = invertcommodity;
2902 assert(bestflowrows[basecommodity] ==
NULL);
2905 for( i = 0; i < ncommodities; i++ )
2909 if( bestflowrows[i] ==
NULL )
2913 assert(0 <= comr && comr < nrows);
2914 assert(rowcommodity[comr] == i);
2915 assert((flowrowsigns[comr] & (LHSASSIGNED | RHSASSIGNED)) != 0);
2916 assert(rownodeid[comr] == -1);
2917 assert(mcfdata->nnodes >= 1);
2919 SCIPdebugMessage(
" -> assigning row %d <%s> of commodity %d to node %d [invert:%u]\n",
2920 comr,
SCIProwGetName(rows[comr]), i, mcfdata->nnodes-1, bestinverted[i]);
2921 rownodeid[comr] = mcfdata->nnodes-1;
2924 if( bestinverted[i] )
2926 assert(commoditysigns[i] != +1);
2927 commoditysigns[i] = -1;
2931 assert(commoditysigns[i] != -1);
2932 commoditysigns[i] = +1;
2955 int* commoditysigns = mcfdata->commoditysigns;
2958 for( k = 0; k < mcfdata->ncommodities; k++ )
2960 if( commoditysigns[k] == 0 )
2961 commoditysigns[k] = +1;
2976 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2977 int* commoditysigns = mcfdata->commoditysigns;
2978 int* rowcommodity = mcfdata->rowcommodity;
2979 int* rownodeid = mcfdata->rownodeid;
2980 int* colsources = mcfdata->colsources;
2981 int* coltargets = mcfdata->coltargets;
2989 assert(sourcenode !=
NULL);
2990 assert(targetnode !=
NULL);
2991 assert(colsources !=
NULL);
2992 assert(coltargets !=
NULL);
2998 if( colsources[c] >= -1 )
3000 assert(coltargets[c] >= -1);
3001 *sourcenode = colsources[c];
3002 *targetnode = coltargets[c];
3013 for( i = 0; i < collen; i++ )
3020 if( rownodeid[r] >= 0 )
3027 k = rowcommodity[r];
3028 assert(0 <= v && v < mcfdata->nnodes);
3029 assert(0 <= k && k < mcfdata->ncommodities);
3030 assert((flowrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) != 0);
3034 if( (flowrowsigns[r] & LHSASSIGNED) != 0 )
3036 if( (flowrowsigns[r] &
INVERTED) != 0 )
3038 if( commoditysigns[k] == -1 )
3042 if( ( scale * colvals[i] ) > 0.0 )
3044 assert(*sourcenode == -1);
3046 if( *targetnode >= 0 )
3051 assert(*targetnode == -1);
3053 if( *sourcenode >= 0 )
3060 colsources[c] = *sourcenode;
3061 coltargets[c] = *targetnode;
3072 int* flowcands = mcfdata->flowcands;
3073 int nflowcands = mcfdata->nflowcands;
3075 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
3076 int* colcommodity = mcfdata->colcommodity;
3077 int* rowcommodity = mcfdata->rowcommodity;
3079 int* rownodeid = mcfdata->rownodeid;
3080 int* colarcid = mcfdata->colarcid;
3081 int nnodes = mcfdata->nnodes;
3082 int ncommodities = mcfdata->ncommodities;
3089 int* sortedflowcands;
3090 int* sortedflowcandnodeid;
3103 assert(mcfdata->nemptycommodities == 0);
3104 assert(ncommodities >= 0);
3108 if( ncommodities == 0 || nflowcands == 0 || nnodes == 0 )
3117 assert(rows !=
NULL);
3118 assert(cols !=
NULL || ncols == 0);
3129 for( n = 0; n < nflowcands; n++ )
3131 sortedflowcands[n] = flowcands[n];
3132 sortedflowcandnodeid[n] = rownodeid[flowcands[n]];
3136 SCIPsortIntInt(sortedflowcandnodeid, sortedflowcands, nflowcands);
3137 assert(sortedflowcandnodeid[0] <= 0);
3138 assert(sortedflowcandnodeid[nflowcands-1] == nnodes-1);
3141 for( v = 0; v < nnodes; v++ )
3157 for( n = 0; n < nflowcands; n++ )
3159 if( sortedflowcandnodeid[n] >= 0 )
3161 assert(0 <= sortedflowcands[n] && sortedflowcands[n] <
SCIPgetNLPRows(scip));
3162 assert(rowcommodity[sortedflowcands[n]] == -1);
3164 assert(n < nflowcands);
3165 assert(sortedflowcandnodeid[n] == 0);
3170 for( v = 0; n < nflowcands; v++ )
3175 assert(0 <= sortedflowcands[n] && sortedflowcands[n] <
SCIPgetNLPRows(scip));
3176 assert(rowcommodity[sortedflowcands[n]] >= 0);
3177 assert(rownodeid[sortedflowcands[n]] == sortedflowcandnodeid[n]);
3178 assert(sortedflowcandnodeid[n] == v);
3179 assert(nadjnodes == 0);
3180 assert(ninccols == 0);
3185 for( ; n < nflowcands && sortedflowcandnodeid[n] == v; n++ )
3192 r = sortedflowcands[n];
3193 assert((flowrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) != 0);
3194 assert(mcfdata->rowarcid[r] == -1);
3199 for( i = 0; i < rowlen; i++ )
3210 arcid = colarcid[c];
3211 assert(-2 <= arcid && arcid < mcfdata->narcs);
3212 assert(rowcommodity[r] == colcommodity[c]);
3222 else if( arcid == -1 )
3232 assert(-1 <= s && s < nnodes);
3233 assert(-1 <= t && t < nnodes);
3234 assert(s == v || t == v);
3245 if( s < 0 || t < 0 )
3253 assert(ninccols < ncols);
3254 inccols[ninccols] = c;
3270 if( sourcecount[u] + targetcount[u] == 1 )
3272 assert(nadjnodes < nnodes);
3273 adjnodes[nadjnodes] = u;
3281 for( l = 0; l < nadjnodes; l++ )
3286 assert(0 <= u && u < nnodes);
3287 assert(sourcecount[u] > 0 || targetcount[u] > 0);
3289 assert(ninccols >= 0);
3292 if( sourcecount[u] >= arcsthreshold )
3302 for( m = 0; m < ninccols; m++ )
3309 assert(0 <= c && c < ncols);
3311 assert(cols !=
NULL);
3313 assert(s == v || t == v);
3318 colarcid[c] = arcid;
3321 inccols[m] = inccols[ninccols-1];
3329 if( targetcount[u] >= arcsthreshold )
3339 for( m = 0; m < ninccols; m++ )
3346 assert(0 <= c && c < ncols);
3348 assert(cols !=
NULL);
3350 assert(s == v || t == v);
3354 assert(cols !=
NULL);
3356 colarcid[c] = arcid;
3359 inccols[m] = inccols[ninccols-1];
3368 for( l = 0; l < nadjnodes; l++ )
3376 for( l = 0; l < ninccols; l++ )
3378 assert(colarcid[inccols[l]] == -1);
3379 colarcid[inccols[l]] = -2;
3383 assert(n == nflowcands);
3384 assert(v == nnodes);
3388 for( n = 0; n < ncols; n++ )
3389 assert(colarcid[n] >= -1);
3400 MCFdebugMessage(
"network after finding uncapacitated arcs has %d nodes, %d arcs, and %d commodities\n",
3401 mcfdata->nnodes, mcfdata->narcs, mcfdata->ncommodities);
3413 int* flowcands = mcfdata->flowcands;
3414 int nflowcands = mcfdata->nflowcands;
3415 int* colcommodity = mcfdata->colcommodity;
3416 int* rowcommodity = mcfdata->rowcommodity;
3417 int* colarcid = mcfdata->colarcid;
3418 int* rowarcid = mcfdata->rowarcid;
3419 int* rownodeid = mcfdata->rownodeid;
3420 int ncommodities = mcfdata->ncommodities;
3421 int* commoditysigns = mcfdata->commoditysigns;
3422 int narcs = mcfdata->narcs;
3423 int nnodes = mcfdata->nnodes;
3424 SCIP_ROW** capacityrows = mcfdata->capacityrows;
3436 int nnodesthreshold;
3437 int newncommodities;
3443 MCFdebugMessage(
"network before cleanup has %d nodes, %d arcs, and %d commodities\n", nnodes, narcs, ncommodities);
3450 permsize = ncommodities;
3451 permsize =
MAX(permsize, narcs);
3452 permsize =
MAX(permsize, nnodes);
3462 assert(flowcands !=
NULL || nflowcands == 0);
3465 for( i = 0; i < nflowcands; i++ )
3469 assert(flowcands !=
NULL);
3471 assert(0 <= r && r < nrows);
3472 assert((rownodeid[r] >= 0) == (rowcommodity[r] >= 0));
3473 if( rowcommodity[r] >= 0 )
3475 assert(rowcommodity[r] < ncommodities);
3476 nnodespercom[rowcommodity[r]]++;
3480 assert(capacityrows !=
NULL || narcs == 0);
3483 for( a = 0; a < narcs; a++ )
3490 assert(capacityrows !=
NULL);
3492 assert(0 <= r && r < nrows);
3493 assert(rowarcid[r] == a);
3499 for( j = 0; j < rowlen; j++ )
3504 assert(0 <= c && c < ncols);
3505 if( colcommodity[c] >= 0 && colarcid[c] == a )
3507 assert(colcommodity[c] < ncommodities);
3508 arcisincom[colcommodity[c]] =
TRUE;
3513 for( k = 0; k < ncommodities; k++ )
3522 for( k = 0; k < ncommodities; k++ )
3523 maxnnodes =
MAX(maxnnodes, nnodespercom[k]);
3534 newncommodities = 0;
3535 for( k = 0; k < ncommodities; k++ )
3537 SCIPdebugMessage(
" -> commodity %d: %d nodes, %d arcs\n", k, nnodespercom[k], narcspercom[k]);
3540 if( nnodespercom[k] >= nnodesthreshold && narcspercom[k] >= 1 )
3542 assert(newncommodities <= k);
3543 perm[k] = newncommodities;
3544 commoditysigns[newncommodities] = commoditysigns[k];
3551 if( newncommodities < ncommodities )
3560 SCIPdebugMessage(
" -> discarding %d of %d commodities\n", ncommodities - newncommodities, ncommodities);
3568 for( c = 0; c < ncols; c++ )
3570 if( colcommodity[c] >= 0 )
3572 assert(-1 <= colarcid[c] && colarcid[c] < narcs);
3573 assert(colcommodity[c] < mcfdata->ncommodities);
3574 colcommodity[c] = perm[colcommodity[c]];
3575 assert(colcommodity[c] < newncommodities);
3576 if( colcommodity[c] == -1 )
3581 else if( colarcid[c] >= 0 )
3582 arcisused[colarcid[c]] =
TRUE;
3585 for( i = 0; i < nflowcands; i++ )
3589 assert(flowcands !=
NULL);
3591 assert(0 <= r && r < nrows);
3592 assert((rownodeid[r] >= 0) == (rowcommodity[r] >= 0));
3593 if( rowcommodity[r] >= 0 )
3595 assert(0 <= rownodeid[r] && rownodeid[r] < nnodes);
3596 assert(rowcommodity[r] < mcfdata->ncommodities);
3597 rowcommodity[r] = perm[rowcommodity[r]];
3598 assert(rowcommodity[r] < newncommodities);
3599 if( rowcommodity[r] == -1 )
3605 nodeisused[rownodeid[r]] =
TRUE;
3609 mcfdata->ncommodities = newncommodities;
3610 ncommodities = newncommodities;
3614 for( a = 0; a < narcs; a++ )
3618 assert(capacityrows !=
NULL);
3622 assert(newnarcs <= a);
3624 capacityrows[newnarcs] = capacityrows[a];
3633 assert(0 <= r && r < nrows);
3634 assert(rowarcid[r] == a);
3635 rowarcid[r] = perm[a];
3639 if( newnarcs < narcs )
3641 SCIPdebugMessage(
" -> discarding %d of %d arcs\n", narcs - newnarcs, narcs);
3643 for( c = 0; c < ncols; c++ )
3645 if( colarcid[c] >= 0 )
3647 colarcid[c] = perm[colarcid[c]];
3648 assert(colarcid[c] >= 0);
3651 mcfdata->narcs = newnarcs;
3655 for( a = 0; a < narcs; a++ )
3658 assert(capacityrows !=
NULL);
3660 assert(0 <= r && r < nrows);
3661 assert(rowarcid[r] == a);
3667 for( v = 0; v < nnodes; v++ )
3671 assert(newnnodes <= v);
3672 perm[v] = newnnodes;
3680 if( newnnodes < nnodes )
3682 SCIPdebugMessage(
" -> discarding %d of %d nodes\n", nnodes - newnnodes, nnodes);
3684 for( i = 0; i < nflowcands; i++ )
3688 assert(flowcands !=
NULL);
3690 assert(0 <= r && r < nrows);
3691 assert((rownodeid[r] >= 0) == (rowcommodity[r] >= 0));
3692 if( rowcommodity[r] >= 0 )
3694 assert(rowcommodity[r] < ncommodities);
3695 rownodeid[r] = perm[rownodeid[r]];
3696 assert(rownodeid[r] >= 0);
3699 mcfdata->nnodes = newnnodes;
3709 mcfdata->nemptycommodities = 0;
3717 MCFdebugMessage(
"network after cleanup has %d nodes, %d arcs, and %d commodities\n", nnodes, narcs, ncommodities);
3731 int* colarcid = mcfdata->colarcid;
3732 int* colcommodity = mcfdata->colcommodity;
3733 int narcs = mcfdata->narcs;
3734 int nnodes = mcfdata->nnodes;
3735 int ncommodities = mcfdata->ncommodities;
3736 SCIP_ROW** capacityrows = mcfdata->capacityrows;
3738 SCIP_Real maxinconsistencyratio = sepadata->maxinconsistencyratio;
3739 SCIP_Real maxarcinconsistencyratio = sepadata->maxarcinconsistencyratio;
3751 int *flowvarspercom;
3764 assert(effortlevel !=
NULL);
3778 arcsources = mcfdata->arcsources;
3779 arctargets = mcfdata->arctargets;
3780 colsources = mcfdata->colsources;
3781 coltargets = mcfdata->coltargets;
3782 firstoutarcs = mcfdata->firstoutarcs;
3783 firstinarcs = mcfdata->firstinarcs;
3784 nextoutarcs = mcfdata->nextoutarcs;
3785 nextinarcs = mcfdata->nextinarcs;
3787 mcfdata->arcarraysize = narcs;
3790 for( c = 0; c < ncols; c++ )
3797 for( v = 0; v < nnodes; v++ )
3799 firstoutarcs[v] = -1;
3800 firstinarcs[v] = -1;
3802 for( a = 0; a < narcs; a++ )
3804 nextoutarcs[a] = -1;
3818 mcfdata->ninconsistencies = 0.0;
3819 maxninconsistencies = maxinconsistencyratio * (
SCIP_Real)narcs;
3822 for( a = 0; a < narcs; a++ )
3843 assert((mcfdata->capacityrowsigns[r] & (LHSASSIGNED |
RHSASSIGNED)) != 0);
3844 assert(mcfdata->rowarcid[r] == a);
3847 for( i = 0; i < nnodes; i++ )
3849 assert(sourcenodecnt[i] == 0);
3850 assert(targetnodecnt[i] == 0);
3861 for( i = 0; i < rowlen; i++ )
3865 if( colarcid[c] >= 0 )
3867 int k = colcommodity[c];
3868 assert (0 <= k && k < ncommodities);
3869 flowvarspercom[k]++;
3870 if( !comtouched[k] )
3873 comtouched[k] =
TRUE;
3879 if( ntouchedcoms == 0 )
3881 capacityrows[a] =
NULL;
3889 totalsourcecnt = 0.0;
3890 totaltargetcnt = 0.0;
3892 for( i = 0; i < rowlen; i++ )
3896 if( colarcid[c] >= 0 )
3898 int k = colcommodity[c];
3903 assert (0 <= k && k < ncommodities);
3904 assert (comtouched[k]);
3905 assert (flowvarspercom[k] >= 1);
3911 weight = 1.0/flowvarspercom[k];
3914 if( sourcenodecnt[sourcev] == 0.0 && targetnodecnt[sourcev] == 0.0 )
3916 touchednodes[ntouchednodes] = sourcev;
3919 sourcenodecnt[sourcev] += weight;
3920 totalsourcecnt += weight;
3924 if( sourcenodecnt[targetv] == 0.0 && targetnodecnt[targetv] == 0.0 )
3926 touchednodes[ntouchednodes] = targetv;
3929 targetnodecnt[targetv] += weight;
3930 totaltargetcnt += weight;
3932 if( sourcev >= 0 || targetv >= 0 )
3933 totalnodecnt += weight;
3940 bestsourcecnt = 0.0;
3941 besttargetcnt = 0.0;
3942 for( i = 0; i < ntouchednodes; i++ )
3944 v = touchednodes[i];
3945 assert(0 <= v && v < nnodes);
3950 if( sourcenodecnt[v] >= targetnodecnt[v] )
3952 if( sourcenodecnt[v] > bestsourcecnt )
3955 bestsourcecnt = sourcenodecnt[v];
3960 if( targetnodecnt[v] > besttargetcnt )
3963 besttargetcnt = targetnodecnt[v];
3969 SCIP_Real nodecnt = sourcenodecnt[v] + targetnodecnt[v];
3973 if( nodecnt > bestsourcecnt )
3975 besttargetv = bestsourcev;
3976 besttargetcnt = bestsourcecnt;
3978 bestsourcecnt = nodecnt;
3980 else if( nodecnt > besttargetcnt )
3983 besttargetcnt = nodecnt;
3988 sourcenodecnt[v] = 0;
3989 targetnodecnt[v] = 0;
3995 totalsourcecnt = totalnodecnt;
3996 totaltargetcnt = totalnodecnt;
3998 assert(
SCIPisGE(scip,totalsourcecnt,bestsourcecnt));
3999 assert(
SCIPisGE(scip,totaltargetcnt,besttargetcnt));
4000 nsourceinconsistencies = (totalsourcecnt - bestsourcecnt)/ntouchedcoms;
4001 ntargetinconsistencies = (totaltargetcnt - besttargetcnt)/ntouchedcoms;
4004 if( nsourceinconsistencies > maxarcinconsistencyratio )
4010 if( ntargetinconsistencies > maxarcinconsistencyratio )
4017 assert(bestsourcev == -1 || bestsourcev != besttargetv);
4018 arcsources[a] = bestsourcev;
4019 arctargets[a] = besttargetv;
4020 SCIPdebugMessage(
"arc %d: %d -> %d (len=%d, sourcecnt=%g/%g, targetcnt=%g/%g, %g/%g inconsistencies)\n",
4021 a, bestsourcev, besttargetv, rowlen,
4022 bestsourcecnt, totalsourcecnt, besttargetcnt, totaltargetcnt,
4023 nsourceinconsistencies, ntargetinconsistencies);
4026 if( bestsourcev != -1 )
4028 nextoutarcs[a] = firstoutarcs[bestsourcev];
4029 firstoutarcs[bestsourcev] = a;
4031 if( besttargetv != -1 )
4033 nextinarcs[a] = firstinarcs[besttargetv];
4034 firstinarcs[besttargetv] = a;
4038 mcfdata->ninconsistencies += 0.5*(nsourceinconsistencies + ntargetinconsistencies);
4040 if( mcfdata->ninconsistencies > maxninconsistencies )
4042 MCFdebugMessage(
" -> reached maximal number of inconsistencies: %g > %g\n",
4043 mcfdata->ninconsistencies, maxninconsistencies);
4049 if( mcfdata->ninconsistencies <= maxninconsistencies && narcs > 0 && ncommodities > 0 )
4054 MCFdebugMessage(
"extracted network has %g inconsistencies (ratio %g) -> separating with effort %d\n",
4055 mcfdata->ninconsistencies, mcfdata->ninconsistencies/(
SCIP_Real)narcs, *effortlevel);
4084 int* arcsources = mcfdata->arcsources;
4085 int* arctargets = mcfdata->arctargets;
4086 int* firstoutarcs = mcfdata->firstoutarcs;
4087 int* firstinarcs = mcfdata->firstinarcs;
4088 int* nextoutarcs = mcfdata->nextoutarcs;
4089 int* nextinarcs = mcfdata->nextinarcs;
4090 int nnodes = mcfdata->nnodes;
4095 assert(nodevisited !=
NULL);
4096 assert(0 <= startv && startv < nnodes);
4097 assert(nodevisited[startv] ==
UNKNOWN);
4098 assert(compnodes !=
NULL);
4099 assert(ncompnodes !=
NULL);
4100 assert(comparcs !=
NULL);
4101 assert(ncomparcs !=
NULL);
4110 stacknodes[0] = startv;
4112 nodevisited[startv] =
ONSTACK;
4115 while( nstacknodes > 0 )
4120 assert(firstoutarcs !=
NULL);
4121 assert(firstinarcs !=
NULL);
4122 assert(nextoutarcs !=
NULL);
4123 assert(nextinarcs !=
NULL);
4126 v = stacknodes[nstacknodes-1];
4128 assert(0 <= v && v < nnodes);
4129 assert(nodevisited[v] ==
ONSTACK);
4133 assert(*ncompnodes < nnodes);
4134 compnodes[*ncompnodes] = v;
4138 for( a = firstoutarcs[v]; a != -1; a = nextoutarcs[a] )
4142 assert(0 <= a && a < mcfdata->narcs);
4143 assert(arctargets !=
NULL);
4145 targetv = arctargets[a];
4148 if( targetv != -1 && nodevisited[targetv] ==
VISITED )
4152 assert(*ncomparcs < mcfdata->narcs);
4153 comparcs[*ncomparcs] = a;
4157 if( targetv != -1 && nodevisited[targetv] ==
UNKNOWN )
4159 assert(nstacknodes < nnodes);
4160 stacknodes[nstacknodes] = targetv;
4162 nodevisited[targetv] =
ONSTACK;
4167 for( a = firstinarcs[v]; a != -1; a = nextinarcs[a] )
4171 assert(0 <= a && a < mcfdata->narcs);
4172 assert(arcsources !=
NULL);
4174 sourcev = arcsources[a];
4177 if( sourcev != -1 && nodevisited[sourcev] ==
VISITED )
4181 assert(*ncomparcs < mcfdata->narcs);
4182 comparcs[*ncomparcs] = a;
4186 if( sourcev != -1 && nodevisited[sourcev] ==
UNKNOWN )
4188 assert(nstacknodes < nnodes);
4189 stacknodes[nstacknodes] = sourcev;
4191 nodevisited[sourcev] =
ONSTACK;
4222 int mcfnetworkssize;
4224 assert(mcfnetworks !=
NULL);
4225 assert(nmcfnetworks !=
NULL);
4226 assert(effortlevel !=
NULL);
4230 *mcfnetworks =
NULL;
4232 mcfnetworkssize = 0;
4263 mcfdata.flowrowsigns =
NULL;
4264 mcfdata.flowrowscalars =
NULL;
4265 mcfdata.flowrowscores =
NULL;
4266 mcfdata.capacityrowsigns =
NULL;
4267 mcfdata.capacityrowscores =
NULL;
4268 mcfdata.flowcands =
NULL;
4269 mcfdata.nflowcands = 0;
4270 mcfdata.capacitycands =
NULL;
4271 mcfdata.ncapacitycands = 0;
4272 mcfdata.plusflow =
NULL;
4273 mcfdata.minusflow =
NULL;
4274 mcfdata.ncommodities = 0;
4275 mcfdata.nemptycommodities = 0;
4276 mcfdata.commoditysigns =
NULL;
4277 mcfdata.commoditysignssize = 0;
4278 mcfdata.colcommodity =
NULL;
4279 mcfdata.rowcommodity =
NULL;
4280 mcfdata.colarcid =
NULL;
4281 mcfdata.rowarcid =
NULL;
4282 mcfdata.rownodeid =
NULL;
4283 mcfdata.arcarraysize = 0;
4284 mcfdata.arcsources =
NULL;
4285 mcfdata.arctargets =
NULL;
4286 mcfdata.colsources =
NULL;
4287 mcfdata.coltargets =
NULL;
4288 mcfdata.firstoutarcs =
NULL;
4289 mcfdata.firstinarcs =
NULL;
4290 mcfdata.nextoutarcs =
NULL;
4291 mcfdata.nextinarcs =
NULL;
4292 mcfdata.newcols =
NULL;
4293 mcfdata.nnewcols = 0;
4296 mcfdata.ninconsistencies = 0.0;
4297 mcfdata.capacityrows =
NULL;
4298 mcfdata.capacityrowssize = 0;
4299 mcfdata.colisincident =
NULL;
4300 mcfdata.zeroarcarray =
NULL;
4301 mcfdata.modeltype = modeltype;
4307 assert(mcfdata.flowrowsigns !=
NULL);
4308 assert(mcfdata.flowrowscalars !=
NULL);
4309 assert(mcfdata.flowrowscores !=
NULL);
4310 assert(mcfdata.flowcands !=
NULL);
4312 if( mcfdata.nflowcands == 0 )
4319 assert(mcfdata.plusflow !=
NULL);
4320 assert(mcfdata.minusflow !=
NULL);
4321 assert(mcfdata.colcommodity !=
NULL);
4322 assert(mcfdata.rowcommodity !=
NULL);
4323 assert(mcfdata.newcols !=
NULL);
4329 printCommodities(scip, &mcfdata);
4336 assert(mcfdata.capacityrowsigns !=
NULL);
4337 assert(mcfdata.capacityrowscores !=
NULL);
4338 assert(mcfdata.capacitycands !=
NULL);
4340 if( mcfdata.ncapacitycands == 0 )
4348 assert(mcfdata.colarcid !=
NULL);
4349 assert(mcfdata.rowarcid !=
NULL);
4353 assert(mcfdata.rownodeid !=
NULL);
4354 assert(mcfdata.colisincident !=
NULL);
4355 assert(mcfdata.zeroarcarray !=
NULL);
4366 assert(mcfdata.arcsources !=
NULL);
4367 assert(mcfdata.arctargets !=
NULL);
4368 assert(mcfdata.colsources !=
NULL);
4369 assert(mcfdata.coltargets !=
NULL);
4370 assert(mcfdata.firstoutarcs !=
NULL);
4371 assert(mcfdata.firstinarcs !=
NULL);
4372 assert(mcfdata.nextoutarcs !=
NULL);
4373 assert(mcfdata.nextinarcs !=
NULL);
4389 printCommodities(scip, &mcfdata);
4402 for( v = 0; v < mcfdata.nnodes; v++ )
4406 for( v = 0; v < mcfdata.nnodes; v++ )
4413 if( nodevisited[v] ==
VISITED )
4418 assert(ncompnodes >= 1);
4419 assert(compnodes[0] == v);
4420 assert(nodevisited[v] ==
VISITED);
4423 if( ncompnodes >= minnodes && ncomparcs >=
MINARCS )
4430 assert(*nmcfnetworks <= mcfnetworkssize);
4431 if( *nmcfnetworks == mcfnetworkssize )
4433 mcfnetworkssize =
MAX(2*mcfnetworkssize, *nmcfnetworks+1);
4436 assert(*nmcfnetworks < mcfnetworkssize);
4442 SCIP_CALL(
mcfnetworkFill(scip, mcfnetwork, &mcfdata, compnodeid, compnodes, ncompnodes, comparcs, ncomparcs) );
4445 for( i = *nmcfnetworks; i > 0 && mcfnetwork->
nnodes > (*mcfnetworks)[i-1]->nnodes; i-- )
4446 (*mcfnetworks)[i] = (*mcfnetworks)[i-1];
4447 (*mcfnetworks)[i] = mcfnetwork;
4452 minnodes =
MAX(minnodes, (*mcfnetworks)[*nmcfnetworks-1]->nnodes);
4457 SCIPdebugMessage(
" -> discarded network with %d nodes and %d arcs due to maxnetworks (minnodes=%d)\n",
4458 (*mcfnetworks)[*nmcfnetworks-1]->nnodes, (*mcfnetworks)[*nmcfnetworks-1]->narcs, minnodes);
4466 SCIPdebugMessage(
" -> discarded component with %d nodes and %d arcs\n", ncompnodes, ncomparcs);
4509 #ifdef COUNTNETWORKVARIABLETYPES
4531 int nintflowvars = 0;
4532 int nbinflowvars = 0;
4533 int ncontflowvars = 0;
4535 int nintcapvars = 0;
4536 int nbincapvars = 0;
4537 int ncontcapvars = 0;
4544 for(c=0; c < ncols; c++)
4545 colvisited[c]=
FALSE;
4550 for(m=0; m < nmcfnetworks; m++)
4554 int narcs = mcfnetwork->
narcs;
4555 int nnodes = mcfnetwork->
nnodes;
4562 for(c=0; c < ncols; c++)
4566 if(colcommodity[c] >= 0 && ! colvisited[c])
4571 colvisited[c] =
TRUE;
4594 for( a = 0; a < narcs; a++ )
4597 row = arccapacityrows[a];
4609 for( i = 0; i < rowlen; i++ )
4614 if(colcommodity[c] == -1 && ! colvisited[c] )
4617 colvisited[c] =
TRUE;
4642 for( k = 0; k < ncommodities; k++ )
4644 for( v = 0; v < nnodes; v++ )
4647 row = nodeflowrows[v][k];
4657 MCFdebugMessage(
" nof flowvars: %5d of which [ %d , %d , %d ] are continuous, integer, binary\n",
4658 nflowvars, ncontflowvars, nintflowvars, nbinflowvars);
4659 MCFdebugMessage(
" nof capvars: %5d of which [ %d , %d , %d ] are continuous, integer, binary\n",
4660 ncapvars, ncontcapvars, nintcapvars, nbincapvars);
4680 int* representatives,
4687 for( v = 0; v < nelems; v++ )
4688 representatives[v] = v;
4694 int* representatives,
4698 assert(representatives !=
NULL);
4700 while( v != representatives[v] )
4702 representatives[v] = representatives[representatives[v]];
4703 v = representatives[v];
4712 int* representatives,
4717 assert(rep1 != rep2);
4718 assert(representatives[rep1] == rep1);
4719 assert(representatives[rep2] == rep2);
4725 representatives[rep2] = rep1;
4727 representatives[rep1] = rep2;
4743 if( nodepair1->weight > nodepair2->weight )
4745 else if( nodepair1->weight < nodepair2->weight )
4780 assert(mcfnetwork !=
NULL);
4786 assert(nodepair1 !=
NULL);
4787 assert(nodepair2 !=
NULL);
4789 source1 = nodepair1->node1;
4790 source2 = nodepair2->node1;
4791 target1 = nodepair1->node2;
4792 target2 = nodepair2->node2;
4794 assert(source1 >=0 && source1 < mcfnetwork->nnodes);
4795 assert(source2 >=0 && source2 < mcfnetwork->nnodes);
4796 assert(target1 >=0 && target1 < mcfnetwork->nnodes);
4797 assert(target2 >=0 && target2 < mcfnetwork->nnodes);
4798 assert(source1 <= target1);
4799 assert(source2 <= target2);
4801 return (source1 == source2 && target1 == target2);
4815 unsigned int hashval;
4819 assert(mcfnetwork !=
NULL);
4823 assert( nodepair !=
NULL);
4825 source = nodepair->node1;
4826 target = nodepair->node2;
4828 assert(source >=0 && source < mcfnetwork->nnodes);
4829 assert(target >=0 && target < mcfnetwork->nnodes);
4830 assert(source <= target);
4832 hashval = (source << 16) + target;
4855 #ifdef BETTERWEIGHTFORDEMANDNODES
4876 assert(mcfnetwork !=
NULL);
4878 #ifdef BETTERWEIGHTFORDEMANDNODES
4888 assert(nodepairqueue !=
NULL);
4898 hashGetKeyNodepairs, hashKeyEqNodepairs, hashKeyValNodepairs, (
void*) mcfnetwork) );
4905 for( a = 0; a < mcfnetwork->
narcs; a++ )
4927 assert(nodepair.node1 < mcfnetwork->
nnodes);
4928 assert(nodepair.node2 < mcfnetwork->
nnodes);
4929 if( nodepair.node1 == -1 || nodepair.node2 == -1 )
4933 if( capacityrow !=
NULL )
4949 slack =
MAX(slack, 0.0);
4953 assert(scale > 0.0);
4963 for( i = 0; i < rowlen; i++ )
4970 if(colcommodity[c] >= 0)
4982 SCIPdebugMessage(
"cap arc -- slack:%g -- dual:%g -- flow:%g -- cap:%g \n", scale * slack, dualsol/scale, totalflow * scale, totalcap * scale);
4984 SCIPdebugMessage(
"cap arc -- slack:%g -- dual:%g1\n", scale * slack, dualsol/scale);
4988 nodepair.weight = scale * slack - ABS(dualsol)/scale;
4989 #ifdef USEFLOWFORTIEBREAKING
4992 nodepair.weight += totalflow * scale;
4993 nodepair.weight =
MIN( nodepair.weight, -0.0001);
4996 #ifdef USECAPACITYFORTIEBREAKING
4999 nodepair.weight += totalcap * scale;
5000 nodepair.weight =
MIN( nodepair.weight, -0.0001);
5016 if( nodepairptr !=
NULL )
5019 SCIPdebugMessage(
"nodepair known [%d,%d] -- old weight:%g -- new weight:%g\n", nodepair.node1,nodepair.node2,nodepairptr->weight,
5020 MIN(nodepair.weight, nodepairptr->weight));
5021 nodepairptr->weight =
MIN(nodepair.weight, nodepairptr->weight);
5026 nodepairs = (*nodepairqueue)->nodepairs;
5028 assert(nnodepairs < mcfnetwork->narcs);
5029 nodepairs[nnodepairs] = nodepair;
5032 SCIPdebugMessage(
"new nodepair [%d,%d]-- weight:%g\n", nodepair.node1, nodepair.node2, nodepair.weight);
5043 #ifdef BETTERWEIGHTFORDEMANDNODES
5051 nodepairs = (*nodepairqueue)->nodepairs;
5052 for( n = 0; n < nnodepairs; n++ )
5056 maxweight =
MAX(maxweight, nodepairs[n].weight);
5058 minweight =
MIN(minweight, nodepairs[n].weight);
5068 for( n = 0; n < nnodepairs; n++ )
5070 int node1 = nodepairs[n].node1;
5071 int node2 = nodepairs[n].node2;
5073 #ifdef BETTERWEIGHTFORDEMANDNODES
5080 SCIPdebugMessage(
"nodepair [%d,%d] weight %g\n", node1,node2,nodepairs[n].weight);
5086 for( k = 0; k < ncommodities; k++ )
5088 if( nodeflowrows[node1][k] ==
NULL )
5091 if( nodeflowscales[node1][k] > 0.0 )
5106 for( k = 0; k < ncommodities; k++ )
5108 if( nodeflowrows[node2][k] ==
NULL )
5111 if( nodeflowscales[node2][k] > 0.0 )
5133 if( !hasdemand1 || !hasdemand2 )
5134 nodepairs[n].weight += maxweight;
5140 if( hasdemand1 && hasdemand2)
5141 nodepairs[n].weight += minweight;
5144 SCIPdebugMessage(
"nodepair [%d,%d] weight %g\n", node1,node2,nodepairs[n].weight);
5161 assert(nodepairqueue !=
NULL);
5162 assert(*nodepairqueue !=
NULL);
5176 assert(nodepairqueue !=
NULL);
5189 assert(nodepairqueue !=
NULL);
5237 assert(mcfnetwork !=
NULL);
5238 assert(nodepartition !=
NULL);
5239 assert(mcfnetwork->
nnodes >= 1);
5247 (*nodepartition)->nclusters = 0;
5256 nclustersleft = mcfnetwork->
nnodes;
5268 assert(nodepair !=
NULL);
5269 node1 = nodepair->node1;
5270 node2 = nodepair->node2;
5271 weight = nodepair->weight;
5273 assert(node1 >= 0 && node1 < mcfnetwork->nnodes);
5274 assert(node2 >= 0 && node2 < mcfnetwork->nnodes);
5279 assert(0 <= node1rep && node1rep < mcfnetwork->nnodes);
5280 assert(0 <= node2rep && node2rep < mcfnetwork->nnodes);
5283 if( node1rep == node2rep )
5287 SCIPdebugMessage(
"shrinking nodepair (%d,%d) with weight %g: join representatives %d and %d\n",
5288 node1, node2, weight, node1rep, node2rep);
5294 assert((*nodepartition)->representatives[0] == 0);
5299 if( nclustersleft > nclusters )
5301 for( v = 1; v < mcfnetwork->
nnodes && nclustersleft > nclusters; v++ )
5313 assert(nclustersleft <= nclusters);
5318 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5328 c = (*nodepartition)->nclusters;
5329 (*nodepartition)->nclusters++;
5332 c = (*nodepartition)->nodeclusters[rep];
5333 assert(0 <= c && c < nclusters);
5336 (*nodepartition)->nodeclusters[v] = c;
5342 for( c = 0; c < (*nodepartition)->nclusters; c++ )
5344 (*nodepartition)->clusterbegin[c] = pos;
5345 pos += clustersize[c];
5347 assert(pos == mcfnetwork->
nnodes);
5348 (*nodepartition)->clusterbegin[(*nodepartition)->nclusters] = mcfnetwork->
nnodes;
5352 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5354 c = (*nodepartition)->nodeclusters[v];
5355 assert(0 <= c && c < (*nodepartition)->nclusters);
5356 pos = (*nodepartition)->clusterbegin[c] + clustersize[c];
5357 assert(pos < (*nodepartition)->clusterbegin[c+1]);
5358 (*nodepartition)->clusternodes[pos] = v;
5378 assert(nodepartition !=
NULL);
5379 assert(*nodepartition !=
NULL);
5392 unsigned int partition,
5403 if( nodepartition ==
NULL )
5404 return ((v == (
int)partition) == !inverted);
5408 unsigned int clusterbit;
5410 cluster = nodepartition->nodeclusters[v];
5411 assert(0 <= cluster && cluster < nodepartition->nclusters);
5412 clusterbit = (1 << cluster);
5414 return (((partition & clusterbit) != 0) == !inverted);
5424 unsigned int partition
5427 const int* nodeclusters = nodepartition->nodeclusters;
5428 const int* arcsources = mcfnetwork->
arcsources;
5429 const int* arctargets = mcfnetwork->
arctargets;
5430 int narcs = mcfnetwork->
narcs;
5437 assert(nodepartition !=
NULL);
5438 nclusters = nodepartition->nclusters;
5445 ncomponents = nclusters;
5446 assert(ncomponents >= 2);
5449 for( a = 0; a < narcs; a++ )
5451 int s = arcsources[a];
5452 int t = arctargets[a];
5455 if( s == -1 || t == -1 )
5466 assert(0 <= s && s < mcfnetwork->nnodes);
5467 assert(0 <= t && t < mcfnetwork->nnodes);
5470 cs = nodeclusters[s];
5471 ct = nodeclusters[t];
5472 assert(0 <= cs && cs < nclusters);
5473 assert(0 <= ct && ct < nclusters);
5482 if( repcs == repct )
5489 if( ncomponents <= 2 )
5499 assert(ncomponents >= 2);
5501 return (ncomponents == 2);
5506 void nodepartitionPrint(
5512 for( c = 0; c < nodepartition->nclusters; c++ )
5517 for( i = nodepartition->clusterbegin[c]; i < nodepartition->clusterbegin[c+1]; i++ )
5532 unsigned int partition
5541 if( nodepartition ==
NULL )
5546 file = fopen(filename,
"w");
5554 fprintf(file,
"graph\n");
5555 fprintf(file,
"[\n");
5556 fprintf(file,
" hierarchic 1\n");
5557 fprintf(file,
" label \"\"\n");
5558 fprintf(file,
" directed 1\n");
5561 for( v = 0; v < mcfnetwork->
nnodes; v++ )
5572 fprintf(file,
" node\n");
5573 fprintf(file,
" [\n");
5574 fprintf(file,
" id %d\n", v);
5575 fprintf(file,
" label \"%s\"\n", label);
5576 fprintf(file,
" graphics\n");
5577 fprintf(file,
" [\n");
5578 fprintf(file,
" w 30.0\n");
5579 fprintf(file,
" h 30.0\n");
5580 fprintf(file,
" type \"ellipse\"\n");
5582 fprintf(file,
" fill \"#FF0000\"\n");
5584 fprintf(file,
" fill \"#00FF00\"\n");
5585 fprintf(file,
" outline \"#000000\"\n");
5586 fprintf(file,
" ]\n");
5587 fprintf(file,
" LabelGraphics\n");
5588 fprintf(file,
" [\n");
5589 fprintf(file,
" text \"%s\"\n", label);
5590 fprintf(file,
" fontSize 13\n");
5591 fprintf(file,
" fontName \"Dialog\"\n");
5592 fprintf(file,
" anchor \"c\"\n");
5593 fprintf(file,
" ]\n");
5595 fprintf(file,
" gid %d\n", mcfnetwork->
nnodes+1);
5597 fprintf(file,
" gid %d\n", mcfnetwork->
nnodes+2);
5598 fprintf(file,
" ]\n");
5602 fprintf(file,
" node\n");
5603 fprintf(file,
" [\n");
5604 fprintf(file,
" id %d\n", mcfnetwork->
nnodes);
5605 fprintf(file,
" label \"?\"\n");
5606 fprintf(file,
" graphics\n");
5607 fprintf(file,
" [\n");
5608 fprintf(file,
" w 30.0\n");
5609 fprintf(file,
" h 30.0\n");
5610 fprintf(file,
" type \"ellipse\"\n");
5611 fprintf(file,
" fill \"#FFFFFF\"\n");
5612 fprintf(file,
" outline \"#000000\"\n");
5613 fprintf(file,
" ]\n");
5614 fprintf(file,
" LabelGraphics\n");
5615 fprintf(file,
" [\n");
5616 fprintf(file,
" text \"?\"\n");
5617 fprintf(file,
" fontSize 13\n");
5618 fprintf(file,
" fontName \"Dialog\"\n");
5619 fprintf(file,
" anchor \"c\"\n");
5620 fprintf(file,
" ]\n");
5621 fprintf(file,
" ]\n");
5624 fprintf(file,
" node\n");
5625 fprintf(file,
" [\n");
5626 fprintf(file,
" id %d\n", mcfnetwork->
nnodes+1);
5627 fprintf(file,
" label \"Partition S\"\n");
5628 fprintf(file,
" graphics\n");
5629 fprintf(file,
" [\n");
5630 fprintf(file,
" type \"roundrectangle\"\n");
5631 fprintf(file,
" fill \"#CAECFF84\"\n");
5632 fprintf(file,
" outline \"#666699\"\n");
5633 fprintf(file,
" outlineStyle \"dotted\"\n");
5634 fprintf(file,
" topBorderInset 0\n");
5635 fprintf(file,
" bottomBorderInset 0\n");
5636 fprintf(file,
" leftBorderInset 0\n");
5637 fprintf(file,
" rightBorderInset 0\n");
5638 fprintf(file,
" ]\n");
5639 fprintf(file,
" LabelGraphics\n");
5640 fprintf(file,
" [\n");
5641 fprintf(file,
" text \"Partition S\"\n");
5642 fprintf(file,
" fill \"#99CCFF\"\n");
5643 fprintf(file,
" fontSize 15\n");
5644 fprintf(file,
" fontName \"Dialog\"\n");
5645 fprintf(file,
" alignment \"right\"\n");
5646 fprintf(file,
" autoSizePolicy \"node_width\"\n");
5647 fprintf(file,
" anchor \"t\"\n");
5648 fprintf(file,
" borderDistance 0.0\n");
5649 fprintf(file,
" ]\n");
5650 fprintf(file,
" isGroup 1\n");
5651 fprintf(file,
" ]\n");
5654 fprintf(file,
" node\n");
5655 fprintf(file,
" [\n");
5656 fprintf(file,
" id %d\n", mcfnetwork->
nnodes+2);
5657 fprintf(file,
" label \"Partition T\"\n");
5658 fprintf(file,
" graphics\n");
5659 fprintf(file,
" [\n");
5660 fprintf(file,
" type \"roundrectangle\"\n");
5661 fprintf(file,
" fill \"#CAECFF84\"\n");
5662 fprintf(file,
" outline \"#666699\"\n");
5663 fprintf(file,
" outlineStyle \"dotted\"\n");
5664 fprintf(file,
" topBorderInset 0\n");
5665 fprintf(file,
" bottomBorderInset 0\n");
5666 fprintf(file,
" leftBorderInset 0\n");
5667 fprintf(file,
" rightBorderInset 0\n");
5668 fprintf(file,
" ]\n");
5669 fprintf(file,
" LabelGraphics\n");
5670 fprintf(file,
" [\n");
5671 fprintf(file,
" text \"Partition T\"\n");
5672 fprintf(file,
" fill \"#99CCFF\"\n");
5673 fprintf(file,
" fontSize 15\n");
5674 fprintf(file,
" fontName \"Dialog\"\n");
5675 fprintf(file,
" alignment \"right\"\n");
5676 fprintf(file,
" autoSizePolicy \"node_width\"\n");
5677 fprintf(file,
" anchor \"t\"\n");
5678 fprintf(file,
" borderDistance 0.0\n");
5679 fprintf(file,
" ]\n");
5680 fprintf(file,
" isGroup 1\n");
5681 fprintf(file,
" ]\n");
5684 for( a = 0; a < mcfnetwork->
narcs; a++ )
5696 hasfractional =
FALSE;
5707 for( i = 0; i < rowlen; i++ )
5714 hasfractional =
TRUE;
5722 fprintf(file,
" edge\n");
5723 fprintf(file,
" [\n");
5726 fprintf(file,
" label \"%s\"\n", label);
5727 fprintf(file,
" graphics\n");
5728 fprintf(file,
" [\n");
5730 fprintf(file,
" fill \"#000000\"\n");
5732 fprintf(file,
" fill \"#FF0000\"\n");
5734 fprintf(file,
" style \"dashed\"\n");
5735 fprintf(file,
" width 1\n");
5736 fprintf(file,
" targetArrow \"standard\"\n");
5737 fprintf(file,
" ]\n");
5738 fprintf(file,
" LabelGraphics\n");
5739 fprintf(file,
" [\n");
5740 fprintf(file,
" text \"%s\"\n", label);
5741 fprintf(file,
" ]\n");
5742 fprintf(file,
" ]\n");
5746 fprintf(file,
"]\n");
5781 assert(scip !=
NULL);
5782 assert(sepadata !=
NULL);
5783 assert(cutcoefs !=
NULL);
5784 assert(ncuts !=
NULL);
5785 assert(cutoff !=
NULL);
5789 assert(nvars == 0 || vars !=
NULL);
5794 if( sepadata->separateknapsack )
5804 cutislocal,
FALSE, sepadata->dynamiccuts) );
5808 for( v = 0; v < nvars; v++ )
5815 if( sepadata->separateknapsack )
5817 assert(cutvars !=
NULL && cutvals !=
NULL);
5818 cutvars[ncutvars] = vars[v];
5819 cutvals[ncutvars] = cutcoefs[v];
5832 SCIPdebugMessage(
" -> found MCF cut <%s>: rhs=%f, act=%f eff=%f rank=%d\n",
5837 if( !(*cutoff) && !cutislocal )
5847 if( !(*cutoff) && sepadata->separateknapsack)
5850 SCIP_CALL(
SCIPseparateRelaxedKnapsack(scip,
NULL, sepa, ncutvars, cutvars, cutvals, +1.0, cutrhs, sol, cutoff, ncuts) );
5883 int nnodes = mcfnetwork->
nnodes;
5884 int narcs = mcfnetwork->
narcs;
5900 unsigned int partition;
5901 unsigned int allpartitions;
5902 unsigned int startpartition;
5916 maxsepacuts = sepadata->maxsepacutsroot;
5918 maxsepacuts = sepadata->maxsepacuts;
5919 if( maxsepacuts < 0 )
5920 maxsepacuts = INT_MAX;
5925 maxtestdelta = sepadata->maxtestdelta;
5926 if( maxtestdelta <= 0 )
5927 maxtestdelta = INT_MAX;
5960 if( nodepartition ==
NULL )
5964 allpartitions = (
unsigned int) nnodes;
5965 SCIPdebugMessage(
"maxtestdelta: %d, maxsepacuts: %d, nnodes: %d \n", maxtestdelta, maxsepacuts, nnodes);
5972 int nclusters = nodepartition->nclusters;
5974 assert((
unsigned int)nclusters <= 8*
sizeof(
unsigned int));
5975 SCIPdebugMessage(
"maxtestdelta: %d, maxsepacuts: %d, nclusters: %d \n", maxtestdelta, maxsepacuts, nclusters);
5982 allpartitions = (1 << (nclusters-1));
5986 for( partition = startpartition; partition <= allpartitions-1 && !
SCIPisStopped(scip) && *ncuts < maxsepacuts && !*cutoff; partition++ )
6000 if( sepadata->checkcutshoreconnectivity )
6007 SCIPdebugMessage(
"generating cluster cuts for partition 0x%x \n", partition );
6008 SCIPdebugMessage(
" -> either shore S or shore T is not connected - skip partition.\n");
6013 for( inverted =
FALSE; inverted <= useinverted && !*cutoff; inverted++ )
6016 if( nodepartition ==
NULL )
6018 SCIPdebugMessage(
"generating single-node cuts for node %u (inverted: %u)\n", partition, inverted);
6022 SCIPdebugMessage(
"generating cluster cuts for partition 0x%x (inverted: %u)\n", partition, inverted);
6026 SCIP_CALL( outputGraph(scip, mcfnetwork, nodepartition, inverted, partition) );
6044 for( v = 0; v < nnodes; v++ )
6054 for( k = 0; k < ncommodities; k++ )
6058 if( nodeflowrows[v][k] ==
NULL )
6061 if( nodeflowscales[v][k] > 0.0 )
6065 if( nodeflowinverted[v][k] )
6068 comcutdemands[k] += rhs * nodeflowscales[v][k];
6071 assert (1 <= nnodesinS && nnodesinS <= nnodes-1);
6076 if( sepadata->separatesinglenodecuts && nodepartition !=
NULL && (nnodesinS == 1 || nnodesinS == nnodes-1) )
6078 SCIPdebugMessage(
" -> shore S or T has only one node - skip partition.\n");
6085 for( k = 0; k < ncommodities; k++ )
6088 SCIPdebugMessage(
" -> commodity %d: directed cutdemand=%g\n", k, comcutdemands[k]);
6095 for( k = 0; k < ncommodities; k++ )
6098 SCIPdebugMessage(
" -> commodity %d: undirected cutdemand=%g\n", k, comcutdemands[k]);
6103 if( k == ncommodities )
6107 for( a = 0; a < narcs; a++ )
6116 assert(arcsources[a] < nnodes);
6117 assert(arctargets[a] < nnodes);
6123 if(
nodeInPartition(nodepartition, partition, inverted, arcsources[a]) ||
6133 if(
nodeInPartition(nodepartition, partition, inverted, arcsources[a]) &&
6139 if( !
nodeInPartition(nodepartition, partition, inverted, arcsources[a]) &&
6148 if( arccapacityrows[a] ==
NULL )
6156 assert(rowweights[r] == 0.0);
6162 if( arcsources[a] == -1 || arctargets[a] == -1 )
6172 assert(maxcoef > 0.0);
6177 rowweights[r] = arccapacityscales[a];
6182 if( sepadata->separateflowcutset )
6184 if( rowweights[r] > 0.0 )
6194 for( j = 0; j < rowlen; j++ )
6199 coef = rowvals[j] * arccapacityscales[a];
6205 k = colcommodity[c];
6207 comdemands[k] = coef;
6221 while( left <= right )
6223 int mid = (left+right)/2;
6225 if(
REALABS( deltas[mid] / coef - 1.0 ) < 1e-03 )
6230 else if( coef < deltas[mid] )
6239 assert(right == left-1);
6240 assert(ndeltas <= deltassize);
6241 if( ndeltas == deltassize )
6246 if( left < ndeltas )
6248 for( d = ndeltas; d > left; d-- )
6249 deltas[d] = deltas[d-1];
6251 deltas[left] = coef;
6260 for( v = 0; v < nnodes; v++ )
6263 for( k = 0; k < ncommodities; k++ )
6269 if( comdemands[k] == 0.0 )
6272 scale = comdemands[k];
6295 if( comcutdemands[k] > 0.0 )
6314 if( nodeflowrows[v][k] ==
NULL )
6323 assert(rowweights[r] == 0.0);
6329 rowweights[r] = scale * nodeflowscales[v][k];
6330 if( nodeflowinverted[v][k] )
6331 rowweights[r] *= -1.0;
6332 SCIPdebugMessage(
" -> node %d, commodity %d, r=%d, flow row <%s>: scale=%g weight=%g slack=%g dual=%g\n",
6333 v, k, r,
SCIProwGetName(nodeflowrows[v][k]), scale, rowweights[r],
6336 if( sepadata->separateflowcutset )
6338 if( nodeflowscales[v][k] > 0.0 )
6354 if( sepadata->separateflowcutset )
6357 bestdelta = deltas[ndeltas-1];
6363 for( d = ndeltas-1; d >= 0 && d >= ndeltas-maxtestdelta; d-- )
6382 NULL,
NULL, cutcoefs, &cutrhs, &cutact,
6383 &success, &cutislocal, &cutrank) );
6392 if( sepadata->separateflowcutset )
6395 relviolation = (cutact - cutrhs) /
MAX( abscutrhs , 1.0 );
6396 if( relviolation > bestrelviolation )
6398 bestdelta = deltas[d];
6399 bestrelviolation = relviolation;
6405 SCIPdebugMessage(
"success -> delta = %g -> rhs: %g, act: %g\n", deltas[d], cutrhs, cutact);
6406 SCIP_CALL(
addCut(scip, sepa, sepadata, sol, cutcoefs, cutrhs, cutislocal, cutrank, ncuts, cutoff) );
6411 for( a = 0; a < narcs; a++ )
6413 if( arccapacityrows[a] !=
NULL )
6419 if( r >= 0 && rowweights[r] != 0.0 )
6421 MCFdebugMessage(
" -> arc %d, capacity row <%s>: weight=%g slack=%g prod=%g dual=%g\n", a,
6433 if( sepadata->separateflowcutset && oldncuts == *ncuts && !*cutoff )
6436 f0 =
SCIPfrac(scip, baserhs/bestdelta);
6441 totalviolationdelta = 0.0;
6442 onedivoneminsf0 = 1.0/(1.0 - f0);
6443 for( a = 0; a < narcs; a++ )
6457 if( arccapacityrows[a] ==
NULL )
6468 if( rowweights[r] == 0.0 )
6483 rowweight = rowweights[r]/bestdelta;
6488 violationdelta = rowweight * (rowlhs - rowconstant);
6490 violationdelta = rowweight * (rowrhs - rowconstant);
6492 for( j = 0; j < rowlen; j++ )
6500 coef = rowvals[j] * rowweight;
6511 if( colcommodity[c] >= 0 )
6522 mircoef =
SCIPfloor(scip, coef) + (fj - f0)*onedivoneminsf0;
6529 mircoef = coef * onedivoneminsf0;
6534 if( colcommodity[c] >= 0 )
6535 violationdelta += mircoef * solval;
6537 violationdelta -= mircoef * solval;
6542 SCIPdebugMessage(
" -> discarding capacity row <%s> of weight %g and slack %g: increases MIR violation by %g\n",
6545 rowweights[r] = 0.0;
6546 totalviolationdelta += violationdelta;
6551 if( totalviolationdelta > 0.0 )
6564 SCIPdebugMessage(
"applying MIR with delta = %g to flowcut inequality (violation improvement: %g)\n", bestdelta, totalviolationdelta);
6567 cutcoefs, &cutrhs, &cutact, &success, &cutislocal, &cutrank) );
6572 SCIPdebugMessage(
" -> delta = %g -> rhs: %g, act: %g\n", bestdelta, cutrhs, cutact);
6573 SCIP_CALL(
addCut(scip, sepa, sepadata, sol, cutcoefs, cutrhs, cutislocal, cutrank, ncuts, cutoff) );
6612 assert(result !=
NULL);
6625 if( ncols != nvars )
6627 MCFdebugMessage(
"%d variables but %d columns -> exit\n", nvars, ncols );
6640 colrowratio = (
SCIP_Real)ncols/(nrows+1e-9);
6644 assert(sepadata !=
NULL);
6653 if( colrowratio < MINCOLROWRATIO || colrowratio >
MAXCOLROWRATIO )
6662 if( sepadata->nmcfnetworks == -1 )
6670 for( i = 0; i < sepadata->nmcfnetworks; i++ )
6672 MCFdebugMessage(
" -> extracted network %d has %d nodes, %d (%d) arcs (uncapacitated), and %d commodities (modeltype: %s)\n",
6673 i, sepadata->mcfnetworks[i]->nnodes, sepadata->mcfnetworks[i]->narcs, sepadata->mcfnetworks[i]->nuncapacitatedarcs,
6674 sepadata->mcfnetworks[i]->ncommodities,
6676 SCIPdebug( mcfnetworkPrint(sepadata->mcfnetworks[i]) );
6679 #ifdef COUNTNETWORKVARIABLETYPES
6680 SCIP_CALL( printFlowSystemInfo(scip,sepadata->mcfnetworks,sepadata->nmcfnetworks));
6684 assert(sepadata->nmcfnetworks >= 0);
6685 assert(sepadata->mcfnetworks !=
NULL || sepadata->nmcfnetworks == 0);
6686 mcfnetworks = sepadata->mcfnetworks;
6687 nmcfnetworks = sepadata->nmcfnetworks;
6694 sepadata->lastroundsuccess =
FALSE;
6696 for( i = 0; i < nmcfnetworks && !cutoff; i++ )
6702 mcfnetwork = mcfnetworks[i];
6705 assert(mcfnetwork->
nnodes >= 2);
6706 assert(mcfnetwork->
narcs >= 1);
6713 MCFdebugMessage(
"MCF network has %d nodes and %d arcs. arc node ratio %.2f exceed --> exit\n",
6719 if( sepadata->separatesinglenodecuts )
6730 nodepartitionPrint(nodepartition);
6740 MCFdebugMessage(
"MCF network has %d nodes, %d arcs, %d commodities. Found %d MCF network cuts, cutoff = %u.\n",
6747 sepadata->lastroundsuccess =
TRUE;
6749 else if( ncuts > 0 )
6752 sepadata->lastroundsuccess =
TRUE;
6769 assert(scip !=
NULL);
6770 assert(sepa !=
NULL);
6788 assert(sepadata !=
NULL);
6789 assert(sepadata->mcfnetworks ==
NULL);
6790 assert(sepadata->nmcfnetworks == -1);
6808 assert(sepadata !=
NULL);
6810 sepadata->lastroundsuccess =
TRUE;
6827 assert(sepadata !=
NULL);
6830 for( i = 0; i < sepadata->nmcfnetworks; i++ )
6835 sepadata->nmcfnetworks = -1;
6897 sepadata->mcfnetworks =
NULL;
6898 sepadata->nmcfnetworks = -1;
6900 sepadata->lastroundsuccess =
TRUE;
6906 sepaExeclpMcf, sepaExecsolMcf,
6909 assert(sepa !=
NULL);
6921 "separating/mcf/nclusters",
6922 "number of clusters to generate in the shrunken network -- default separation",
6925 "separating/mcf/maxweightrange",
6926 "maximal valid range max(|weights|)/min(|weights|) of row weights",
6929 "separating/mcf/maxtestdelta",
6930 "maximal number of different deltas to try (-1: unlimited) -- default separation",
6933 "separating/mcf/trynegscaling",
6934 "should negative values also be tested in scaling?",
6937 "separating/mcf/fixintegralrhs",
6938 "should an additional variable be complemented if f0 = 0?",
6941 "separating/mcf/dynamiccuts",
6942 "should generated cuts be removed from the LP if they are no longer tight?",
6945 "separating/mcf/modeltype",
6946 "model type of network (0: auto, 1:directed, 2:undirected)",
6949 "separating/mcf/maxsepacuts",
6950 "maximal number of mcf cuts separated per separation round",
6953 "separating/mcf/maxsepacutsroot",
6954 "maximal number of mcf cuts separated per separation round in the root node -- default separation",
6957 "separating/mcf/maxinconsistencyratio",
6958 "maximum inconsistency ratio for separation at all",
6961 "separating/mcf/maxarcinconsistencyratio",
6962 "maximum inconsistency ratio of arcs not to be deleted",
6965 "separating/mcf/checkcutshoreconnectivity",
6966 "should we separate only if the cuts shores are connected?",
6969 "separating/mcf/separatesinglenodecuts",
6970 "should we separate inequalities based on single-node cuts?",
6973 "separating/mcf/separateflowcutset",
6974 "should we separate flowcutset inequalities on the network cuts?",
6977 "separating/mcf/separateknapsack",
6978 "should we separate knapsack cover inequalities on the network cuts?",