46 #define BETTERWEIGHTFORDEMANDNODES 56 #define SEPA_NAME "mcf" 57 #define SEPA_DESC "multi-commodity-flow network cut separator" 58 #define SEPA_PRIORITY -10000 60 #define SEPA_MAXBOUNDDIST 0.0 61 #define SEPA_USESSUBSCIP FALSE 62 #define SEPA_DELAY FALSE 65 #define DEFAULT_NCLUSTERS 5 66 #define DEFAULT_MAXWEIGHTRANGE 1e+06 67 #define DEFAULT_MAXTESTDELTA 20 68 #define DEFAULT_TRYNEGSCALING FALSE 69 #define DEFAULT_FIXINTEGRALRHS TRUE 70 #define DEFAULT_DYNAMICCUTS TRUE 71 #define DEFAULT_MODELTYPE 0 72 #define DEFAULT_MAXSEPACUTS 100 73 #define DEFAULT_MAXSEPACUTSROOT 200 74 #define DEFAULT_MAXINCONSISTENCYRATIO 0.02 75 #define DEFAULT_MAXARCINCONSISTENCYRATIO 0.5 76 #define DEFAULT_CHECKCUTSHORECONNECTIVITY TRUE 77 #define DEFAULT_SEPARATESINGLENODECUTS TRUE 78 #define DEFAULT_SEPARATEFLOWCUTSET TRUE 79 #define DEFAULT_SEPARATEKNAPSACK TRUE 82 #define BOUNDSWITCH 0.5 83 #define POSTPROCESS TRUE 88 #define MAXCOLS 2000000 89 #define MAXAGGRLEN(nvars) (0.1*(nvars)+1000) 90 #define MINCOLROWRATIO 0.01 91 #define MAXCOLROWRATIO 100.0 92 #define MAXFLOWVARFLOWROWRATIO 100.0 93 #define MAXARCNODERATIO 100.0 95 #define MAXFLOWCANDDENSITY 0.1 96 #define MINCOMNODESFRACTION 0.5 99 #define MAXCAPACITYSLACK 0.1 100 #define UNCAPACITATEDARCSTRESHOLD 0.8 101 #define HASHSIZE_NODEPAIRS 500 113 #define MCFdebugMessage printf 117 #define MCFdebugMessage while(FALSE) printf 191 unsigned char* flowrowsigns;
194 unsigned char* capacityrowsigns;
203 int nemptycommodities;
205 int commoditysignssize;
226 int capacityrowssize;
253 int* representatives;
265 #define LHSPOSSIBLE 1u 266 #define RHSPOSSIBLE 2u 267 #define LHSASSIGNED 4u 268 #define RHSASSIGNED 8u 270 #define DISCARDED 32u 271 #define UNDIRECTED 64u 281 assert(mcfnetwork != NULL);
284 (*mcfnetwork)->nodeflowrows = NULL;
285 (*mcfnetwork)->nodeflowscales = NULL;
286 (*mcfnetwork)->nodeflowinverted = NULL;
287 (*mcfnetwork)->arccapacityrows = NULL;
288 (*mcfnetwork)->arccapacityscales = NULL;
289 (*mcfnetwork)->arcsources = NULL;
290 (*mcfnetwork)->arctargets = NULL;
291 (*mcfnetwork)->colcommodity = NULL;
292 (*mcfnetwork)->nnodes = 0;
293 (*mcfnetwork)->nuncapacitatedarcs = 0;
294 (*mcfnetwork)->narcs = 0;
295 (*mcfnetwork)->ncommodities = 0;
307 assert(mcfnetwork != NULL);
309 if( *mcfnetwork != NULL )
314 for( v = 0; v < (*mcfnetwork)->nnodes; v++ )
318 for( k = 0; k < (*mcfnetwork)->ncommodities; k++ )
320 if( (*mcfnetwork)->nodeflowrows[v][k] != NULL )
329 for( a = 0; a < (*mcfnetwork)->narcs; a++ )
331 if( (*mcfnetwork)->arccapacityrows[a] != NULL )
364 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
365 SCIP_Real* flowrowscalars = mcfdata->flowrowscalars;
366 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
367 int* flowcands = mcfdata->flowcands;
368 int nflowcands = mcfdata->nflowcands;
370 int* commoditysigns = mcfdata->commoditysigns;
372 int* rowcommodity = mcfdata->rowcommodity;
373 int* rownodeid = mcfdata->rownodeid;
374 SCIP_ROW** capacityrows = mcfdata->capacityrows;
383 int ncompcommodities;
390 assert(mcfnetwork != NULL);
392 assert(2 <= ncompnodes && ncompnodes <= mcfdata->
nnodes);
393 assert(1 <= ncomparcs && ncomparcs <= mcfdata->
narcs);
394 assert(ncommodities > 0);
398 for( v = 0; v < mcfdata->nnodes; v++ )
399 assert(compnodeid[v] == -1);
411 compcommodity[k] = -1;
418 for( i = 0; i < ncompnodes; i++ )
421 assert(0 <= v && v < mcfdata->nnodes);
426 ncompcommodities = 0;
427 for( i = 0; i < nflowcands; i++ )
433 assert(0 <= r && r < nrows);
436 if( rv >= 0 && compnodeid[rv] >= 0 )
439 assert(0 <= k && k < ncommodities);
440 if( compcommodity[k] == -1 )
442 compcommodity[k] = ncompcommodities;
453 mcfnetwork->
nnodes = ncompnodes;
454 mcfnetwork->
narcs = ncomparcs;
462 for( v = 0; v < mcfnetwork->
nnodes; v++ )
480 for( a = 0; a < mcfnetwork->
narcs; a++ )
490 for( i = 0; i < nflowcands; i++ )
496 assert(0 <= r && r < nrows);
499 if( rv >= 0 && compnodeid[rv] >= 0 )
505 rk = rowcommodity[r];
506 assert(v < mcfnetwork->nnodes);
507 assert(0 <= rk && rk < ncommodities);
510 k = compcommodity[rk];
511 assert(0 <= k && k < mcfnetwork->ncommodities);
516 scale = flowrowscalars[r];
519 if( commoditysigns[rk] == -1 )
527 for( a = 0; a < mcfnetwork->
narcs; a++ )
537 globala = comparcs[a];
538 capacityrow = capacityrows[globala];
543 if( capacityrow != NULL)
546 assert(0 <= r && r < nrows);
548 assert((capacityrowsigns[r] &
INVERTED) == 0);
549 assert(mcfdata->rowarcid[r] == globala);
567 for( j = 0; j < rowlen; j++ )
574 if( comdemands[k] != 0.0 )
589 for( j = 0; j < rowlen; j++ )
594 if( k >= 0 && comdemands[k] == 0.0 )
606 if( mcfdata->arcsources[globala] >= 0 )
608 assert(mcfdata->arcsources[globala] < mcfdata->nnodes);
609 assert(0 <= compnodeid[mcfdata->arcsources[globala]] && compnodeid[mcfdata->arcsources[globala]] < mcfnetwork->
nnodes);
610 mcfnetwork->
arcsources[a] = compnodeid[mcfdata->arcsources[globala]];
612 if( mcfdata->arctargets[globala] >= 0 )
614 assert(mcfdata->arctargets[globala] < mcfdata->nnodes);
615 assert(0 <= compnodeid[mcfdata->arctargets[globala]] && compnodeid[mcfdata->arctargets[globala]] < mcfnetwork->
nnodes);
616 mcfnetwork->
arctargets[a] = compnodeid[mcfdata->arctargets[globala]];
621 for( c = 0; c < ncols; c++ )
631 for( i = 0; i < ncompnodes; i++ )
633 assert(0 <= compnodes[i] && compnodes[i] < mcfdata->nnodes);
634 assert(compnodeid[compnodes[i]] == i);
635 compnodeid[compnodes[i]] = -1;
648 void mcfnetworkPrint(
652 if( mcfnetwork == NULL )
659 for( v = 0; v < mcfnetwork->
nnodes; v++ )
678 for( a = 0; a < mcfnetwork->
narcs; a++ )
694 void printCommodities(
699 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
700 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
702 int* commoditysigns = mcfdata->commoditysigns;
704 int* rowcommodity = mcfdata->rowcommodity;
705 int* colarcid = mcfdata->colarcid;
706 int* rownodeid = mcfdata->rownodeid;
707 int nnodes = mcfdata->nnodes;
708 SCIP_ROW** capacityrows = mcfdata->capacityrows;
728 for( c = 0; c < ncols; c++ )
730 if( colcommodity[c] == k )
733 for( r = 0; r < nrows; r++ )
735 if( rowcommodity[r] == k )
738 (flowrowsigns[r] &
INVERTED) != 0 ? -1 : +1);
743 if( rownodeid != NULL )
747 for( v = 0; v <
nnodes; v++ )
750 for( r = 0; r < nrows; r++ )
752 if( rownodeid[r] == v )
755 (flowrowsigns[r] &
INVERTED) != 0 ? -1 : +1);
761 assert(capacityrows != NULL || mcfdata->narcs == 0);
764 for( a = 0; a < mcfdata->narcs; a++ )
767 if( capacityrows[a] != NULL )
770 assert(0 <= r && r < nrows);
773 else if( (capacityrowsigns[r] &
RHSASSIGNED) != 0 )
781 assert(colcommodity != NULL || ncols == 0);
784 for( c = 0; c < ncols; c++ )
786 if( colcommodity[c] == -1 )
795 for( r = 0; r < nrows; r++ )
797 assert(rowcommodity != NULL);
799 if( rowcommodity[r] == -1 && (capacityrowsigns == NULL || (capacityrowsigns[r] & (
LHSASSIGNED |
RHSASSIGNED)) == 0) )
815 if( rowscores[ind2] < rowscores[ind1] )
817 else if( rowscores[ind2] > rowscores[ind1] )
830 unsigned char* flowrowsigns;
850 flowrowsigns = mcfdata->flowrowsigns;
851 flowrowscalars = mcfdata->flowrowscalars;
852 flowrowscores = mcfdata->flowrowscores;
853 flowcands = mcfdata->flowcands;
855 assert(mcfdata->nflowcands == 0);
858 for( r = 0; r < nrows; r++ )
883 absdualsol = ABS(absdualsol);
886 flowrowscalars[r] = 0.0;
887 flowrowscores[r] = 0.0;
908 coef = ABS(rowvals[0]);
915 for( i = 0; i < rowlen; i++ )
921 hasposcoef = hasposcoef || (rowvals[i] > 0.0);
922 hasnegcoef = hasnegcoef || (rowvals[i] < 0.0);
952 flowrowscalars[r] = 1.0/coef;
953 flowcands[mcfdata->nflowcands] = r;
954 mcfdata->nflowcands++;
961 if(
SCIPisEQ(scip, flowrowscalars[r], 1.0) )
962 flowrowscores[r] += 1000.0;
965 if( hasposcoef && hasnegcoef )
966 flowrowscores[r] += 500.0;
973 if( ncontvars == rowlen )
974 flowrowscores[r] += 1000.0;
975 else if( nintvars + nimplintvars == rowlen )
976 flowrowscores[r] += 500.0;
977 else if( nbinvars == rowlen )
978 flowrowscores[r] += 100.0;
982 flowrowscores[r] += 10.0*rowlen/(rowlen+10.0);
986 flowrowscores[r] += 50.0;
988 assert(flowrowscores[r] > 0.0);
991 maxdualflow =
MAX(maxdualflow, absdualsol);
1004 for( i = 0; i < mcfdata->nflowcands; i++ )
1009 assert(0 <= r && r < nrows);
1014 dualsol = ABS(dualsol);
1017 assert(maxdualflow > 0.0);
1018 flowrowscores[r] += dualsol/maxdualflow + 1.0;
1019 assert(flowrowscores[r] > 0.0);
1024 SCIPsortInd(mcfdata->flowcands, compCands, (
void*)flowrowscores, mcfdata->nflowcands);
1026 MCFdebugMessage(
"flow conservation candidates [%d]\n", mcfdata->nflowcands);
1028 for( r = 0; r < mcfdata->nflowcands; r++ )
1031 SCIPdebugMsg(scip,
"%4d [score: %2g]: %s\n", mcfdata->flowcands[r], flowrowscores[mcfdata->flowcands[r]],
1046 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1049 int nactivecommodities = mcfdata->ncommodities - mcfdata->nemptycommodities;
1052 unsigned char* capacityrowsigns;
1061 int maxcolspercommoditylimit;
1062 int *ncolspercommodity;
1063 int *maxcolspercommodity;
1073 capacityrowsigns = mcfdata->capacityrowsigns;
1074 capacityrowscores = mcfdata->capacityrowscores;
1075 capacitycands = mcfdata->capacitycands;
1077 assert(mcfdata->ncapacitycands == 0);
1087 maxcolspercommoditylimit = 2;
1090 maxcolspercommoditylimit = 1;
1093 maxcolspercommoditylimit = 2;
1096 SCIPerrorMessage(
"invalid parameter value %d for model type\n", modeltype);
1100 maxdualcapacity = 0.0;
1101 directedcandsscore = 0.0;
1102 undirectedcandsscore = 0.0;
1103 for( r = 0; r < nrows; r++ )
1113 int nposcapacitycoefs;
1114 int nnegcapacitycoefs;
1116 int ncoveredcommodities;
1121 unsigned char rowsign;
1127 capacityrowsigns[r] = 0;
1128 capacityrowscores[r] = 0.0;
1147 absdualsol = ABS(absdualsol);
1156 maxcolspercommodity[r] = 0;
1161 nposcapacitycoefs = 0;
1162 nnegcapacitycoefs = 0;
1164 ncoveredcommodities = 0;
1166 sameabsflowcoef = 0.0;
1167 maxabscapacitycoef = 0.0;
1174 for( i = 0; i < rowlen; i++ )
1183 k = colcommodity[c];
1184 assert(-1 <= k && k < ncommodities);
1189 abscoef = ABS(rowvals[i]);
1190 if( sameflowcoef == 0.0 )
1191 sameflowcoef = rowvals[i];
1192 else if( !
SCIPisEQ(scip, sameflowcoef, rowvals[i]) )
1194 if( sameabsflowcoef == 0.0 )
1195 sameabsflowcoef = abscoef;
1196 else if( !
SCIPisEQ(scip, sameabsflowcoef, abscoef) )
1199 if( rowvals[i] > 0.0 )
1205 if( ncolspercommodity[k] == 0 )
1206 ncoveredcommodities++;
1207 ncolspercommodity[k]++;
1208 maxcolspercommodity[r] =
MAX(maxcolspercommodity[r], ncolspercommodity[k]);
1210 if( ncolspercommodity[k] >= 2 )
1219 abscoef = ABS(rowvals[i]);
1220 if( abscoef > maxabscapacitycoef )
1221 maxabscapacitycoef = abscoef;
1224 if( rowvals[i] > 0.0 )
1225 nposcapacitycoefs++;
1227 nnegcapacitycoefs++;
1237 if( rowsign != 0 && nposflowcoefs + nnegflowcoefs > 0 )
1241 capacityrowsigns[r] |= rowsign;
1242 capacitycands[mcfdata->ncapacitycands] = r;
1243 mcfdata->ncapacitycands++;
1246 capacityrowscores[r] = 1.0;
1250 assert(ncoveredcommodities > 0);
1251 commodityexcessratio =
1252 ABS((nposflowcoefs + nnegflowcoefs)/(
SCIP_Real)ncoveredcommodities - maxcolspercommoditylimit);
1254 capacityrowscores[r] += 1000.0 *
MAX(0.0, 2.0 - commodityexcessratio);
1261 if( (capacityrowsigns[r] &
RHSPOSSIBLE) != 0 && nnegflowcoefs == 0 && nposcapacitycoefs == 0 && nnegcapacitycoefs > 0 )
1262 capacityrowscores[r] += 1000.0;
1263 if( (capacityrowsigns[r] &
LHSPOSSIBLE) != 0 && nposflowcoefs == 0 && nposcapacitycoefs > 0 && nnegcapacitycoefs == 0 )
1264 capacityrowscores[r] += 1000.0;
1273 assert(nactivecommodities + 3 > 0);
1274 capacityrowscores[r] += 2000.0 * ncoveredcommodities/(
SCIP_Real)(nactivecommodities + 3);
1277 if(
SCIPisEQ(scip, ABS(sameflowcoef), 1.0) )
1278 capacityrowscores[r] += 500.0;
1282 capacityrowscores[r] += 250.0;
1285 if(
SCIPisEQ(scip, sameabsflowcoef, 1.0) )
1286 capacityrowscores[r] += 100.0;
1289 if( maxabscapacitycoef > 0.0 && !
SCIPisEQ(scip, maxabscapacitycoef, 1.0) )
1290 capacityrowscores[r] += 100.0;
1293 capacityrowscores[r] += 20.0 *
MAX(nposflowcoefs, nnegflowcoefs)/
MAX(1.0,(
SCIP_Real)(nposflowcoefs + nnegflowcoefs));
1296 capacityrowscores[r] += 10.0 *
MAX(nposcapacitycoefs, nnegcapacitycoefs)/(
SCIP_Real)(nposcapacitycoefs+nnegcapacitycoefs+1.0);
1299 if( (capacityrowsigns[r] & RHSPOSSIBLE) != 0 && !
SCIPisNegative(scip, rowrhs) )
1300 capacityrowscores[r] += 10.0;
1304 capacityrowscores[r] += 10.0;
1306 assert(capacityrowscores[r] > 0.0);
1307 SCIPdebugMsg(scip,
"row <%s>: maxcolspercommodity=%d capacityrowsign=%d nposflowcoefs=%d nnegflowcoefs=%d nposcapacitycoefs=%d nnegcapacitycoefs=%d nbadcoefs=%d nactivecommodities=%d sameflowcoef=%g -> score=%g\n",
1308 SCIProwGetName(row), maxcolspercommodity[r], capacityrowsigns[r], nposflowcoefs, nnegflowcoefs, nposcapacitycoefs, nnegcapacitycoefs, nbadcoefs, nactivecommodities, sameflowcoef, capacityrowscores[r]);
1311 maxdualcapacity =
MAX(maxdualcapacity, absdualsol);
1316 assert(maxcolspercommoditylimit == 2);
1317 if( (capacityrowsigns[r] &
UNDIRECTED) != 0 )
1318 undirectedcandsscore += capacityrowscores[r];
1320 directedcandsscore += capacityrowscores[r];
1325 SCIPdebugMsg(scip,
"row <%s>: rowsign = %d nposflowcoefs = %d nnegflowcoefs = %d -> discard\n",
1333 if( directedcandsscore > undirectedcandsscore )
1338 MCFdebugMessage(
"detected model type: %s (%g directed score, %g undirected score)\n",
1346 for( i = 0; i < mcfdata->ncapacitycands; i++ )
1348 r = capacitycands[i];
1349 assert(0 <= r && r < nrows);
1350 if( (capacityrowsigns[r] &
UNDIRECTED) != 0 )
1353 if( maxcolspercommodity[r] <= maxcolspercommoditylimit )
1354 capacityrowscores[r] -= 1000.0;
1368 for( i = 0; i < mcfdata->ncapacitycands; i++ )
1372 r = capacitycands[i];
1373 assert(0 <= r && r < nrows);
1378 dualsol = ABS(dualsol);
1381 assert(maxdualcapacity > 0.0);
1382 capacityrowscores[r] +=
MAX(dualsol, 0.0)/maxdualcapacity;
1383 assert(capacityrowscores[r] > 0.0);
1388 SCIPsortInd(mcfdata->capacitycands, compCands, (
void*)capacityrowscores, mcfdata->ncapacitycands);
1390 MCFdebugMessage(
"capacity candidates [%d]\n", mcfdata->ncapacitycands);
1392 for( r = 0; r < mcfdata->ncapacitycands; r++ )
1394 SCIPdebugMsg(scip,
"row %4d [score: %2g]: %s\n", mcfdata->capacitycands[r],
1395 capacityrowscores[mcfdata->capacitycands[r]],
SCIProwGetName(rows[mcfdata->capacitycands[r]]));
1415 assert(mcfdata->ncommodities <= mcfdata->commoditysignssize);
1416 if( mcfdata->ncommodities == mcfdata->commoditysignssize )
1418 mcfdata->commoditysignssize =
MAX(2*mcfdata->commoditysignssize, mcfdata->ncommodities+1);
1421 assert(mcfdata->ncommodities < mcfdata->commoditysignssize);
1424 SCIPdebugMsg(scip,
"**** creating new commodity %d ****\n", mcfdata->ncommodities);
1425 mcfdata->commoditysigns[mcfdata->ncommodities] = 0;
1426 mcfdata->ncommodities++;
1441 assert(source != target );
1442 assert(0 <= source && source < mcfdata->
nnodes);
1443 assert(0 <= target && target < mcfdata->nnodes);
1444 assert(newarcid != NULL);
1446 *newarcid = mcfdata->narcs;
1449 assert(mcfdata->narcs <= mcfdata->arcarraysize);
1450 if( mcfdata->narcs == mcfdata->arcarraysize )
1452 mcfdata->arcarraysize =
MAX(2*mcfdata->arcarraysize, mcfdata->narcs+1);
1458 assert(mcfdata->narcs < mcfdata->arcarraysize);
1461 if( mcfdata->capacityrowssize < mcfdata->arcarraysize )
1463 mcfdata->capacityrowssize = mcfdata->arcarraysize;
1466 assert(mcfdata->narcs < mcfdata->capacityrowssize);
1469 SCIPdebugMsg(scip,
"**** creating new arc %d: %d -> %d ****\n", mcfdata->narcs, source, target);
1471 mcfdata->arcsources[*newarcid] = source;
1472 mcfdata->arctargets[*newarcid] = target;
1473 mcfdata->nextoutarcs[*newarcid] = mcfdata->firstoutarcs[source];
1474 mcfdata->firstoutarcs[source] = *newarcid;
1475 mcfdata->nextinarcs[*newarcid] = mcfdata->firstinarcs[target];
1476 mcfdata->firstinarcs[target] = *newarcid;
1477 mcfdata->capacityrows[*newarcid] = NULL;
1490 unsigned char rowsign,
1495 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1496 SCIP_Bool* plusflow = mcfdata->plusflow;
1497 SCIP_Bool* minusflow = mcfdata->minusflow;
1499 int* commoditysigns = mcfdata->commoditysigns;
1501 int* rowcommodity = mcfdata->rowcommodity;
1502 int* newcols = mcfdata->newcols;
1513 assert(comcolids != NULL);
1514 assert(ncomcolids != NULL);
1523 invertrow = ((rowsign &
INVERTED) != 0);
1526 assert(rowcommodity[r] == -1);
1527 assert((flowrowsigns[r] | rowsign) == flowrowsigns[r]);
1529 assert(rowsign != 0);
1535 commoditysigns[k] = +1;
1564 else if( rowlhs > 0.0 )
1581 flowrowsigns[r] |= rowsign;
1583 SCIPdebugMsg(scip,
"adding flow row %d <%s> with sign %+d%s to commodity %d [score:%g]\n",
1585 k, mcfdata->flowrowscores[r]);
1589 rowcommodity[r] = k;
1593 for( i = 0; i < rowlen; i++ )
1602 if( colcommodity[c] == -1 )
1604 assert(!plusflow[c]);
1605 assert(!minusflow[c]);
1607 colcommodity[c] = k;
1608 newcols[mcfdata->nnewcols] = c;
1609 mcfdata->nnewcols++;
1610 comcolids[*ncomcolids] = c;
1613 assert(colcommodity[c] == k);
1616 val = rowscale * rowvals[i];
1619 assert(!plusflow[c]);
1624 assert(!minusflow[c]);
1625 minusflow[c] =
TRUE;
1642 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1643 SCIP_Bool* plusflow = mcfdata->plusflow;
1644 SCIP_Bool* minusflow = mcfdata->minusflow;
1648 assert(mcfdata->commoditysigns[k] == 0);
1649 assert(comrows != NULL || ncomrows == 0);
1650 assert(comcolids != NULL);
1653 for( i = 0; i < ncomrows; i++ )
1657 unsigned char rowsign;
1659 assert(comrows != NULL);
1661 assert( row != NULL );
1664 assert(mcfdata->rowcommodity[r] == k);
1668 rowsign = flowrowsigns[r];
1680 for( i = 0; i < ncomcolids; i++ )
1687 assert(mcfdata->colcommodity[c] == k);
1690 plusflow[c] = minusflow[c];
1707 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1708 SCIP_Bool* plusflow = mcfdata->plusflow;
1709 SCIP_Bool* minusflow = mcfdata->minusflow;
1712 int* rowcommodity = mcfdata->rowcommodity;
1716 assert(0 <= k && k < ncommodities);
1718 assert( ndelflowrows != NULL );
1719 assert( ndelflowvars != NULL );
1721 SCIPdebugMsg(scip,
"deleting commodity %d (%d total commodities) with %d flow rows\n", k, ncommodities, nrows);
1726 for( n = 0; n < nrows; n++ )
1737 assert(rowcommodity[r] == k);
1746 rowcommodity[r] = -1;
1749 for( i = 0; i < rowlen; i++ )
1757 assert(colcommodity[c] == k || colcommodity[c] == -1);
1758 if(colcommodity[c] == k)
1760 colcommodity[c] = -1;
1763 plusflow[c] =
FALSE;
1764 minusflow[c] =
FALSE;
1773 if( k == ncommodities-1 )
1774 mcfdata->ncommodities--;
1776 mcfdata->nemptycommodities++;
1786 unsigned char* rowsign,
1790 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
1791 SCIP_Bool* plusflow = mcfdata->plusflow;
1792 SCIP_Bool* minusflow = mcfdata->minusflow;
1794 int* rowcommodity = mcfdata->rowcommodity;
1795 int* commoditysigns = mcfdata->commoditysigns;
1800 unsigned char flowrowsign;
1801 unsigned char invflowrowsign;
1805 assert(invertcommodity != NULL);
1808 *invertcommodity =
FALSE;
1814 if( rowcommodity[r] != -1 )
1818 flowrowsign = flowrowsigns[r];
1824 invflowrowsign = flowrowsign;
1830 for( j = 0; j < rowlen && (flowrowsign != 0 || invflowrowsign != 0); j++ )
1838 if( colcommodity[rowc] == k )
1841 if( plusflow[rowc] )
1844 if( rowvals[j] > 0.0 )
1855 if( minusflow[rowc] )
1858 if( rowvals[j] > 0.0 )
1870 else if( colcommodity[rowc] != -1 )
1878 if( flowrowsign != 0 )
1881 *rowsign = flowrowsign;
1882 *invertcommodity =
FALSE;
1884 else if( invflowrowsign != 0 )
1890 if( commoditysigns == NULL || commoditysigns[k] == 0 )
1893 *rowsign = invflowrowsign;
1894 *invertcommodity =
TRUE;
1899 *rowsign = (invflowrowsign |
INVERTED);
1900 *invertcommodity =
FALSE;
1917 unsigned char* nextrowsign,
1921 SCIP_Real* flowrowscores = mcfdata->flowrowscores;
1922 SCIP_Bool* plusflow = mcfdata->plusflow;
1923 SCIP_Bool* minusflow = mcfdata->minusflow;
1924 int* newcols = mcfdata->newcols;
1930 assert(nextrow != NULL);
1931 assert(nextrowsign != NULL);
1935 *nextinvertcommodity =
FALSE;
1940 assert(cols != NULL);
1943 while( mcfdata->nnewcols > 0 )
1949 unsigned char bestrowsign;
1956 c = newcols[mcfdata->nnewcols-1];
1957 mcfdata->nnewcols--;
1961 assert(plusflow[c] || minusflow[c]);
1962 if( plusflow[c] && minusflow[c] )
1968 bestinvertcommodity =
FALSE;
1973 for( i = 0; i < collen; i++ )
1976 unsigned char flowrowsign;
1982 getFlowrowFit(scip, mcfdata, row, k, &flowrowsign, &invertcommodity);
1985 if( flowrowsign != 0 )
1992 score = flowrowscores[r];
1993 assert(score > 0.0);
1999 if( (flowrowsign &
INVERTED) != 0 )
2002 if( score > bestscore )
2005 bestrowsign = flowrowsign;
2006 bestinvertcommodity = invertcommodity;
2016 if( bestrow != NULL )
2018 assert(bestscore > 0.0);
2019 assert(bestrowsign != 0);
2021 *nextrowsign = bestrowsign;
2022 *nextinvertcommodity = bestinvertcommodity;
2037 int* flowcands = mcfdata->flowcands;
2064 assert(failed != NULL);
2073 plusflow = mcfdata->plusflow;
2074 minusflow = mcfdata->minusflow;
2075 colcommodity = mcfdata->colcommodity;
2076 rowcommodity = mcfdata->rowcommodity;
2088 for( c = 0; c < ncols; c++ )
2089 colcommodity[c] = -1;
2090 for( r = 0; r < nrows; r++ )
2091 rowcommodity[r] = -1;
2093 assert(flowcands != NULL || mcfdata->nflowcands == 0);
2104 for( i = 0; i < mcfdata->nflowcands; i++ )
2107 unsigned char newrowsign;
2111 assert(flowcands != NULL);
2113 assert(0 <= r && r < nrows);
2117 getFlowrowFit(scip, mcfdata, newrow, mcfdata->ncommodities, &newrowsign, &newinvertcommodity);
2118 if( newrowsign == 0 )
2120 assert(!newinvertcommodity);
2121 assert((newrowsign &
INVERTED) == 0);
2124 SCIPdebugMsg(scip,
" -------------------start new commodity %d--------------------- \n", mcfdata->ncommodities );
2133 if( newinvertcommodity )
2134 invertCommodity(scip, mcfdata, mcfdata->ncommodities-1, comrows, nnodes, comcolids, ncomcolids);
2139 comrows[
nnodes] = newrow;
2144 getNextFlowrow(scip, mcfdata, &newrow, &newrowsign, &newinvertcommodity);
2146 while( newrow != NULL );
2148 ncomnodes[mcfdata->ncommodities-1] =
nnodes;
2149 maxnnodes =
MAX(maxnnodes, nnodes);
2150 nflowvars += ncomcolids;
2151 SCIPdebugMsg(scip,
" -> finished commodity %d: identified %d nodes, maxnnodes=%d\n", mcfdata->ncommodities-1, nnodes, maxnnodes);
2159 deleteCommodity(scip, mcfdata, mcfdata->ncommodities-1, comrows, nnodes, &ndelflowrows, &ndelflowvars);
2160 nflowrows -= ndelflowrows;
2161 nflowvars -= ndelflowvars;
2162 assert(nflowvars >= 0);
2163 assert(nflowrows >= 0);
2167 for( k = 0; k < mcfdata->ncommodities; k++ )
2179 for( i = 0; i < mcfdata->nflowcands; i++ )
2181 assert(flowcands != NULL);
2183 if( rowcommodity[r] == k )
2185 comrows[
nnodes] = rows[r];
2188 if( nnodes == ncomnodes[k] )
2193 assert(nnodes == ncomnodes[k]);
2194 deleteCommodity(scip, mcfdata, k, comrows, nnodes, &ndelflowrows, &ndelflowvars);
2195 nflowrows -= ndelflowrows;
2196 nflowvars -= ndelflowvars;
2197 assert(nflowvars >= 0);
2198 assert(nflowrows >= 0);
2207 MCFdebugMessage(
"identified %d commodities (%d empty) with a maximum of %d nodes and %d flowrows, %d flowvars \n",
2208 mcfdata->ncommodities, mcfdata->nemptycommodities, maxnnodes, nflowrows, nflowvars);
2210 assert(nflowvars >= 0);
2211 assert(nflowrows >= 0);
2230 unsigned char* capacityrowsigns = mcfdata->capacityrowsigns;
2233 unsigned char* flowrowsigns = mcfdata->capacityrowsigns;
2234 int* rowcommodity = mcfdata->rowcommodity;
2250 SCIP_Real* capacityrowscores = mcfdata->capacityrowscores;
2252 int *capacitycands = mcfdata->capacitycands;
2253 int ncapacitycands = mcfdata->ncapacitycands;
2255 assert(mcfdata->narcs == 0);
2256 assert(capacitycands != NULL || ncapacitycands == 0);
2265 colarcid = mcfdata->colarcid;
2266 rowarcid = mcfdata->rowarcid;
2269 for( c = 0; c < ncols; c++ )
2271 for( r = 0; r < nrows; r++ )
2275 for( i = 0; i < ncapacitycands; i++ )
2281 int nassignedflowvars;
2282 int nunassignedflowvars;
2285 assert(capacitycands != NULL);
2286 r = capacitycands[i];
2287 assert(0 <= r && r < nrows );
2288 capacityrow = rows[r];
2292 assert((capacityrowsigns[r] &
DISCARDED) == 0);
2293 assert(capacityrowscores[r] > 0.0);
2297 assert(rowarcid[r] == -1);
2300 assert( rowcommodity[r] == -1 );
2306 nassignedflowvars = 0;
2307 nunassignedflowvars = 0;
2308 for( k = 0; k < rowlen; k++ )
2311 assert(0 <= c && c < ncols);
2313 assert(-1 <= colcommodity[c] && colcommodity[c] < mcfdata->ncommodities);
2314 assert(-1 <= colarcid[c] && colarcid[c] < mcfdata->narcs);
2317 if( colcommodity[c] == -1 )
2321 if( colarcid[c] >= 0 )
2322 nassignedflowvars++;
2324 nunassignedflowvars++;
2331 if( nunassignedflowvars == 0 || nassignedflowvars >= nunassignedflowvars * 2 )
2333 SCIPdebugMsg(scip,
"discarding capacity candidate row %d <%s> [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2334 r,
SCIProwGetName(capacityrow), mcfdata->capacityrowscores[r], nassignedflowvars, nunassignedflowvars);
2340 assert(mcfdata->narcs <= mcfdata->capacityrowssize);
2341 if( mcfdata->narcs == mcfdata->capacityrowssize )
2343 mcfdata->capacityrowssize =
MAX(2*mcfdata->capacityrowssize, mcfdata->narcs+1);
2346 assert(mcfdata->narcs < mcfdata->capacityrowssize);
2347 assert(mcfdata->narcs < nrows);
2349 mcfdata->capacityrows[mcfdata->narcs] = capacityrow;
2352 assert(0 <= r && r < nrows);
2353 rowarcid[r] = mcfdata->narcs;
2364 SCIPdebugMsg(scip,
"assigning capacity row %d <%s> with sign %+d to arc %d [score:%g]: %d assigned flowvars, %d unassigned flowvars\n",
2366 mcfdata->capacityrowscores[r], nassignedflowvars, nunassignedflowvars);
2369 for( k = 0; k < rowlen; k++ )
2372 assert(0 <= rowc && rowc < ncols);
2377 if( colcommodity[rowc] >= 0 && colarcid[rowc] == -1 )
2378 colarcid[rowc] = mcfdata->narcs;
2398 int* colarcid = mcfdata->colarcid;
2399 int* newcols = mcfdata->newcols;
2400 SCIP_ROW** capacityrows = mcfdata->capacityrows;
2401 SCIP_Bool* colisincident = mcfdata->colisincident;
2410 assert(!colisincident[i]);
2416 mcfdata->nnewcols = 0;
2418 for( i = 0; i < rowlen; i++ )
2431 arcid = colarcid[c];
2434 assert(arcid < mcfdata->
narcs);
2437 assert(capacityrows[arcid] != NULL);
2441 for( j = 0; j < capacityrowlen; j++ )
2449 if( colcommodity[caprowc] == -1 )
2451 assert(colarcid[caprowc] == -1);
2454 assert(colarcid[caprowc] <= arcid);
2457 if( colcommodity[caprowc] == basecommodity )
2461 if( !colisincident[caprowc] )
2463 assert(mcfdata->nnewcols < SCIPgetNLPCols(scip));
2464 colisincident[caprowc] =
TRUE;
2465 newcols[mcfdata->nnewcols] = caprowc;
2466 mcfdata->nnewcols++;
2480 int* basearcpattern,
2489 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2490 int* commoditysigns = mcfdata->commoditysigns;
2491 int narcs = mcfdata->narcs;
2492 int* rowcommodity = mcfdata->rowcommodity;
2493 int* colarcid = mcfdata->colarcid;
2494 int* arcpattern = mcfdata->zeroarcarray;
2507 int* overlappingarcs;
2508 int noverlappingarcs;
2513 *invertcommodity =
FALSE;
2516 for( i = 0; i <
narcs; i++ )
2517 assert(arcpattern[i] == 0);
2526 rowcom = rowcommodity[r];
2528 rowcomsign = commoditysigns[rowcom];
2529 assert(-1 <= rowcomsign && rowcomsign <= +1);
2534 incompatible =
FALSE;
2535 noverlappingarcs = 0;
2539 for( i = 0; i < rowlen; i++ )
2549 valsign = (rowvals[i] > 0.0 ? +1 : -1);
2552 if( (flowrowsigns[r] &
INVERTED) != 0 )
2555 arcid = colarcid[c];
2564 assert(arcid < narcs);
2567 if( basearcpattern[arcid] != 0 )
2574 if( ( valsign * basearcpattern[arcid] ) > 0 )
2579 if( rowcomsign == 0 )
2582 rowcomsign = validcomsign;
2584 else if( rowcomsign != validcomsign )
2587 incompatible =
TRUE;
2598 if( arcpattern[arcid] == 0 )
2600 overlappingarcs[noverlappingarcs] = arcid;
2603 arcpattern[arcid] += valsign;
2609 for( i = 0; i < noverlappingarcs; i++ )
2615 arcid = overlappingarcs[i];
2616 assert(0 <= arcid && arcid < narcs);
2619 basenum = ABS(basearcpattern[arcid]);
2620 arcnum = ABS(arcpattern[arcid]);
2621 assert(basenum != 0.0);
2622 assert(arcnum != 0.0);
2624 if( basenum > arcnum )
2625 overlap += arcnum/basenum;
2627 overlap += basenum/arcnum;
2629 arcpattern[arcid] = 0;
2633 if( !incompatible && overlap > 0.0 )
2636 int rowarcs = rowlen - nposuncap - nneguncap;
2637 int baserowarcs = baserowlen - basenposuncap - basenneguncap;
2640 assert(overlap <= (
SCIP_Real) baserowlen);
2641 assert(noverlappingarcs >= 1);
2643 *invertcommodity = (rowcomsign == -1);
2647 if( noverlappingarcs >= 2 )
2650 assert(rowarcs >= 0 && baserowarcs >= 0 );
2653 *score = overlap - (rowarcs + baserowarcs - 2.0 * overlap)/(2.0 * ncols + 1.0);
2655 *score = overlap - (rowarcs + baserowarcs - 4.0 * overlap)/(2.0 * ncols + 1.0);
2658 if(*invertcommodity)
2659 *score += 1.0 - (ABS(nneguncap - basenposuncap) + ABS(nposuncap - basenneguncap))/(2.0 * ncols + 1.0);
2661 *score += 1.0 - (ABS(nposuncap - basenposuncap) + ABS(nneguncap - basenneguncap))/(2.0 * ncols + 1.0);
2663 *score =
MAX(*score, 1e-6);
2667 SCIPdebugMsg(scip,
" -> node similarity: row <%s>: incompatible=%u overlap=%g rowlen=%d baserowlen=%d score=%g\n",
2668 SCIProwGetName(row), incompatible, overlap, rowlen, baserowlen, *score);
2683 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2685 int* commoditysigns = mcfdata->commoditysigns;
2686 int narcs = mcfdata->narcs;
2687 int* flowcands = mcfdata->flowcands;
2688 int nflowcands = mcfdata->nflowcands;
2689 int* rowcommodity = mcfdata->rowcommodity;
2690 int* colarcid = mcfdata->colarcid;
2691 int* newcols = mcfdata->newcols;
2712 assert(mcfdata->nnodes == 0);
2724 rownodeid = mcfdata->rownodeid;
2725 colisincident = mcfdata->colisincident;
2735 for( r = 0; r < nrows; r++ )
2737 for( c = 0; c < ncols; c++ )
2738 colisincident[c] =
FALSE;
2740 assert(flowcands != NULL || nflowcands == 0);
2743 for( n = 0; n < nflowcands; n++ )
2752 assert(flowcands != NULL);
2754 assert(0 <= r && r < nrows);
2757 basecommodity = rowcommodity[r];
2758 if( basecommodity == -1 )
2761 assert(mcfdata->rowarcid[r] == -1);
2764 if( rownodeid[r] >= 0 )
2768 SCIPdebugMsg(scip,
"assigning row %d <%s> of commodity %d to node %d [score: %g]\n",
2769 r,
SCIProwGetName(rows[r]), basecommodity, mcfdata->nnodes, mcfdata->flowrowscores[r]);
2770 rownodeid[r] = mcfdata->nnodes;
2778 if(ncommodities == 1)
2793 if( (flowrowsigns[r] &
INVERTED) != 0 )
2795 if( commoditysigns[basecommodity] == -1 )
2798 for( i = 0; i < rowlen; i++ )
2803 assert(0 <= c && c < ncols);
2804 arcid = colarcid[c];
2809 arcpattern[arcid]++;
2811 arcpattern[arcid]--;
2826 bestflowrows[i] = NULL;
2827 bestscores[i] = 0.0;
2828 bestinverted[i] =
FALSE;
2840 for( i = 0; i < mcfdata->nnewcols; i++ )
2847 assert(0 <= c && c < ncols);
2848 assert(mcfdata->colcommodity[c] >= 0);
2849 assert(mcfdata->colcommodity[c] != basecommodity);
2852 assert(colisincident[c]);
2853 colisincident[c] =
FALSE;
2859 for( j = 0; j < collen; j++ )
2867 assert(0 <= colr && colr < nrows);
2870 if( rowprocessed[colr] )
2872 rowprocessed[colr] =
TRUE;
2875 rowcom = rowcommodity[colr];
2876 assert(rowcom != basecommodity);
2880 assert(rowcom == mcfdata->colcommodity[c]);
2881 assert((flowrowsigns[colr] & (
LHSASSIGNED | RHSASSIGNED)) != 0);
2882 assert(mcfdata->rowarcid[colr] == -1);
2885 if( rownodeid[colr] >= 0 )
2890 nposuncap, nneguncap, colrows[j], &score, &invertcommodity) );
2893 if( score > bestscores[rowcom] )
2895 bestflowrows[rowcom] = colrows[j];
2896 bestscores[rowcom] = score;
2897 bestinverted[rowcom] = invertcommodity;
2901 assert(bestflowrows[basecommodity] == NULL);
2908 if( bestflowrows[i] == NULL )
2912 assert(0 <= comr && comr < nrows);
2913 assert(rowcommodity[comr] == i);
2914 assert((flowrowsigns[comr] & (
LHSASSIGNED | RHSASSIGNED)) != 0);
2915 assert(rownodeid[comr] == -1);
2916 assert(mcfdata->nnodes >= 1);
2918 SCIPdebugMsg(scip,
" -> assigning row %d <%s> of commodity %d to node %d [invert:%u]\n",
2919 comr,
SCIProwGetName(rows[comr]), i, mcfdata->nnodes-1, bestinverted[i]);
2920 rownodeid[comr] = mcfdata->nnodes-1;
2923 if( bestinverted[i] )
2925 assert(commoditysigns[i] != +1);
2926 commoditysigns[i] = -1;
2930 assert(commoditysigns[i] != -1);
2931 commoditysigns[i] = +1;
2954 int* commoditysigns = mcfdata->commoditysigns;
2957 for( k = 0; k < mcfdata->ncommodities; k++ )
2959 if( commoditysigns[k] == 0 )
2960 commoditysigns[k] = +1;
2975 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
2976 int* commoditysigns = mcfdata->commoditysigns;
2977 int* rowcommodity = mcfdata->rowcommodity;
2978 int* rownodeid = mcfdata->rownodeid;
2979 int* colsources = mcfdata->colsources;
2980 int* coltargets = mcfdata->coltargets;
2988 assert(sourcenode != NULL);
2989 assert(targetnode != NULL);
2990 assert(colsources != NULL);
2991 assert(coltargets != NULL);
2997 if( colsources[c] >= -1 )
2999 assert(coltargets[c] >= -1);
3000 *sourcenode = colsources[c];
3001 *targetnode = coltargets[c];
3012 for( i = 0; i < collen; i++ )
3019 if( rownodeid[r] >= 0 )
3026 k = rowcommodity[r];
3027 assert(0 <= v && v < mcfdata->
nnodes);
3035 if( (flowrowsigns[r] &
INVERTED) != 0 )
3037 if( commoditysigns[k] == -1 )
3041 if( ( scale * colvals[i] ) > 0.0 )
3043 assert(*sourcenode == -1);
3045 if( *targetnode >= 0 )
3050 assert(*targetnode == -1);
3052 if( *sourcenode >= 0 )
3059 colsources[c] = *sourcenode;
3060 coltargets[c] = *targetnode;
3071 int* flowcands = mcfdata->flowcands;
3072 int nflowcands = mcfdata->nflowcands;
3074 unsigned char* flowrowsigns = mcfdata->flowrowsigns;
3076 int* rowcommodity = mcfdata->rowcommodity;
3078 int* rownodeid = mcfdata->rownodeid;
3079 int* colarcid = mcfdata->colarcid;
3080 int nnodes = mcfdata->nnodes;
3088 int* sortedflowcands;
3089 int* sortedflowcandnodeid;
3102 assert(mcfdata->nemptycommodities == 0);
3103 assert(ncommodities >= 0);
3107 if( ncommodities == 0 || nflowcands == 0 || nnodes == 0 )
3116 assert(rows != NULL);
3117 assert(cols != NULL || ncols == 0);
3128 for( n = 0; n < nflowcands; n++ )
3130 sortedflowcands[n] = flowcands[n];
3131 sortedflowcandnodeid[n] = rownodeid[flowcands[n]];
3135 SCIPsortIntInt(sortedflowcandnodeid, sortedflowcands, nflowcands);
3136 assert(sortedflowcandnodeid[0] <= 0);
3137 assert(sortedflowcandnodeid[nflowcands-1] == nnodes-1);
3140 for( v = 0; v <
nnodes; v++ )
3156 for( n = 0; n < nflowcands; n++ )
3158 if( sortedflowcandnodeid[n] >= 0 )
3160 assert(0 <= sortedflowcands[n] && sortedflowcands[n] <
SCIPgetNLPRows(scip));
3161 assert(rowcommodity[sortedflowcands[n]] == -1);
3163 assert(n < nflowcands);
3164 assert(sortedflowcandnodeid[n] == 0);
3169 for( v = 0; n < nflowcands; v++ )
3174 assert(0 <= sortedflowcands[n] && sortedflowcands[n] <
SCIPgetNLPRows(scip));
3175 assert(rowcommodity[sortedflowcands[n]] >= 0);
3176 assert(rownodeid[sortedflowcands[n]] == sortedflowcandnodeid[n]);
3177 assert(sortedflowcandnodeid[n] == v);
3178 assert(nadjnodes == 0);
3179 assert(ninccols == 0);
3184 for( ; n < nflowcands && sortedflowcandnodeid[n] == v; n++ )
3191 r = sortedflowcands[n];
3193 assert(mcfdata->rowarcid[r] == -1);
3198 for( i = 0; i < rowlen; i++ )
3209 arcid = colarcid[c];
3210 assert(-2 <= arcid && arcid < mcfdata->
narcs);
3211 assert(rowcommodity[r] == colcommodity[c]);
3221 else if( arcid == -1 )
3231 assert(-1 <= s && s < nnodes);
3232 assert(-1 <= t && t < nnodes);
3233 assert(s == v || t == v);
3244 if( s < 0 || t < 0 )
3252 assert(ninccols < ncols);
3253 inccols[ninccols] = c;
3269 if( sourcecount[u] + targetcount[u] == 1 )
3271 assert(nadjnodes < nnodes);
3272 adjnodes[nadjnodes] = u;
3280 for( l = 0; l < nadjnodes; l++ )
3285 assert(0 <= u && u < nnodes);
3286 assert(sourcecount[u] > 0 || targetcount[u] > 0);
3288 assert(ninccols >= 0);
3291 if( sourcecount[u] >= arcsthreshold )
3298 SCIPdebugMsg(scip,
" -> new arc: <%i> = (%i,%i)\n", arcid, u, v);
3301 for( m = 0; m < ninccols; m++ )
3308 assert(0 <= c && c < ncols);
3310 assert(cols != NULL);
3312 assert(s == v || t == v);
3317 colarcid[c] = arcid;
3320 inccols[m] = inccols[ninccols-1];
3328 if( targetcount[u] >= arcsthreshold )
3335 SCIPdebugMsg(scip,
" -> new arc: <%i> = (%i,%i)\n", arcid, v, u);
3338 for( m = 0; m < ninccols; m++ )
3345 assert(0 <= c && c < ncols);
3347 assert(cols != NULL);
3349 assert(s == v || t == v);
3354 colarcid[c] = arcid;
3357 inccols[m] = inccols[ninccols-1];
3366 for( l = 0; l < nadjnodes; l++ )
3374 for( l = 0; l < ninccols; l++ )
3376 assert(colarcid[inccols[l]] == -1);
3377 colarcid[inccols[l]] = -2;
3381 assert(n == nflowcands);
3382 assert(v == nnodes);
3386 for( n = 0; n < ncols; n++ )
3387 assert(colarcid[n] >= -1);
3398 MCFdebugMessage(
"network after finding uncapacitated arcs has %d nodes, %d arcs, and %d commodities\n",
3399 mcfdata->nnodes, mcfdata->narcs, mcfdata->ncommodities);
3411 int* flowcands = mcfdata->flowcands;
3412 int nflowcands = mcfdata->nflowcands;
3414 int* rowcommodity = mcfdata->rowcommodity;
3415 int* colarcid = mcfdata->colarcid;
3416 int* rowarcid = mcfdata->rowarcid;
3417 int* rownodeid = mcfdata->rownodeid;
3419 int* commoditysigns = mcfdata->commoditysigns;
3420 int narcs = mcfdata->narcs;
3421 int nnodes = mcfdata->nnodes;
3422 SCIP_ROW** capacityrows = mcfdata->capacityrows;
3434 int nnodesthreshold;
3435 int newncommodities;
3441 MCFdebugMessage(
"network before cleanup has %d nodes, %d arcs, and %d commodities\n", nnodes, narcs, ncommodities);
3449 permsize =
MAX(permsize, narcs);
3450 permsize =
MAX(permsize, nnodes);
3460 assert(flowcands != NULL || nflowcands == 0);
3463 for( i = 0; i < nflowcands; i++ )
3467 assert(flowcands != NULL);
3469 assert(0 <= r && r < nrows);
3470 assert((rownodeid[r] >= 0) == (rowcommodity[r] >= 0));
3471 if( rowcommodity[r] >= 0 )
3473 assert(rowcommodity[r] < ncommodities);
3474 nnodespercom[rowcommodity[r]]++;
3478 assert(capacityrows != NULL || narcs == 0);
3481 for( a = 0; a <
narcs; a++ )
3488 assert(capacityrows != NULL);
3490 assert(0 <= r && r < nrows);
3491 assert(rowarcid[r] == a);
3497 for( j = 0; j < rowlen; j++ )
3502 assert(0 <= c && c < ncols);
3503 if( colcommodity[c] >= 0 && colarcid[c] == a )
3505 assert(colcommodity[c] < ncommodities);
3506 arcisincom[colcommodity[c]] =
TRUE;
3521 maxnnodes =
MAX(maxnnodes, nnodespercom[k]);
3529 SCIPdebugMsg(scip,
" -> node threshold: %d\n", nnodesthreshold);
3532 newncommodities = 0;
3535 SCIPdebugMsg(scip,
" -> commodity %d: %d nodes, %d arcs\n", k, nnodespercom[k], narcspercom[k]);
3538 if( nnodespercom[k] >= nnodesthreshold && narcspercom[k] >= 1 )
3540 assert(newncommodities <= k);
3541 perm[k] = newncommodities;
3542 commoditysigns[newncommodities] = commoditysigns[k];
3549 if( newncommodities < ncommodities )
3558 SCIPdebugMsg(scip,
" -> discarding %d of %d commodities\n", ncommodities - newncommodities, ncommodities);
3566 for( c = 0; c < ncols; c++ )
3568 if( colcommodity[c] >= 0 )
3570 assert(-1 <= colarcid[c] && colarcid[c] < narcs);
3571 assert(colcommodity[c] < mcfdata->ncommodities);
3572 colcommodity[c] = perm[colcommodity[c]];
3573 assert(colcommodity[c] < newncommodities);
3574 if( colcommodity[c] == -1 )
3579 else if( colarcid[c] >= 0 )
3580 arcisused[colarcid[c]] =
TRUE;
3583 for( i = 0; i < nflowcands; i++ )
3587 assert(flowcands != NULL);
3589 assert(0 <= r && r < nrows);
3590 assert((rownodeid[r] >= 0) == (rowcommodity[r] >= 0));
3591 if( rowcommodity[r] >= 0 )
3593 assert(0 <= rownodeid[r] && rownodeid[r] < nnodes);
3594 assert(rowcommodity[r] < mcfdata->ncommodities);
3595 rowcommodity[r] = perm[rowcommodity[r]];
3596 assert(rowcommodity[r] < newncommodities);
3597 if( rowcommodity[r] == -1 )
3603 nodeisused[rownodeid[r]] =
TRUE;
3607 mcfdata->ncommodities = newncommodities;
3608 ncommodities = newncommodities;
3612 for( a = 0; a <
narcs; a++ )
3616 assert(capacityrows != NULL);
3620 assert(newnarcs <= a);
3622 capacityrows[newnarcs] = capacityrows[a];
3631 assert(0 <= r && r < nrows);
3632 assert(rowarcid[r] == a);
3633 rowarcid[r] = perm[a];
3637 if( newnarcs < narcs )
3639 SCIPdebugMsg(scip,
" -> discarding %d of %d arcs\n", narcs - newnarcs, narcs);
3641 for( c = 0; c < ncols; c++ )
3643 if( colarcid[c] >= 0 )
3645 colarcid[c] = perm[colarcid[c]];
3646 assert(colarcid[c] >= 0);
3649 mcfdata->narcs = newnarcs;
3653 for( a = 0; a <
narcs; a++ )
3656 assert(capacityrows != NULL);
3658 assert(0 <= r && r < nrows);
3659 assert(rowarcid[r] == a);
3665 for( v = 0; v <
nnodes; v++ )
3669 assert(newnnodes <= v);
3670 perm[v] = newnnodes;
3678 if( newnnodes < nnodes )
3680 SCIPdebugMsg(scip,
" -> discarding %d of %d nodes\n", nnodes - newnnodes, nnodes);
3682 for( i = 0; i < nflowcands; i++ )
3686 assert(flowcands != NULL);
3688 assert(0 <= r && r < nrows);
3689 assert((rownodeid[r] >= 0) == (rowcommodity[r] >= 0));
3690 if( rowcommodity[r] >= 0 )
3692 assert(rowcommodity[r] < ncommodities);
3693 rownodeid[r] = perm[rownodeid[r]];
3694 assert(rownodeid[r] >= 0);
3697 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;
3733 int narcs = mcfdata->narcs;
3734 int nnodes = mcfdata->nnodes;
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++ )
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 SCIPdebugMsg(scip,
"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);
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;
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 SCIPdebugMsg(scip,
" -> 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 SCIPdebugMsg(scip,
" -> 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++)
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;
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);
4895 hashtablesize = mcfnetwork->
narcs;
4898 hashGetKeyNodepairs, hashKeyEqNodepairs, hashKeyValNodepairs, (
void*) mcfnetwork) );
4905 for( a = 0; a < mcfnetwork->narcs; a++ )
4911 capacityrow = mcfnetwork->arccapacityrows[a];
4913 SCIPdebugMsg(scip,
"arc %i = (%i %i)\n", a, mcfnetwork->arcsources[a], mcfnetwork->arctargets[a]);
4916 if( mcfnetwork->arcsources[a] <= mcfnetwork->arctargets[a] )
4918 nodepair.node1 = mcfnetwork->arcsources[a];
4919 nodepair.node2 = mcfnetwork->arctargets[a];
4923 nodepair.node2 = mcfnetwork->arcsources[a];
4924 nodepair.node1 = mcfnetwork->arctargets[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);
4952 scale = ABS(mcfnetwork->arccapacityscales[a])/maxval;
4953 assert(scale > 0.0);
4963 for( i = 0; i < rowlen; i++ )
4970 if(colcommodity[c] >= 0)
4982 SCIPdebugMsg(scip,
"cap arc -- slack:%g -- dual:%g -- flow:%g -- cap:%g \n", scale * slack, dualsol/scale, totalflow * scale, totalcap * scale);
4984 SCIPdebugMsg(scip,
"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 SCIPdebugMsg(scip,
"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 SCIPdebugMsg(scip,
"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);
5061 SCIPdebugMsg(scip,
"min/max weight:%g / %g\n", minweight, maxweight);
5068 for( n = 0; n < nnodepairs; n++ )
5070 int node1 = nodepairs[n].node1;
5071 int node2 = nodepairs[n].node2;
5073 #ifdef BETTERWEIGHTFORDEMANDNODES 5080 SCIPdebugMsg(scip,
"nodepair [%d,%d] weight %g\n", node1,node2,nodepairs[n].weight);
5088 if( nodeflowrows[node1][k] == NULL )
5091 if( nodeflowscales[node1][k] > 0.0 )
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 SCIPdebugMsg(scip,
"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;
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 SCIPdebugMsg(scip,
"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;
5437 assert(nodepartition->nodeclusters != 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 )
5545 SCIPinfoMessage(scip, NULL,
"creating GML output file <%s>...\n", filename);
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);
5795 for( i = 0; i < cutnnz; ++i )
5797 cutvars[i] = vars[cutinds[i]];
5803 sepadata->dynamiccuts) );
5813 SCIPdebugMsg(scip,
" -> found MCF cut <%s>: rhs=%f, act=%f eff=%f rank=%d\n",
5830 if( !(*cutoff) && sepadata->separateknapsack)
5833 SCIP_CALL(
SCIPseparateRelaxedKnapsack(scip, NULL, sepa, cutnnz, cutvars, cutcoefs, +1.0, cutrhs, sol, cutoff, ncuts) );
5883 unsigned int partition;
5884 unsigned int allpartitions;
5885 unsigned int startpartition;
5899 maxsepacuts = sepadata->maxsepacutsroot;
5901 maxsepacuts = sepadata->maxsepacuts;
5902 if( maxsepacuts < 0 )
5903 maxsepacuts = INT_MAX;
5908 maxtestdelta = sepadata->maxtestdelta;
5909 if( maxtestdelta <= 0 )
5910 maxtestdelta = INT_MAX;
5946 if( nodepartition == NULL )
5950 allpartitions = (
unsigned int) nnodes;
5951 SCIPdebugMsg(scip,
"maxtestdelta: %d, maxsepacuts: %d, nnodes: %d \n", maxtestdelta, maxsepacuts, nnodes);
5958 int nclusters = nodepartition->nclusters;
5960 assert((
unsigned int)nclusters <= 8*
sizeof(
unsigned int));
5961 SCIPdebugMsg(scip,
"maxtestdelta: %d, maxsepacuts: %d, nclusters: %d \n", maxtestdelta, maxsepacuts, nclusters);
5968 allpartitions = (1 << (nclusters-1));
5972 for( partition = startpartition; partition <= allpartitions-1 && !
SCIPisStopped(scip) && *ncuts < maxsepacuts && !*cutoff; partition++ )
5987 if( sepadata->checkcutshoreconnectivity )
5994 SCIPdebugMsg(scip,
"generating cluster cuts for partition 0x%x \n", partition );
5995 SCIPdebugMsg(scip,
" -> either shore S or shore T is not connected - skip partition.\n");
6000 for( inverted =
FALSE; inverted <= useinverted && !*cutoff; inverted++ )
6003 if( nodepartition == NULL )
6005 SCIPdebugMsg(scip,
"generating single-node cuts for node %u (inverted: %u)\n", partition, inverted);
6009 SCIPdebugMsg(scip,
"generating cluster cuts for partition 0x%x (inverted: %u)\n", partition, inverted);
6013 SCIP_CALL( outputGraph(scip, mcfnetwork, nodepartition, inverted, partition) );
6031 for( v = 0; v <
nnodes; v++ )
6045 if( nodeflowrows[v][k] == NULL )
6048 if( nodeflowscales[v][k] > 0.0 )
6052 if( nodeflowinverted[v][k] )
6055 comcutdemands[k] += rhs * nodeflowscales[v][k];
6058 assert (1 <= nnodesinS && nnodesinS <= nnodes-1);
6063 if( sepadata->separatesinglenodecuts && nodepartition != NULL && (nnodesinS == 1 || nnodesinS == nnodes-1) )
6065 SCIPdebugMsg(scip,
" -> shore S or T has only one node - skip partition.\n");
6075 SCIPdebugMsg(scip,
" -> commodity %d: directed cutdemand=%g\n", k, comcutdemands[k]);
6085 SCIPdebugMsg(scip,
" -> commodity %d: undirected cutdemand=%g\n", k, comcutdemands[k]);
6090 if( k == ncommodities )
6094 for( a = 0; a <
narcs; a++ )
6103 assert(arcsources[a] < nnodes);
6104 assert(arctargets[a] < nnodes);
6110 if(
nodeInPartition(nodepartition, partition, inverted, arcsources[a]) ||
6120 if(
nodeInPartition(nodepartition, partition, inverted, arcsources[a]) &&
6126 if( !
nodeInPartition(nodepartition, partition, inverted, arcsources[a]) &&
6135 if( arccapacityrows[a] == NULL )
6143 assert(rowweights[r] == 0.0);
6149 if( arcsources[a] == -1 || arctargets[a] == -1 )
6159 assert(maxcoef > 0.0);
6164 rowweights[r] = arccapacityscales[a];
6165 SCIPdebugMsg(scip,
" -> arc %d, r=%d, capacity row <%s>: weight=%g slack=%g dual=%g\n", a, r,
SCIProwGetName(arccapacityrows[a]), rowweights[r],
6169 if( sepadata->separateflowcutset )
6171 if( rowweights[r] > 0.0 )
6181 for( j = 0; j < rowlen; j++ )
6186 coef = rowvals[j] * arccapacityscales[a];
6192 k = colcommodity[c];
6194 comdemands[k] = coef;
6208 while( left <= right )
6210 int mid = (left+right)/2;
6212 if(
REALABS( deltas[mid] / coef - 1.0 ) < 1e-03 )
6217 else if( coef < deltas[mid] )
6226 assert(right == left-1);
6227 assert(ndeltas <= deltassize);
6228 if( ndeltas == deltassize )
6233 if( left < ndeltas )
6235 for( d = ndeltas; d > left; d-- )
6236 deltas[d] = deltas[d-1];
6238 deltas[left] = coef;
6240 SCIPdebugMsg(scip,
" -> new capacity %g considered as delta\n", coef);
6247 for( v = 0; v <
nnodes; v++ )
6256 if( comdemands[k] == 0.0 )
6259 scale = comdemands[k];
6282 if( comcutdemands[k] > 0.0 )
6301 if( nodeflowrows[v][k] == NULL )
6310 assert(rowweights[r] == 0.0);
6316 rowweights[r] = scale * nodeflowscales[v][k];
6317 if( nodeflowinverted[v][k] )
6318 rowweights[r] *= -1.0;
6319 SCIPdebugMsg(scip,
" -> node %d, commodity %d, r=%d, flow row <%s>: scale=%g weight=%g slack=%g dual=%g\n",
6320 v, k, r,
SCIProwGetName(nodeflowrows[v][k]), scale, rowweights[r],
6323 if( sepadata->separateflowcutset )
6325 if( nodeflowscales[v][k] > 0.0 )
6341 if( sepadata->separateflowcutset )
6344 bestdelta = deltas[ndeltas-1];
6354 SCIPdebugMsg(scip,
" -> found %d different deltas to try\n", ndeltas);
6355 for( d = ndeltas-1; d >= 0 && d >= ndeltas-maxtestdelta; d-- )
6369 SCIPdebugMsg(scip,
"applying MIR with delta = %g\n", deltas[d]);
6370 SCIP_CALL(
SCIPcalcMIR(scip, sol,
POSTPROCESS,
BOUNDSWITCH,
USEVBDS, allowlocal, sepadata->fixintegralrhs, NULL, NULL,
MINFRAC,
MAXFRAC,
6371 1.0/deltas[d], aggrrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, &cutrank, &cutislocal, &success) );
6372 assert(allowlocal || !cutislocal);
6380 if( sepadata->separateflowcutset )
6382 if( cutefficacy > bestefficacy )
6384 bestdelta = deltas[d];
6385 bestefficacy = cutefficacy;
6391 SCIPdebugMsg(scip,
"success -> delta = %g -> rhs: %g, efficacy: %g\n", deltas[d], cutrhs, cutefficacy);
6392 SCIP_CALL(
addCut(scip, sepa, sepadata, sol, cutcoefs, cutrhs, cutinds, cutnnz, cutislocal, cutrank, ncuts, cutoff) );
6397 for( a = 0; a <
narcs; a++ )
6399 if( arccapacityrows[a] != NULL )
6405 if( r >= 0 && rowweights[r] != 0.0 )
6407 MCFdebugMessage(
" -> arc %d, capacity row <%s>: weight=%g slack=%g prod=%g dual=%g\n", a,
6420 if( sepadata->separateflowcutset && oldncuts == *ncuts && !*cutoff )
6423 f0 =
SCIPfrac(scip, baserhs/bestdelta);
6428 totalviolationdelta = 0.0;
6429 onedivoneminsf0 = 1.0/(1.0 - f0);
6430 for( a = 0; a <
narcs; a++ )
6444 if( arccapacityrows[a] == NULL )
6455 if( rowweights[r] == 0.0 )
6470 rowweight = rowweights[r]/bestdelta;
6475 violationdelta = rowweight * (rowlhs - rowconstant);
6477 violationdelta = rowweight * (rowrhs - rowconstant);
6479 for( j = 0; j < rowlen; j++ )
6487 coef = rowvals[j] * rowweight;
6498 if( colcommodity[c] >= 0 )
6509 mircoef =
SCIPfloor(scip, coef) + (fj - f0)*onedivoneminsf0;
6516 mircoef = coef * onedivoneminsf0;
6521 if( colcommodity[c] >= 0 )
6522 violationdelta += mircoef * solval;
6524 violationdelta -= mircoef * solval;
6529 SCIPdebugMsg(scip,
" -> discarding capacity row <%s> of weight %g and slack %g: increases MIR violation by %g\n",
6532 rowweights[r] = 0.0;
6533 totalviolationdelta += violationdelta;
6538 if( totalviolationdelta > 0.0 )
6551 SCIPdebugMsg(scip,
"applying MIR with delta = %g to flowcut inequality (violation improvement: %g)\n", bestdelta, totalviolationdelta);
6558 SCIP_CALL(
SCIPcalcMIR(scip, sol,
POSTPROCESS,
BOUNDSWITCH,
USEVBDS, allowlocal, sepadata->fixintegralrhs, NULL, NULL,
MINFRAC,
MAXFRAC,
6559 1.0/bestdelta, aggrrow, cutcoefs, &cutrhs, cutinds, &cutnnz, &cutefficacy, &cutrank, &cutislocal, &success) );
6561 assert(allowlocal || !cutislocal);
6565 SCIPdebugMsg(scip,
" -> delta = %g -> rhs: %g, efficacy: %g\n", bestdelta, cutrhs, cutefficacy);
6566 SCIP_CALL(
addCut(scip, sepa, sepadata, sol, cutcoefs, cutrhs, cutinds, cutnnz, cutislocal, cutrank, ncuts, cutoff) );
6609 assert(result != NULL);
6622 if( ncols != nvars )
6624 MCFdebugMessage(
"%d variables but %d columns -> exit\n", nvars, ncols );
6637 colrowratio = (
SCIP_Real)ncols/(nrows+1e-9);
6641 assert(sepadata != NULL);
6650 if( colrowratio < MINCOLROWRATIO || colrowratio >
MAXCOLROWRATIO )
6659 if( sepadata->nmcfnetworks == -1 )
6667 for( i = 0; i < sepadata->nmcfnetworks; i++ )
6669 MCFdebugMessage(
" -> extracted network %d has %d nodes, %d (%d) arcs (uncapacitated), and %d commodities (modeltype: %s)\n",
6670 i, sepadata->mcfnetworks[i]->nnodes, sepadata->mcfnetworks[i]->narcs, sepadata->mcfnetworks[i]->nuncapacitatedarcs,
6671 sepadata->mcfnetworks[i]->ncommodities,
6673 SCIPdebug( mcfnetworkPrint(sepadata->mcfnetworks[i]) );
6676 #ifdef COUNTNETWORKVARIABLETYPES 6677 SCIP_CALL( printFlowSystemInfo(scip,sepadata->mcfnetworks,sepadata->nmcfnetworks));
6681 assert(sepadata->nmcfnetworks >= 0);
6682 assert(sepadata->mcfnetworks != NULL || sepadata->nmcfnetworks == 0);
6683 mcfnetworks = sepadata->mcfnetworks;
6684 nmcfnetworks = sepadata->nmcfnetworks;
6691 sepadata->lastroundsuccess =
FALSE;
6693 for( i = 0; i < nmcfnetworks && !cutoff; i++ )
6699 mcfnetwork = mcfnetworks[i];
6702 assert(mcfnetwork->
nnodes >= 2);
6703 assert(mcfnetwork->
narcs >= 1);
6710 MCFdebugMessage(
"MCF network has %d nodes and %d arcs. arc node ratio %.2f exceed --> exit\n",
6716 if( sepadata->separatesinglenodecuts )
6727 nodepartitionPrint(nodepartition);
6737 MCFdebugMessage(
"MCF network has %d nodes, %d arcs, %d commodities. Found %d MCF network cuts, cutoff = %u.\n",
6744 sepadata->lastroundsuccess =
TRUE;
6746 else if( ncuts > 0 )
6749 sepadata->lastroundsuccess =
TRUE;
6766 assert(scip != NULL);
6767 assert(sepa != NULL);
6785 assert(sepadata != NULL);
6786 assert(sepadata->mcfnetworks == NULL);
6787 assert(sepadata->nmcfnetworks == -1);
6805 assert(sepadata != NULL);
6807 sepadata->lastroundsuccess =
TRUE;
6824 assert(sepadata != NULL);
6827 for( i = 0; i < sepadata->nmcfnetworks; i++ )
6832 sepadata->nmcfnetworks = -1;
6894 sepadata->mcfnetworks = NULL;
6895 sepadata->nmcfnetworks = -1;
6897 sepadata->lastroundsuccess =
TRUE;
6903 sepaExeclpMcf, sepaExecsolMcf,
6906 assert(sepa != NULL);
6918 "separating/mcf/nclusters",
6919 "number of clusters to generate in the shrunken network -- default separation",
6922 "separating/mcf/maxweightrange",
6923 "maximal valid range max(|weights|)/min(|weights|) of row weights",
6926 "separating/mcf/maxtestdelta",
6927 "maximal number of different deltas to try (-1: unlimited) -- default separation",
6930 "separating/mcf/trynegscaling",
6931 "should negative values also be tested in scaling?",
6934 "separating/mcf/fixintegralrhs",
6935 "should an additional variable be complemented if f0 = 0?",
6938 "separating/mcf/dynamiccuts",
6939 "should generated cuts be removed from the LP if they are no longer tight?",
6942 "separating/mcf/modeltype",
6943 "model type of network (0: auto, 1:directed, 2:undirected)",
6946 "separating/mcf/maxsepacuts",
6947 "maximal number of mcf cuts separated per separation round",
6950 "separating/mcf/maxsepacutsroot",
6951 "maximal number of mcf cuts separated per separation round in the root node -- default separation",
6954 "separating/mcf/maxinconsistencyratio",
6955 "maximum inconsistency ratio for separation at all",
6958 "separating/mcf/maxarcinconsistencyratio",
6959 "maximum inconsistency ratio of arcs not to be deleted",
6962 "separating/mcf/checkcutshoreconnectivity",
6963 "should we separate only if the cuts shores are connected?",
6966 "separating/mcf/separatesinglenodecuts",
6967 "should we separate inequalities based on single-node cuts?",
6970 "separating/mcf/separateflowcutset",
6971 "should we separate flowcutset inequalities on the network cuts?",
6974 "separating/mcf/separateknapsack",
6975 "should we separate knapsack cover inequalities on the network cuts?",
enum SCIP_Result SCIP_RESULT
SCIP_ROW ** SCIPgetLPRows(SCIP *scip)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE mcfnetworkCreate(SCIP *scip, SCIP_MCFNETWORK **mcfnetwork)
#define DEFAULT_TRYNEGSCALING
void SCIPaggrRowFree(SCIP *scip, SCIP_AGGRROW **aggrrow)
static SCIP_RETCODE extractFlowRows(SCIP *scip, MCFDATA *mcfdata)
static void fixCommoditySigns(SCIP *scip, MCFDATA *mcfdata)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
SCIP_Bool ** nodeflowinverted
void SCIPsortInd(int *indarray, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
static SCIP_RETCODE nodepairqueueCreate(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPAIRQUEUE **nodepairqueue)
static SCIP_RETCODE identifySourcesTargets(SCIP *scip, MCFDATA *mcfdata, SCIP_SEPADATA *sepadata, MCFEFFORTLEVEL *effortlevel)
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
SCIP_Real * SCIPcolGetVals(SCIP_COL *col)
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_RETCODE extractFlow(SCIP *scip, MCFDATA *mcfdata, SCIP_Real maxflowvarflowrowratio, SCIP_Bool *failed)
const char * SCIProwGetName(SCIP_ROW *row)
static SCIP_RETCODE extractCapacities(SCIP *scip, MCFDATA *mcfdata)
#define SEPA_MAXBOUNDDIST
static SCIP_RETCODE identifyComponent(SCIP *scip, MCFDATA *mcfdata, int *nodevisited, int startv, int *compnodes, int *ncompnodes, int *comparcs, int *ncomparcs)
#define DEFAULT_MODELTYPE
struct nodepairqueue NODEPAIRQUEUE
int SCIProwGetNLPNonz(SCIP_ROW *row)
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
#define DEFAULT_MAXINCONSISTENCYRATIO
static SCIP_RETCODE nodepartitionCreate(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION **nodepartition, int nclusters)
static void nodepairqueueFree(SCIP *scip, NODEPAIRQUEUE **nodepairqueue)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
enum SCIP_Retcode SCIP_RETCODE
static SCIP_DECL_SORTINDCOMP(compCands)
void * SCIPpqueueFirst(SCIP_PQUEUE *pqueue)
static SCIP_DECL_HASHKEYVAL(hashKeyValNodepairs)
#define DEFAULT_FIXINTEGRALRHS
static SCIP_DECL_SORTPTRCOMP(compNodepairs)
static SCIP_RETCODE getNodeSimilarityScore(SCIP *scip, MCFDATA *mcfdata, int baserowlen, int *basearcpattern, int basenposuncap, int basenneguncap, SCIP_ROW *row, SCIP_Real *score, SCIP_Bool *invertcommodity)
#define SCIPfreeBlockMemory(scip, ptr)
#define DEFAULT_CHECKCUTSHORECONNECTIVITY
static NODEPAIRENTRY * nodepairqueueRemove(NODEPAIRQUEUE *nodepairqueue)
void SCIPpqueueFree(SCIP_PQUEUE **pqueue)
SCIP_MCFMODELTYPE modeltype
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPfreeBufferArray(scip, ptr)
static SCIP_RETCODE separateCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_Bool allowlocal, SCIP_RESULT *result)
#define SCIPallocBlockMemory(scip, ptr)
int SCIPgetNLPBranchCands(SCIP *scip)
SCIP_RETCODE SCIPgetLPColsData(SCIP *scip, SCIP_COL ***cols, int *ncols)
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
static SCIP_RETCODE mcfnetworkExtract(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_MCFNETWORK ***mcfnetworks, int *nmcfnetworks, MCFEFFORTLEVEL *effortlevel)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
SCIP_Real SCIPgetRowFeasibility(SCIP *scip, SCIP_ROW *row)
#define MAXFLOWCANDDENSITY
SCIP_Real SCIPgetRowMaxCoef(SCIP *scip, SCIP_ROW *row)
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
static SCIP_RETCODE findUncapacitatedArcs(SCIP *scip, MCFDATA *mcfdata)
#define MAXFLOWVARFLOWROWRATIO
#define DEFAULT_MAXTESTDELTA
#define DEFAULT_SEPARATEFLOWCUTSET
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
static void getIncidentNodes(SCIP *scip, MCFDATA *mcfdata, SCIP_COL *col, int *sourcenode, int *targetnode)
SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
Constraint handler for knapsack constraints of the form , x binary and .
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
static SCIP_DECL_SEPACOPY(sepaCopyMcf)
#define SCIPallocMemory(scip, ptr)
#define MAXAGGRLEN(nvars)
static void unionfindJoinSets(int *representatives, int rep1, int rep2)
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
#define DEFAULT_MAXSEPACUTSROOT
SCIP_ROW ** SCIPcolGetRows(SCIP_COL *col)
static SCIP_Bool nodeInPartition(NODEPARTITION *nodepartition, unsigned int partition, SCIP_Bool inverted, int v)
static void nodepartitionJoin(NODEPARTITION *nodepartition, int rep1, int rep2)
static SCIP_RETCODE createNewArc(SCIP *scip, MCFDATA *mcfdata, int source, int target, int *newarcid)
#define SCIPallocBuffer(scip, ptr)
SCIP_Bool SCIPisEfficacious(SCIP *scip, SCIP_Real efficacy)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
static int nodepartitionIsConnected(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION *nodepartition, unsigned int partition)
#define DEFAULT_MAXSEPACUTS
const char * SCIPvarGetName(SCIP_VAR *var)
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
SCIP_RETCODE SCIPsetSepaInitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAINITSOL((*sepainitsol)))
int SCIPgetNLPRows(SCIP *scip)
static SCIP_RETCODE cleanupNetwork(SCIP *scip, MCFDATA *mcfdata)
enum McfEffortLevel MCFEFFORTLEVEL
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPincludeSepaMcf(SCIP *scip)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
#define DEFAULT_MAXWEIGHTRANGE
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
void * SCIPpqueueRemove(SCIP_PQUEUE *pqueue)
static SCIP_RETCODE mcfnetworkFill(SCIP *scip, SCIP_MCFNETWORK *mcfnetwork, MCFDATA *mcfdata, int *compnodeid, int *compnodes, int ncompnodes, int *comparcs, int ncomparcs)
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
SCIP_RETCODE SCIPincludeSepaBasic(SCIP *scip, SCIP_SEPA **sepa, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
static void collectIncidentFlowCols(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *flowrow, int basecommodity)
SCIP_Bool SCIPsepaWasLPDelayed(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPcalcMIR(SCIP *scip, SCIP_SOL *sol, SCIP_Bool postprocess, SCIP_Real boundswitch, SCIP_Bool usevbds, SCIP_Bool allowlocal, SCIP_Bool fixintegralrhs, int *boundsfortrans, SCIP_BOUNDTYPE *boundtypesfortrans, SCIP_Real minfrac, SCIP_Real maxfrac, SCIP_Real scale, SCIP_AGGRROW *aggrrow, SCIP_Real *cutcoefs, SCIP_Real *cutrhs, int *cutinds, int *cutnnz, SCIP_Real *cutefficacy, int *cutrank, SCIP_Bool *cutislocal, SCIP_Bool *success)
#define SCIPallocBufferArray(scip, ptr, num)
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
public data structures and miscellaneous methods
struct nodepair NODEPAIRENTRY
SCIP_RETCODE SCIPsetSepaExitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAEXITSOL((*sepaexitsol)))
multi-commodity-flow network cut separator
#define DEFAULT_NCLUSTERS
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
int SCIPgetDepth(SCIP *scip)
enum SCIP_McfModeltype SCIP_MCFMODELTYPE
SCIP_RETCODE SCIPcaptureRow(SCIP *scip, SCIP_ROW *row)
static SCIP_DECL_HASHKEYEQ(hashKeyEqNodepairs)
static SCIP_DECL_SEPAEXITSOL(sepaExitsolMcf)
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
SCIP_ROW ** arccapacityrows
SCIP_RETCODE SCIPcreateEmptyRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_SEPA *sepa, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
#define SCIPreallocMemoryArray(scip, ptr, newnum)
static void deleteCommodity(SCIP *scip, MCFDATA *mcfdata, int k, SCIP_ROW **comrows, int nrows, int *ndelflowrows, int *ndelflowvars)
SCIP_COL ** SCIPgetLPCols(SCIP *scip)
#define SCIPallocMemoryArray(scip, ptr, num)
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
#define UNCAPACITATEDARCSTRESHOLD
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
int SCIProwGetRank(SCIP_ROW *row)
static void getNextFlowrow(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW **nextrow, unsigned char *nextrowsign, SCIP_Bool *nextinvertcommodity)
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
int SCIPgetNVars(SCIP *scip)
#define HASHSIZE_NODEPAIRS
static SCIP_RETCODE mcfnetworkFree(SCIP *scip, SCIP_MCFNETWORK **mcfnetwork)
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
#define DEFAULT_MAXARCINCONSISTENCYRATIO
#define SCIPfreeMemory(scip, ptr)
#define SCIPfreeBuffer(scip, ptr)
#define DEFAULT_SEPARATEKNAPSACK
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
SCIP_RETCODE SCIPaggrRowSumRows(SCIP *scip, SCIP_AGGRROW *aggrrow, SCIP_Real *weights, int *rowinds, int nrowinds, SCIP_Bool sidetypebasis, SCIP_Bool allowlocal, int negslack, int maxaggrlen, SCIP_Bool *valid)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
SCIP_RETCODE SCIPpqueueInsert(SCIP_PQUEUE *pqueue, void *elem)
static int nodepartitionGetRepresentative(NODEPARTITION *nodepartition, int v)
SCIP_RETCODE SCIPpqueueCreate(SCIP_PQUEUE **pqueue, int initsize, SCIP_Real sizefac, SCIP_DECL_SORTPTRCOMP((*ptrcomp)))
void SCIProwChgRank(SCIP_ROW *row, int rank)
#define DEFAULT_SEPARATESINGLENODECUTS
static SCIP_RETCODE addCut(SCIP *scip, SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata, SCIP_SOL *sol, SCIP_Real *cutcoefs, SCIP_Real cutrhs, int *cutinds, int cutnnz, SCIP_Bool cutislocal, int cutrank, int *ncuts, SCIP_Bool *cutoff)
SCIP_Real SCIPgetRowLPFeasibility(SCIP *scip, SCIP_ROW *row)
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
int SCIProwGetLPPos(SCIP_ROW *row)
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_Real ** nodeflowscales
static SCIP_RETCODE extractCapacityRows(SCIP *scip, MCFDATA *mcfdata)
#define MINCOMNODESFRACTION
static SCIP_DECL_SEPAEXECSOL(sepaExecsolMcf)
static void getFlowrowFit(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *row, int k, unsigned char *rowsign, SCIP_Bool *invertcommodity)
SCIP_RETCODE SCIPaggrRowCreate(SCIP *scip, SCIP_AGGRROW **aggrrow)
static SCIP_DECL_SEPAINITSOL(sepaInitsolMcf)
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
static SCIP_DECL_SEPAEXECLP(sepaExeclpMcf)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_ROW *** nodeflowrows
SCIP_Real * arccapacityscales
int SCIPgetNLPCols(SCIP *scip)
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
static SCIP_Bool nodepairqueueIsEmpty(NODEPAIRQUEUE *nodepairqueue)
#define BMSclearMemoryArray(ptr, num)
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
static void unionfindInitSets(int *representatives, int nelems)
static void invertCommodity(SCIP *scip, MCFDATA *mcfdata, int k, SCIP_ROW **comrows, int ncomrows, int *comcolids, int ncomcolids)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
#define DEFAULT_DYNAMICCUTS
static SCIP_RETCODE generateClusterCuts(SCIP *scip, SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata, SCIP_SOL *sol, SCIP_Bool allowlocal, SCIP_MCFNETWORK *mcfnetwork, NODEPARTITION *nodepartition, int *ncuts, SCIP_Bool *cutoff)
static int unionfindGetRepresentative(int *representatives, int v)
#define SCIPfreeMemoryArrayNull(scip, ptr)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
static void addFlowrowToCommodity(SCIP *scip, MCFDATA *mcfdata, SCIP_ROW *row, unsigned char rowsign, int *comcolids, int *ncomcolids)
int SCIPcolGetNLPNonz(SCIP_COL *col)
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
int SCIPcolGetLPPos(SCIP_COL *col)
static SCIP_DECL_HASHGETKEY(hashGetKeyNodepairs)
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
static SCIP_RETCODE extractNodes(SCIP *scip, MCFDATA *mcfdata)
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
struct nodepartition NODEPARTITION
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
static SCIP_DECL_SEPAFREE(sepaFreeMcf)
struct SCIP_SepaData SCIP_SEPADATA
SCIP_RETCODE SCIPseparateRelaxedKnapsack(SCIP *scip, SCIP_CONS *cons, SCIP_SEPA *sepa, int nknapvars, SCIP_VAR **knapvars, SCIP_Real *knapvals, SCIP_Real valscale, SCIP_Real rhs, SCIP_SOL *sol, SCIP_Bool *cutoff, int *ncuts)
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
static void nodepartitionFree(SCIP *scip, NODEPARTITION **nodepartition)
static SCIP_RETCODE createNewCommodity(SCIP *scip, MCFDATA *mcfdata)
#define SCIPreallocBufferArray(scip, ptr, num)