41 #define SEPA_NAME "oddcycle" 42 #define SEPA_DESC "odd cycle separator" 43 #define SEPA_PRIORITY -15000 45 #define SEPA_MAXBOUNDDIST 1.0 46 #define SEPA_USESSUBSCIP FALSE 47 #define SEPA_DELAY FALSE 51 #define DEFAULT_SCALEFACTOR 1000 52 #define DEFAULT_USEGLS TRUE 53 #define DEFAULT_LIFTODDCYCLES FALSE 54 #define DEFAULT_REPAIRCYCLES TRUE 55 #define DEFAULT_ADDSELFARCS TRUE 56 #define DEFAULT_INCLUDETRIANGLES TRUE 57 #define DEFAULT_MULTIPLECUTS FALSE 58 #define DEFAULT_ALLOWMULTIPLECUTS TRUE 59 #define DEFAULT_LPLIFTCOEF FALSE 61 #define DEFAULT_RECALCLIFTCOEF TRUE 62 #define DEFAULT_MAXSEPACUTS 5000 63 #define DEFAULT_MAXSEPACUTSROOT 5000 64 #define DEFAULT_PERCENTTESTVARS 0 65 #define DEFAULT_OFFSETTESTVARS 100 66 #define DEFAULT_MAXCUTSROOT 1 67 #define DEFAULT_SORTSWITCH 3 68 #define DEFAULT_MAXREFERENCE 0 69 #define DEFAULT_MAXROUNDS 10 70 #define DEFAULT_MAXROUNDSROOT 10 71 #define DEFAULT_MAXNLEVELS 20 72 #define DEFAULT_MAXPERNODESLEVEL 100 73 #define DEFAULT_OFFSETNODESLEVEL 10 74 #define DEFAULT_SORTROOTNEIGHBORS TRUE 75 #define DEFAULT_MAXCUTSLEVEL 50 76 #define DEFAULT_MAXUNSUCESSFULL 3 77 #define DEFAULT_CUTTHRESHOLD -1 101 unsigned int maxnodes;
102 unsigned int maxarcs;
103 unsigned int nlevels;
111 unsigned int* weightForward;
112 unsigned int* weightBackward;
113 unsigned int sizeForward;
114 unsigned int sizeBackward;
117 unsigned int* sourceAdj;
118 unsigned int* targetAdj;
119 unsigned int* weightAdj;
120 unsigned int* levelAdj;
121 unsigned int sizeAdj;
124 typedef struct levelGraph LEVELGRAPH;
148 LEVELGRAPH* levelgraph;
158 unsigned int oldncuts;
170 unsigned int* mapping;
176 int maxsepacutsround;
182 int maxpernodeslevel;
183 int offsetnodeslevel;
184 unsigned int maxlevelsize;
211 unsigned int nbinvars,
212 unsigned int startnode
215 unsigned int varsindex;
216 unsigned int counter;
218 assert(vars !=
NULL);
219 assert(pred !=
NULL);
220 assert(nbinvars > 0);
221 assert(startnode < 4*nbinvars);
224 varsindex = startnode;
227 if( varsindex < nbinvars || ( varsindex >= 2*nbinvars && varsindex < 3*nbinvars ) )
237 for( varsindex = pred[startnode]; varsindex != startnode; varsindex = pred[varsindex] )
239 if( varsindex < nbinvars || ( varsindex >= 2*nbinvars && varsindex < 3*nbinvars ) )
251 if( varsindex < nbinvars || ( varsindex >= 2*nbinvars && varsindex < 3*nbinvars ) )
276 unsigned int nbinvars,
284 assert(vars !=
NULL);
285 assert(nbinvars > 2);
286 assert(graphdata !=
NULL);
289 assert(a < 2*nbinvars);
290 assert(b < 2*nbinvars);
297 if( dijkstragraph->
outcnt[a] == 0 || dijkstragraph->
outcnt[b] == 0 )
301 for( i = dijkstragraph->
outbeg[a]; i < dijkstragraph->outbeg[a] + dijkstragraph->
outcnt[a]; ++i )
303 if( dijkstragraph->
head[i] == b + 2*nbinvars )
309 LEVELGRAPH* levelgraph = graphdata->
levelgraph;
312 if( (levelgraph->beginForward[a] != -1 || levelgraph->beginBackward[a] != -1)
313 && (levelgraph->beginForward[b] != -1 || levelgraph->beginBackward[b] != -1) )
315 assert(levelgraph->level[a] <= levelgraph->nlevels);
316 assert(levelgraph->level[b] <= levelgraph->nlevels);
319 if( levelgraph->level[a] > levelgraph->level[b] + 1
320 || levelgraph->level[b] > levelgraph->level[a] + 1 )
323 assert(levelgraph->level[a] == levelgraph->level[b]
324 || levelgraph->level[a]+1 == levelgraph->level[b]
325 || levelgraph->level[a] == levelgraph->level[b]+1);
328 if( levelgraph->level[a] == levelgraph->level[b]+1 )
330 if( levelgraph->beginBackward[a] >= 0 )
332 i = (
unsigned int) levelgraph->beginBackward[a];
333 while( levelgraph->targetBackward[i] != -1 )
335 if( levelgraph->targetBackward[i] == (
int)b )
341 else if( levelgraph->level[a] == levelgraph->level[b]-1 )
343 if( levelgraph->beginForward[a] >= 0 )
345 i = (
unsigned int) levelgraph->beginForward[a];
346 while( levelgraph->targetForward[i] != -1 )
348 if( levelgraph->targetForward[i] == (
int)b )
356 assert(levelgraph->level[a] == levelgraph->level[b]);
357 assert(levelgraph->level[a] > 0);
359 if( a < b && levelgraph->beginAdj[a] >= 0 )
361 i = (
unsigned int) levelgraph->beginAdj[a];
362 assert(i >= levelgraph->levelAdj[levelgraph->level[a]]);
364 while( i < levelgraph->levelAdj[levelgraph->level[a]+1] && levelgraph->sourceAdj[i] == a )
366 if( levelgraph->targetAdj[i] == b )
370 if( levelgraph->sourceAdj[i] == 0 && levelgraph->targetAdj[i] == 0 )
373 assert(levelgraph->sourceAdj[i] < levelgraph->targetAdj[i]);
377 if( b < a && levelgraph->beginAdj[b] >= 0 )
379 i = (
unsigned int) levelgraph->beginAdj[b];
380 assert(i >= levelgraph->levelAdj[levelgraph->level[b]]);
382 while( i < levelgraph->levelAdj[levelgraph->level[b]+1] && levelgraph->sourceAdj[i] == b )
384 if( levelgraph->targetAdj[i] == a )
388 if( levelgraph->sourceAdj[i] == 0 && levelgraph->targetAdj[i] == 0 )
391 assert(levelgraph->sourceAdj[i] < levelgraph->targetAdj[i]);
407 unsigned int ncliques;
408 unsigned int ncliquevars;
418 assert(a < nbinvars);
426 assert(b < nbinvars);
440 varfixingtemp = originalb;
442 originalb = originala;
444 originala = varfixingtemp;
451 assert(cliques !=
NULL || ncliques == 0);
453 for( i = 0; i < ncliques; ++i )
455 assert( cliques !=
NULL );
460 assert(cliquevars !=
NULL || ncliquevars == 0);
461 assert(cliquevals !=
NULL || ncliquevars == 0);
463 for( j = 0; j < ncliquevars; ++j )
465 assert( cliquevals !=
NULL && cliquevars !=
NULL );
468 if( (cliquevals[j] ==
FALSE && originalb ==
TRUE) || ( cliquevals[j] ==
TRUE && originalb ==
FALSE ) )
493 unsigned int ncyclevars,
495 unsigned int nbinvars,
496 unsigned int* lifted,
497 unsigned int* nlifted,
504 assert(a < ncyclevars);
505 assert(b < ncyclevars);
506 assert(c < ncyclevars);
507 assert(cycle !=
NULL);
508 assert(ncyclevars % 2 == 1);
509 assert(ncyclevars > 2);
510 assert(ncyclevars <= nbinvars);
511 assert(vars !=
NULL);
512 assert(nbinvars > 2);
513 assert(lifted !=
NULL);
514 assert(nlifted !=
NULL);
518 while( (myi[a] || myi[b] || myi[c]) && k < *nlifted )
522 if( !
isNeighbor(vars, nbinvars, graphdata, i, lifted[k])
523 &&
isNeighbor(vars, nbinvars, graphdata, cycle[a], lifted[k])
524 &&
isNeighbor(vars, nbinvars, graphdata, cycle[b], lifted[k])
525 &&
isNeighbor(vars, nbinvars, graphdata, cycle[c], lifted[k]) )
544 unsigned int ncyclevars,
546 unsigned int nbinvars,
547 unsigned int* lifted,
548 unsigned int* nlifted,
558 assert(scip !=
NULL);
559 assert(i < 2*nbinvars);
560 assert(cycle !=
NULL);
561 assert(ncyclevars % 2 == 1);
562 assert(ncyclevars > 2);
563 assert(ncyclevars <= 2*nbinvars);
564 assert(vars !=
NULL);
565 assert(nbinvars > 2);
566 assert(nlifted !=
NULL);
567 assert(lifted !=
NULL);
572 for( j = 1; j < (int)ncyclevars-1; ++j )
574 myi[j] =
isNeighbor(vars, nbinvars, graphdata, i, cycle[j-1]) &&
isNeighbor(vars, nbinvars, graphdata, i, cycle[j])
575 &&
isNeighbor(vars, nbinvars, graphdata, i, cycle[j+1]);
579 myi[0] =
isNeighbor(vars, nbinvars, graphdata, i, cycle[ncyclevars-1])
580 &&
isNeighbor(vars, nbinvars, graphdata, i, cycle[0])
581 &&
isNeighbor(vars, nbinvars, graphdata, i, cycle[1]);
582 myi[ncyclevars-1] =
isNeighbor(vars, nbinvars, graphdata, i, cycle[ncyclevars-2])
583 &&
isNeighbor(vars, nbinvars, graphdata, i, cycle[ncyclevars-1])
584 &&
isNeighbor(vars, nbinvars, graphdata, i, cycle[0]);
589 for( j = 1; j < (int)ncyclevars-1; ++j )
591 checkBlocking((
unsigned int) (j-1), (
unsigned int) j, (
unsigned int) (j+1), i, cycle, ncyclevars, vars, nbinvars, lifted, nlifted, graphdata, myi);
593 checkBlocking(ncyclevars-2, ncyclevars-1, 0, i, cycle, ncyclevars, vars, nbinvars, lifted, nlifted, graphdata, myi);
594 checkBlocking(ncyclevars-1, 0, 1, i, cycle, ncyclevars, vars, nbinvars, lifted, nlifted, graphdata, myi);
604 while( myi[end] && end > 0 )
609 assert(k == ncyclevars || end > 0);
614 assert(ncyclevars % 2 == 1);
615 coef = (ncyclevars-1)/2;
623 coef = (
unsigned int)
SCIPfloor(scip,(k+1.0)/2.0);
624 assert(coef <= (ncyclevars-1)/2);
633 while( j < (
int)end )
636 while( j<(
int)end && ! myi[j] )
640 while( j<(
int)end && myi[j] )
649 coef += (
unsigned int)
SCIPfloor(scip,(k+1.0)/2.0);
650 assert(coef <= (ncyclevars-1)/2);
679 unsigned int* nlifted,
680 unsigned int* lifted,
681 unsigned int* liftcoef,
685 unsigned int nbinvars,
686 unsigned int startnode,
688 unsigned int ncyclevars,
698 unsigned int negated;
700 unsigned int liftround;
703 assert(scip !=
NULL);
704 assert(graphdata !=
NULL);
707 assert(vars !=
NULL);
708 assert(nbinvars > 2);
709 assert(startnode < 2*nbinvars);
710 assert(pred !=
NULL);
711 assert(ncyclevars % 2 == 1);
712 assert(ncyclevars > 2);
713 assert(ncyclevars <= nbinvars);
714 assert(result !=
NULL);
715 assert(nlifted !=
NULL);
716 assert(lifted !=
NULL);
717 assert(liftcoef !=
NULL);
723 cycle[0] = startnode;
726 while( i != startnode )
732 assert(j == ncyclevars);
747 for( i = 0; i < 2*nbinvars; ++i )
751 for( i = 0; i < ncyclevars; ++i )
753 candList[cycle[i]] =
FALSE;
754 if( cycle[i] >= nbinvars )
755 negated = cycle[i] - nbinvars;
757 negated = cycle[i] + nbinvars;
758 assert(negated < 2*nbinvars);
759 candList[negated] =
FALSE;
768 while( bestcand >= 0 )
771 if( sepadata->recalcliftcoef || liftround == 0 )
773 for( i = 0; i < 2*nbinvars; ++i )
777 coef[i] =
getCoef(scip, i, cycle, ncyclevars, vars, nbinvars, lifted, nlifted, graphdata, myi);
778 assert(coef[i] <= (ncyclevars-1)/2);
786 for( i = 0; i < 2*nbinvars; ++i )
791 if( sepadata->lpliftcoef )
793 if( bestcand < 0 || coef[i]*vals[i] > coef[bestcand]*vals[bestcand] )
799 if( bestcand < 0 || coef[i] > coef[bestcand] )
808 if( !(sepadata->recalcliftcoef) )
809 coef[i] =
getCoef(scip, (
unsigned int) bestcand, cycle, ncyclevars, vars, nbinvars, lifted, nlifted, graphdata, myi);
810 assert(coef[bestcand] <= (ncyclevars-1)/2);
811 candList[bestcand] =
FALSE;
812 if( coef[bestcand] > 0 )
814 if( bestcand >= (
int)nbinvars )
815 negated = (
unsigned int) bestcand - nbinvars;
817 negated = (
unsigned int) bestcand + nbinvars;
818 assert(negated < 2*nbinvars);
820 candList[negated] =
FALSE;
822 assert(*nlifted < nbinvars-ncyclevars);
823 lifted[*nlifted] = (
unsigned int) bestcand;
824 liftcoef[*nlifted] = coef[bestcand];
854 unsigned int nbinvars,
855 unsigned int startnode,
857 unsigned int ncyclevars,
866 unsigned int negatedcount;
867 unsigned int negated;
870 unsigned int nlifted;
871 unsigned int* lifted;
872 unsigned int* liftcoef;
878 assert(scip !=
NULL);
879 assert(vars !=
NULL);
880 assert(startnode < 2*nbinvars);
881 assert(pred !=
NULL);
882 assert(ncyclevars % 2 == 1);
883 assert(ncyclevars <= nbinvars);
884 assert(incut !=
NULL);
885 assert(graphdata !=
NULL);
888 assert(result !=
NULL);
892 printCycle(vars, pred, nbinvars, startnode);
900 if( startnode < nbinvars )
906 negated = startnode - nbinvars;
907 assert(negated < nbinvars);
915 if( ncyclevars < 5 && ! sepadata->includetriangles )
925 if( sepadata->liftoddcycles )
929 SCIP_CALL(
liftOddCycleCut(scip, &nlifted, lifted, liftcoef, sepadata, graphdata, vars, nbinvars, startnode, pred, ncyclevars, vals, result) );
941 while( i != startnode )
943 assert(i < 2*nbinvars);
952 negated = i - nbinvars;
953 assert(negated < nbinvars);
958 incut[negated] =
TRUE;
964 if( startnode < nbinvars )
972 negated = startnode - nbinvars;
973 assert(negated < nbinvars);
978 incut[negated] =
TRUE;
982 for( i = 0; i < nlifted; ++i)
984 assert(lifted !=
NULL);
985 assert(liftcoef !=
NULL);
986 if( lifted[i] < nbinvars )
988 assert(vars[lifted[i]] !=
NULL);
993 negated = lifted[i] - nbinvars;
994 assert(negated < nbinvars);
995 assert(vars[negated] !=
NULL);
997 negatedcount += liftcoef[i];
1016 ++sepadata->nliftedcuts;
1036 if( sepadata->liftoddcycles )
1053 unsigned int* incut,
1055 unsigned int startnode,
1056 unsigned int nbinvars,
1057 unsigned int* ncyclevars,
1065 assert(scip !=
NULL);
1066 assert(pred !=
NULL);
1067 assert(incycle !=
NULL);
1068 assert(incut !=
NULL);
1069 assert(ncyclevars !=
NULL);
1070 assert(*ncyclevars <= nbinvars);
1071 assert(success !=
NULL);
1074 assert(x < 2*nbinvars);
1077 if( incut[x] && !allowmultiplecuts )
1085 negx = x + nbinvars;
1087 negx = x - nbinvars;
1088 assert(negx < 2*nbinvars);
1093 if( incycle[x] || (incycle[negx] && !repaircycles) )
1100 if( !incycle[negx] )
1102 assert(!incycle[x]);
1126 if( negx == startnode )
1136 if( pred[negx] == x )
1142 while( pred[a] != negx )
1155 unsigned int* chain;
1156 unsigned int nchain;
1165 while( pred[a] != negx )
1183 pred[a] = chain[nchain-1];
1189 for( i = nchain-1; i > 0; --i )
1190 pred[chain[i]] = chain[i-1];
1197 assert(!incycle[x] && incycle[negx]);
1198 incycle[negx] =
FALSE;
1222 unsigned int** weightArray,
1223 unsigned int** sourceAdjArray,
1224 unsigned int** targetAdjArray,
1229 unsigned int additional;
1231 assert(scip !=
NULL);
1232 assert(graph !=
NULL);
1233 assert(size !=
NULL);
1234 assert(targetArray !=
NULL || (sourceAdjArray !=
NULL && targetAdjArray !=
NULL));
1235 assert(weightArray !=
NULL);
1236 assert(success !=
NULL);
1240 additional =
MIN(graph->maxarcs + graph->maxnodes - *size, *size) * ((int)
sizeof(**weightArray));
1241 if( targetArray !=
NULL )
1243 additional +=
MIN(graph->maxarcs + graph->maxnodes - *size, *size) * ((int)
sizeof(**targetArray));
1247 additional +=
MIN(graph->maxarcs + graph->maxnodes - *size, *size) * ((int)
sizeof(**sourceAdjArray));
1248 additional +=
MIN(graph->maxarcs + graph->maxnodes - *size, *size) * ((int)
sizeof(**targetAdjArray));
1260 if( memorylimit <= additional/1048576.0 ||
SCIPisStopped(scip) )
1267 *size = 2 * (*size);
1270 if( targetArray !=
NULL )
1308 unsigned int weight,
1314 if( graph->level[v] == level+1 )
1316 graph->targetForward[graph->lastF] = (int) v;
1317 graph->weightForward[graph->lastF] = weight;
1320 if( graph->lastF == graph->sizeForward )
1323 &(graph->weightForward),
NULL,
NULL, success) );
1330 assert(graph->level[v] == level || graph->level[v] == level-1);
1333 if( graph->level[v] == level-1 )
1335 graph->targetBackward[graph->lastB] = (int) v;
1336 graph->weightBackward[graph->lastB] = weight;
1340 if( graph->lastB == graph->sizeBackward )
1343 &(graph->weightBackward),
NULL,
NULL, success) );
1350 assert(graph->level[v] == level);
1355 graph->sourceAdj[graph->levelAdj[level+1]+*nAdj] = u;
1356 graph->targetAdj[graph->levelAdj[level+1]+*nAdj] = v;
1357 graph->weightAdj[graph->levelAdj[level+1]+*nAdj] = weight;
1361 if( graph->levelAdj[level+1]+*nAdj == graph->sizeAdj )
1364 &(graph->sourceAdj), &(graph->targetAdj), success) );
1388 unsigned int* newlevel,
1389 unsigned int* nnewlevel,
1395 unsigned int ncliques;
1396 unsigned int nbinvars;
1397 unsigned int varsidx;
1399 unsigned int ncliquevars;
1405 assert(scip !=
NULL);
1406 assert(vars !=
NULL);
1407 assert(vals !=
NULL);
1408 assert(graph !=
NULL);
1409 assert(graph->targetForward !=
NULL);
1410 assert(graph->weightForward !=
NULL);
1411 assert(graph->targetBackward !=
NULL);
1412 assert(graph->weightBackward !=
NULL);
1413 assert(graph->sourceAdj !=
NULL);
1414 assert(graph->targetAdj !=
NULL);
1415 assert(graph->weightAdj !=
NULL);
1416 assert(inlevelgraph !=
NULL);
1417 assert(newlevel !=
NULL);
1418 assert(nnewlevel !=
NULL);
1419 assert(nAdj !=
NULL);
1420 assert(success !=
NULL);
1422 assert(u < graph->maxnodes);
1424 nbinvars = (graph->maxnodes)/2;
1436 varsidx = u - nbinvars;
1438 assert(varsidx < nbinvars);
1447 assert(cliques !=
NULL);
1449 for( j = 0; j < ncliques; ++j )
1455 assert(cliquevars !=
NULL || ncliquevars == 0);
1456 assert(cliquevals !=
NULL || ncliquevars == 0);
1458 for( k = 0; k < ncliquevars; ++k )
1462 unsigned int weight;
1464 assert( cliquevars !=
NULL && cliquevals !=
NULL );
1467 assert(l < nbinvars);
1474 if( cliquevals[k] ==
FALSE )
1479 assert(v < graph->maxnodes);
1486 if( !inlevelgraph[v] && (*nnewlevel) <= sepadata->maxlevelsize )
1489 graph->level[v] = level+1;
1490 inlevelgraph[v] =
TRUE;
1491 newlevel[*nnewlevel] = v;
1494 assert(*nnewlevel > sepadata->maxlevelsize || inlevelgraph[v]);
1497 if( inlevelgraph[v] && (graph->level[v] == level+1 || graph->level[v] == level || graph->level[v] == level-1))
1506 tmp = (int)
SCIPfeasCeil(scip, sepadata->scale * (1 - vals[varsidx] - vals[v]));
1507 weight = (
unsigned int)
MAX(tmp, sepadata->maxreference);
1512 tmp = (int)
SCIPfeasCeil(scip, sepadata->scale * (1.0 - (1.0 - vals[varsidx]) - vals[v]));
1513 weight = (
unsigned int)
MAX(tmp, sepadata->maxreference);
1547 unsigned int nbinvars,
1548 unsigned int ncurlevel,
1553 unsigned int* nnewlevel,
1556 unsigned int* newlevel,
1562 unsigned int nneighbors;
1568 unsigned int varsidx;
1571 unsigned int ncliques;
1573 unsigned int ncliquevars;
1585 nbinvars = (graph->maxnodes)/2;
1587 assert(ncurlevel == 1);
1591 if( root < nbinvars )
1600 varsidx = root - nbinvars;
1602 assert(varsidx < nbinvars);
1611 assert(cliques !=
NULL);
1613 for( j = 0; j < ncliques; ++j )
1619 assert(cliquevars !=
NULL || ncliquevars == 0);
1620 assert(cliquevals !=
NULL || ncliquevars == 0);
1622 for( k = 0; k < ncliquevars; ++k )
1626 assert( cliquevars !=
NULL && cliquevals !=
NULL );
1629 assert(kidx < nbinvars);
1632 if( kidx == varsidx )
1639 if( cliquevals[k] ==
TRUE )
1641 if ( ! isneighbor[kidx] )
1644 isneighbor[kidx] =
TRUE;
1649 assert(cliquevals[k] ==
FALSE);
1650 if ( ! isneighbor[kidx + nbinvars] )
1653 isneighbor[kidx+nbinvars] =
TRUE;
1661 assert(! isneighbor[root]);
1668 for( j = 0; j < graph->maxnodes; ++j )
1675 neighbors[k] = (int) j;
1676 sortvals[k] =
MIN(1.0 - vals[j], vals[j]);
1680 assert(k == nneighbors);
1689 for( j = 0; j < nneighbors && (*nnewlevel) <= sepadata->maxlevelsize; ++j )
1693 v = (
unsigned int) neighbors[j];
1694 assert( v < 2 * nbinvars );
1697 assert(! inlevelgraph[v] || v == root+nbinvars || v == root-nbinvars);
1701 graph->level[v] = level + 1;
1702 inlevelgraph[v] =
TRUE;
1703 newlevel[*nnewlevel] = v;
1709 graph->targetForward[graph->lastF] = (int) v;
1713 tmp = (int)
SCIPfeasCeil(scip, sepadata->scale * (1.0 - vals[varsidx] - vals[v]));
1714 graph->weightForward[graph->lastF] = (
unsigned int)
MAX(tmp, sepadata->maxreference);
1718 assert( ! varfixing );
1719 tmp = (int)
SCIPfeasCeil(scip, sepadata->scale * (1.0 - (1.0 - vals[varsidx]) - vals[v]));
1720 graph->weightForward[graph->lastF] = (
unsigned int)
MAX(tmp, sepadata->maxreference);
1724 if( graph->lastF == graph->sizeForward )
1727 &(graph->weightForward),
NULL,
NULL, success) );
1751 unsigned int startnode,
1752 unsigned int* distance,
1753 unsigned int* queue,
1765 assert(scip !=
NULL);
1766 assert(graph !=
NULL);
1767 assert(graph->beginBackward !=
NULL);
1768 assert(graph->targetBackward !=
NULL);
1769 assert(graph->weightBackward !=
NULL);
1770 assert(distance !=
NULL);
1771 assert(queue !=
NULL);
1772 assert(inQueue !=
NULL);
1773 assert(parentTree !=
NULL);
1776 for( i = 0; i < graph->maxnodes; ++i )
1778 distance[i] = 2*(graph->nnodes)*scale;
1782 distance[startnode] = 0;
1787 queue[0] = startnode;
1790 while( startQueue <= endQueue )
1793 u = queue[startQueue];
1797 assert(graph->beginBackward[u] >= 0);
1798 i = (
unsigned int) graph->beginBackward[u];
1799 for( v = graph->targetBackward[i]; v >= 0; v = graph->targetBackward[++i] )
1802 d = distance[u] + graph->weightBackward[i];
1805 if( d < distance[v] )
1808 parentTree[v] = (int) u;
1814 queue[endQueue] = (
unsigned int) v;
1821 assert(parentTree[u] != -1);
1840 unsigned int startnode,
1851 assert(scip !=
NULL);
1852 assert(graph !=
NULL);
1853 assert(graph->level !=
NULL);
1854 assert(graph->beginForward !=
NULL);
1855 assert(graph->targetForward !=
NULL);
1856 assert(graph->beginBackward !=
NULL);
1857 assert(graph->targetBackward !=
NULL);
1858 assert(graph->sourceAdj !=
NULL);
1859 assert(graph->targetAdj !=
NULL);
1860 assert(inlevelgraph !=
NULL);
1861 assert(blocked !=
NULL);
1862 assert(parentTree !=
NULL);
1864 assert(parentTree[root] >= 0);
1867 u = (
unsigned int) parentTree[root];
1868 while( u != startnode )
1871 i = (
unsigned int) graph->beginForward[u];
1872 for( v = graph->targetForward[i]; v >= 0; v = graph->targetForward[++i] )
1874 assert(inlevelgraph[v]);
1879 i = (
unsigned int) graph->beginBackward[u];
1880 for( v = graph->targetBackward[i]; v >= 0; v = graph->targetBackward[++i] )
1882 assert(inlevelgraph[v]);
1887 assert(graph->level[u] > 0);
1888 for( i = graph->levelAdj[graph->level[u]]; i < graph->levelAdj[graph->level[u]+1]; ++i )
1890 assert(graph->sourceAdj[i] < graph->targetAdj[i]);
1891 assert(graph->level[graph->sourceAdj[i]] == graph->level[graph->targetAdj[i]]);
1894 if( graph->sourceAdj[i] == u )
1896 blocked[graph->targetAdj[i]] =
TRUE;
1898 if( graph->targetAdj[i] == u )
1900 blocked[graph->sourceAdj[i]] =
TRUE;
1905 u = (
unsigned int) parentTree[u];
1907 assert(u == startnode);
1910 assert(graph->beginBackward[u] > 0);
1911 i = (
unsigned int) graph->beginBackward[u];
1912 for( v = graph->targetBackward[i]; v >= 0; v = graph->targetBackward[++i] )
1930 unsigned int startnode,
1931 unsigned int* distance,
1932 unsigned int* queue,
1934 int* parentTreeBackward,
1948 assert(scip !=
NULL);
1949 assert(graph !=
NULL);
1950 assert(graph->beginBackward !=
NULL);
1951 assert(graph->targetBackward !=
NULL);
1952 assert(graph->weightBackward !=
NULL);
1953 assert(distance !=
NULL);
1954 assert(queue !=
NULL);
1955 assert(inQueue !=
NULL);
1961 assert(parentTree !=
NULL);
1962 assert(transform !=
NULL);
1965 for( i = 0; i < graph->maxnodes; ++i )
1967 distance[i] = 2*(graph->nnodes)*scale;
1969 parentTreeBackward[i] = -1;
1973 distance[startnode] = 0;
1978 queue[0] = startnode;
1981 while( startQueue <= endQueue )
1984 u = queue[startQueue];
1988 assert(graph->beginBackward[u] >= 0);
1989 i = (
unsigned int) graph->beginBackward[u];
1990 for( v = graph->targetBackward[i]; v >= 0; v = graph->targetBackward[++i] )
1992 if( blocked[v] && v != (
int) root)
1996 d = distance[u] + graph->weightBackward[i];
1999 if( d < distance[v] )
2002 parentTree[v] = (int) u;
2008 queue[endQueue] = (
unsigned int) v;
2018 transform[0] = (int) root;
2020 while(parentTree[v] >= 0)
2022 transform[i] = parentTree[v];
2029 parentTreeBackward[transform[i]] = transform[i-1];
2053 unsigned int* curlevel,
2054 unsigned int ncurlevel,
2055 unsigned int* newlevel,
2056 unsigned int* nnewlevel,
2061 unsigned int nbinvars;
2064 assert(scip !=
NULL);
2065 assert(vars !=
NULL);
2066 assert(vals !=
NULL);
2067 assert(graph !=
NULL);
2068 assert(graph->level !=
NULL);
2069 assert(graph->beginForward !=
NULL);
2070 assert(graph->targetForward !=
NULL);
2071 assert(graph->weightForward !=
NULL);
2072 assert(graph->beginBackward !=
NULL);
2073 assert(graph->targetBackward !=
NULL);
2074 assert(graph->weightBackward !=
NULL);
2075 assert(graph->beginAdj !=
NULL);
2076 assert(graph->levelAdj !=
NULL);
2077 assert(graph->sourceAdj !=
NULL);
2078 assert(graph->targetAdj !=
NULL);
2079 assert(graph->weightAdj !=
NULL);
2080 assert(inlevelgraph !=
NULL);
2081 assert(curlevel !=
NULL);
2082 assert(newlevel !=
NULL);
2083 assert(success !=
NULL);
2087 assert(graph->maxnodes % 2 == 0);
2088 nbinvars = (graph->maxnodes)/2;
2093 for( i = 0; i < ncurlevel; ++i )
2095 unsigned int negated;
2100 assert(u < graph->maxnodes);
2101 assert(graph->level[u] == level);
2102 assert(graph->beginForward[u] < 0);
2103 assert(graph->beginBackward[u] < 0);
2104 assert(graph->beginAdj[u] < 0);
2105 assert(inlevelgraph[u]);
2109 negated = u + nbinvars;
2111 negated = u - nbinvars;
2112 assert(negated < graph->maxnodes);
2113 assert(negated < nbinvars || u < nbinvars);
2114 assert(negated >= nbinvars || u >= nbinvars);
2117 graph->beginForward[u] = (int) graph->lastF;
2118 graph->beginBackward[u] = (
int) graph->lastB;
2119 graph->beginAdj[u] = (int) (graph->levelAdj[level+1] + nAdj);
2122 if( sepadata->addselfarcs )
2129 if( !inlevelgraph[negated] && (*nnewlevel) <= sepadata->maxlevelsize )
2132 graph->level[negated] = level+1;
2133 inlevelgraph[negated] =
TRUE;
2134 newlevel[*nnewlevel] = negated;
2137 assert( *nnewlevel > sepadata->maxlevelsize || inlevelgraph[negated] );
2140 if( inlevelgraph[negated] && ((graph->level[negated] == level - 1)
2141 || (graph->level[negated] == level) || (graph->level[negated] == level + 1)) )
2144 SCIP_CALL(
addArc(scip, graph, u, negated, level, 0, &nAdj, success) );
2151 if( graph->nlevels == 0 && sepadata->sortrootneighbors )
2154 sepadata, nnewlevel, inlevelgraph, level, newlevel, success) );
2159 newlevel, nnewlevel, &nAdj, success) );
2165 assert(graph->lastB > (
unsigned int) graph->beginBackward[u] || graph->nlevels == 0 );
2168 assert(graph->lastF > 0);
2171 graph->targetForward[graph->lastF] = -1;
2173 if( graph->lastF == graph->sizeForward )
2176 &(graph->weightForward),
NULL,
NULL, success) );
2181 graph->targetBackward[graph->lastB] = -1;
2183 if( graph->lastB == graph->sizeBackward )
2186 &(graph->weightBackward),
NULL,
NULL, success) );
2193 graph->sourceAdj[graph->levelAdj[level+1]+nAdj] = 0;
2194 graph->targetAdj[graph->levelAdj[level+1]+nAdj] = 0;
2196 graph->levelAdj[level+2] = graph->levelAdj[level+1]+nAdj;
2234 unsigned int nbinvars;
2235 unsigned int* incut;
2239 unsigned int* curlevel;
2240 unsigned int* newlevel;
2241 unsigned int ncurlevel;
2242 unsigned int nnewlevel;
2246 unsigned int* queue;
2249 int* parentTreeBackward;
2250 unsigned int* distance;
2254 unsigned int maxroots;
2255 unsigned int rootcounter;
2256 unsigned int ncutsroot;
2257 unsigned int ncutslevel;
2269 assert(scip !=
NULL);
2270 assert(sepadata !=
NULL);
2271 assert(result !=
NULL);
2274 assert(nscipbinvars >= 0);
2275 assert(nscipintvars >= 0);
2276 assert(nscipimplvars >= 0);
2278 nintegral = nscipbinvars + nscipintvars + nscipimplvars;
2279 assert(scipvars !=
NULL || ((nscipbinvars == 0) && (nscipintvars == 0) && (nscipimplvars == 0) && (nintegral == 0)));
2283 for (l = 0; l < nscipbinvars; ++l)
2284 vars[l] = scipvars[l];
2286 nbinvars = (
unsigned int) nscipbinvars;
2287 for (l = nscipbinvars; l < nintegral; ++l)
2291 vars[nbinvars++] = scipvars[l];
2304 assert( vars !=
NULL );
2305 switch( sepadata->sortswitch )
2313 for( i = 0; i < nbinvars; ++i )
2322 for( i = 0; i < nbinvars; ++i )
2331 for( i = 0; i < nbinvars; ++i )
2334 vals[i] =
MIN(1.0 - vals[i], vals[i]);
2343 for( i = 0; i < nbinvars; ++i )
2346 vals[i] =
MIN(1.0 - vals[i], vals[i]);
2358 assert(vars !=
NULL);
2364 for( i = 0; i < nbinvars; ++i )
2371 for( i = nbinvars; i < 2*nbinvars; ++i )
2372 vals[i] = 1.0 - vals[i - nbinvars];
2375 graph.maxnodes = 2 * nbinvars;
2381 graph.maxarcs = UINT_MAX;
2384 graph.sizeForward = 100 * graph.maxnodes;
2385 graph.sizeBackward = 100 * graph.maxnodes;
2386 graph.sizeAdj = 100 * graph.maxnodes;
2419 maxroots = (
unsigned int)
SCIPceil(scip, sepadata->offsettestvars + (0.02 * nbinvars * sepadata->percenttestvars));
2420 sepadata->maxlevelsize = (
unsigned int)
SCIPceil(scip, sepadata->offsetnodeslevel + 0.01 * sepadata->maxpernodeslevel * graph.maxnodes);
2424 for( i = (
unsigned int) sepadata->lastroot; i < graph.maxnodes && rootcounter < maxroots
2425 && sepadata->ncuts - sepadata->oldncuts < (
unsigned int) sepadata->maxsepacutsround
2430 if( incut[i] && ! sepadata->multiplecuts )
2463 for( j = 0; j < graph.maxnodes; ++j)
2465 graph.beginForward[j] = -1;
2466 graph.beginBackward[j] = -1;
2467 graph.beginAdj[j] = -1;
2468 inlevelgraph[j] =
FALSE;
2477 inlevelgraph[i] =
TRUE;
2479 graph.levelAdj[0] = 0;
2485 graph.levelAdj[graph.nlevels+1] = 0;
2496 curlevel, ncurlevel, newlevel, &nnewlevel, &success) );
2502 if( graph.nlevels > 0 && (sepadata->includetriangles || graph.nlevels > 1) )
2504 unsigned int maxcutslevel;
2509 maxcutslevel = (
unsigned int) sepadata->maxcutslevel;
2510 maxcutslevel = (
unsigned int)
MIN(maxcutslevel, ncutsroot-sepadata->maxcutsroot);
2511 maxcutslevel = (
unsigned int)
MIN(maxcutslevel, sepadata->maxsepacutsround + sepadata->oldncuts - sepadata->ncuts);
2514 for( j = graph.levelAdj[graph.nlevels+1]; j < graph.levelAdj[graph.nlevels+2]
2517 unsigned int ncyclevars;
2524 assert(graph.sourceAdj[j] < graph.targetAdj[j]);
2533 while( u != graph.sourceAdj[j] )
2535 assert(parentTree[u] != -1 && k <= graph.maxnodes);
2536 u = (
unsigned int) parentTree[u];
2542 for( k = 0; k < graph.nnodes; ++k )
2547 if( blocked[graph.targetAdj[j]] )
2552 graph.targetAdj[j], distance, queue, inQueue, parentTreeBackward, i, blocked) );
2555 if( parentTreeBackward[graph.targetAdj[j]] < 0 )
2561 for( k = 0; k < 2 * nbinvars; ++k )
2573 u = graph.targetAdj[j];
2576 while( success && u != i )
2579 pred[u] = (
unsigned int) parentTreeBackward[u];
2582 SCIP_CALL(
cleanCycle(scip, pred, incycle, incut, u, graph.targetAdj[j], nbinvars, &ncyclevars,
2583 sepadata->repaircycles, sepadata->allowmultiplecuts, &success) );
2585 assert(parentTreeBackward[u] >= 0 || u == i);
2588 u = (
unsigned int) parentTreeBackward[u];
2592 while( success && u != graph.sourceAdj[j] )
2595 pred[u] = (
unsigned int) parentTree[u];
2598 SCIP_CALL(
cleanCycle(scip, pred, incycle, incut, u, graph.targetAdj[j], nbinvars, &ncyclevars,
2599 sepadata->repaircycles, sepadata->allowmultiplecuts, &success) );
2602 u = (
unsigned int) parentTree[u];
2604 assert(!success || u == graph.sourceAdj[j]);
2609 pred[u] = graph.targetAdj[j];
2612 SCIP_CALL(
cleanCycle(scip, pred, incycle, incut, u, graph.targetAdj[j], nbinvars, &ncyclevars,
2613 sepadata->repaircycles, sepadata->allowmultiplecuts, &success) );
2620 unsigned int oldncuts;
2626 oldncuts = sepadata->ncuts;
2629 incut, vals, sepadata, &graphdata, result) );
2631 if(oldncuts < sepadata->ncuts)
2652 for( j = 0; j < nnewlevel; ++j )
2653 curlevel[j] = newlevel[j];
2654 ncurlevel = nnewlevel;
2658 && graph.nlevels < (
unsigned int) sepadata->maxnlevels
2659 && ncutsroot < (
unsigned int) sepadata->maxcutsroot
2660 && sepadata->ncuts - sepadata->oldncuts < (
unsigned int) sepadata->maxsepacutsround);
2666 if( sepadata->sortswitch ==
UNSORTED )
2668 if( i == graph.maxnodes )
2669 sepadata->lastroot = 0;
2671 sepadata->lastroot = (int) i;
2716 unsigned int maxarcs,
2717 unsigned int* arraysize,
2723 unsigned int additional;
2725 unsigned int oldarraysize;
2727 assert(scip !=
NULL);
2728 assert(arraysize !=
NULL);
2729 assert(graph !=
NULL);
2732 assert(success !=
NULL);
2734 SCIPdebugMsg(scip,
"reallocating graph->head and graph->weight...\n");
2736 additional = (
MIN(maxarcs, 2 * (*arraysize)) - (*arraysize)) * ((
int)
sizeof(*(graph->
head)));
2737 additional += (
MIN(maxarcs, 2 * (*arraysize)) - (*arraysize)) * ((
int)
sizeof(*(graph->
weight)));
2748 if( memorylimit <= additional/1048576.0 ||
SCIPisStopped(scip) )
2755 oldarraysize = *arraysize;
2756 *arraysize = 2*(*arraysize);
2773 SCIPdebugMsg(scip,
"...memory limit exceeded - freeing all arrays\n");
2779 for( j = oldarraysize; j <
MIN(maxarcs,(*arraysize)); ++j )
2796 unsigned int varsidx,
2797 unsigned int dijkindex,
2799 unsigned int nbinvars,
2800 unsigned int ncliques,
2802 unsigned int*
narcs,
2803 unsigned int maxarcs,
2806 unsigned int* arraysize,
2811 unsigned int neighindex;
2813 unsigned int ncliquevars;
2819 assert(scip !=
NULL);
2820 assert(sepadata !=
NULL);
2821 assert(vars !=
NULL);
2822 assert(graph !=
NULL);
2826 assert(emptygraph !=
NULL);
2827 assert(arraysize !=
NULL);
2828 assert(success !=
NULL);
2832 assert(cliques !=
NULL || ncliques == 0);
2834 for( k = 0; k < ncliques; ++k )
2836 assert( cliques !=
NULL );
2843 assert(cliquevars !=
NULL || ncliquevars == 0);
2844 assert(cliquevals !=
NULL || ncliquevars == 0);
2847 for( m = 0; m < ncliquevars; ++m )
2851 assert( cliquevars !=
NULL && cliquevals !=
NULL );
2852 neighbor = cliquevars[m];
2855 assert(neighindex < nbinvars);
2858 if( neighindex == varsidx )
2872 tmp = (int)
SCIPfeasCeil(scip, sepadata->scale * (1 - vals[varsidx] - vals[neighindex] ));
2874 graph->
head[*
narcs] = neighindex + 2 * nbinvars;
2879 tmp = (int)
SCIPfeasCeil(scip, sepadata->scale * (1 - vals[varsidx] - (1 - vals[neighindex]) ));
2881 graph->
head[*
narcs] = neighindex + 3 * nbinvars;
2890 tmp = (int)
SCIPfeasCeil(scip, sepadata->scale * (1 - (1 - vals[varsidx]) - vals[neighindex] ));
2892 graph->
head[*
narcs] = neighindex + 2 * nbinvars;
2897 tmp = (int)
SCIPfeasCeil(scip, sepadata->scale * (1 - (1 - vals[varsidx]) - (1-vals[neighindex]) )) ;
2899 graph->
head[*
narcs] = neighindex + 3 * nbinvars;
2911 if( *arraysize == *
narcs )
2918 assert((*
narcs) < maxarcs);
2919 ++(graph->
outcnt[dijkindex]);
2921 *emptygraph =
FALSE;
2962 unsigned int* incut;
2969 unsigned int nbinvars;
2972 unsigned int ncliques;
2975 unsigned int arraysize;
2977 unsigned int maxarcs;
2978 unsigned int maxstarts;
2979 unsigned int startcounter;
2980 unsigned long long cutoff;
2982 unsigned int startnode;
2983 unsigned int endnode;
2984 unsigned long long* dist;
2986 unsigned int* entry;
2987 unsigned int* order;
2988 unsigned int dijkindex;
2992 unsigned int* pred2;
3000 assert(scip !=
NULL);
3001 assert(sepadata !=
NULL);
3002 assert(result !=
NULL);
3008 assert(nscipbinvars >= 0);
3009 assert(nscipintvars >= 0);
3010 assert(nscipimplvars >= 0);
3012 nintegral = nscipbinvars + nscipintvars + nscipimplvars;
3013 assert(scipvars !=
NULL || ((nscipbinvars == 0) && (nscipintvars == 0) && (nscipimplvars == 0) && (nintegral == 0)));
3017 for (k = 0; k < nscipbinvars; ++k)
3018 vars[k] = scipvars[k];
3020 nbinvars = (
unsigned int) nscipbinvars;
3021 for (k = nscipbinvars; k < nintegral; ++k)
3025 vars[nbinvars++] = scipvars[k];
3038 assert( vars !=
NULL );
3039 switch( sepadata->sortswitch )
3047 for( i = 0; i < nbinvars; ++i )
3056 for( i = 0; i < nbinvars; ++i )
3065 for( i = 0; i < nbinvars; ++i )
3068 vals[i] =
MIN(1.0 - vals[i], vals[i]);
3077 for( i = 0; i < nbinvars; ++i )
3080 vals[i] =
MIN(1.0 - vals[i], vals[i]);
3092 assert(vars !=
NULL);
3100 for( i = 0; i < nbinvars; ++i )
3107 for( i = nbinvars; i < 2*nbinvars; ++i )
3108 vals[i] = 1 - vals[i - nbinvars];
3111 graph.
nodes = 4 * nbinvars;
3133 arraysize = 100 * graph.
nodes;
3144 for( i = 0; i <
MIN(arraysize, maxarcs); ++i )
3154 for( i = 0; i < graph.
nodes; ++i )
3162 for( dijkindex = 0; dijkindex < 2 * nbinvars; ++dijkindex )
3165 graph.
outcnt[dijkindex] = 0;
3168 if( dijkindex < nbinvars )
3175 i = dijkindex - nbinvars;
3178 assert(i < nbinvars);
3191 &
narcs, maxarcs, original, &emptygraph, &arraysize, &success) );
3199 if( sepadata->addselfarcs && graph.
outcnt[dijkindex] > 0 )
3204 assert(dijkindex < nbinvars);
3205 graph.
head[
narcs] = dijkindex + 3*nbinvars;
3210 assert(dijkindex >= nbinvars && dijkindex < 2*nbinvars);
3211 graph.
head[
narcs] = dijkindex + nbinvars;
3223 if( arraysize ==
narcs )
3229 assert(
narcs < maxarcs);
3230 ++(graph.
outcnt[dijkindex]);
3237 if( arraysize ==
narcs )
3243 assert(
narcs < maxarcs);
3251 for( i = 0; i < 2*nbinvars; ++i )
3254 graph.
outcnt[2 * nbinvars + i] = 0;
3260 assert(graph.
head[j] >= 2*nbinvars && graph.
head[j] < 4*nbinvars);
3266 if( arraysize ==
narcs )
3273 assert(
narcs < maxarcs);
3274 ++(graph.
outcnt[2*nbinvars+i]);
3282 if( arraysize ==
narcs )
3289 assert(
narcs < maxarcs);
3300 #ifdef SCIP_ODDCYCLE_WRITEGRAPH 3315 maxstarts = (
unsigned int)
SCIPceil(scip, sepadata->offsettestvars + (0.02 * nbinvars * sepadata->percenttestvars));
3323 cutoff = (
unsigned long long) (0.5 * sepadata->scale);
3324 for( i = (
unsigned int) sepadata->lastroot; i < 2 * nbinvars
3325 && startcounter < maxstarts
3326 && sepadata->ncuts - sepadata->oldncuts < (
unsigned int) sepadata->maxsepacutsround
3329 unsigned int ncyclevars;
3345 endnode = i + 2 * nbinvars;
3350 if( incut[startnode] && ! sepadata->multiplecuts )
3355 if ( sepadata->allowmultiplecuts )
3358 (
void)
dijkstraPairCutoff(&graph, startnode, endnode, cutoff, dist, pred, entry, order);
3365 if ( dist[endnode] >= cutoff )
3373 for( j = 0; j < 2 * nbinvars; ++j )
3380 edgedirection =
TRUE;
3384 for( dijkindex = endnode; dijkindex != startnode && success; dijkindex = pred[dijkindex], edgedirection = !edgedirection )
3389 assert(dijkindex >= 2 * nbinvars && dijkindex < 4 * nbinvars);
3390 assert(pred[dijkindex] < 2*nbinvars);
3392 pred2[dijkindex - 2 * nbinvars] = pred[dijkindex];
3398 SCIP_CALL(
cleanCycle(scip, pred2, incycle, incut, dijkindex-2*nbinvars, endnode-2*nbinvars, nbinvars,
3399 &ncyclevars, sepadata->repaircycles, sepadata->allowmultiplecuts, &success) );
3404 assert(dijkindex < 2 * nbinvars);
3405 assert(pred[dijkindex] >= 2 * nbinvars && pred[dijkindex] < 4 * nbinvars);
3407 pred2[dijkindex] = pred[dijkindex] - 2 * nbinvars;
3413 SCIP_CALL(
cleanCycle(scip, pred2, incycle, incut, dijkindex, endnode-2*nbinvars, nbinvars, &ncyclevars,
3414 sepadata->repaircycles, sepadata->allowmultiplecuts, &success) );
3427 SCIP_CALL(
generateOddCycleCut(scip, sepa, sol, vars, nbinvars, startnode, pred2, ncyclevars, incut, vals, sepadata, &graphdata, result) );
3438 if( sepadata->sortswitch ==
UNSORTED )
3440 if( i == 2 * nbinvars )
3441 sepadata->lastroot = 0;
3443 sepadata->lastroot = (int) i;
3473 assert(scip !=
NULL);
3474 assert(sepa !=
NULL);
3491 assert(sepadata !=
NULL);
3507 assert(sepadata !=
NULL);
3509 sepadata->ncuts = 0;
3510 sepadata->oldncuts = 0;
3511 sepadata->nliftedcuts = 0;
3512 sepadata->lastroot = 0;
3524 assert(sepa !=
NULL);
3527 assert(sepadata !=
NULL);
3529 sepadata->nunsucessfull = 0;
3530 sepadata->lastnode = -1;
3550 assert(sepadata !=
NULL);
3556 if( (depth == 0 && sepadata->maxroundsroot >= 0 && ncalls >= sepadata->maxroundsroot)
3557 || (depth > 0 && sepadata->maxrounds >= 0 && ncalls >= sepadata->maxrounds) )
3563 SCIPdebugMsg(scip,
"skipping separator: not enough binary variables\n");
3570 SCIPdebugMsg(scip,
"skipping separator: not enough fractional variables\n");
3577 SCIPdebugMsg(scip,
"skipping separator: not enough implications present\n");
3588 sepadata->nunsucessfull = 0;
3593 if ( sepadata->nunsucessfull > sepadata->maxunsucessfull )
3595 SCIPdebugMsg(scip,
"skipping separator: number of unsucessfull calls = %d.\n", sepadata->nunsucessfull);
3601 sepadata->oldncuts = sepadata->ncuts;
3602 SCIPdebug( oldnliftedcuts = sepadata->nliftedcuts; )
3605 sepadata->maxsepacutsround = sepadata->maxsepacutsroot;
3607 sepadata->maxsepacutsround = sepadata->maxsepacuts;
3610 if( sepadata->usegls )
3612 SCIPdebugMsg(scip,
"using GLS method for finding odd cycles\n");
3617 SCIPdebugMsg(scip,
"using level graph heuristic for finding odd cycles\n");
3621 if( sepadata->ncuts - sepadata->oldncuts > 0 )
3623 SCIPdebugMsg(scip,
"added %u cuts (%d allowed), %d lifted.\n", sepadata->ncuts - sepadata->oldncuts,
3624 sepadata->maxsepacutsround, sepadata->nliftedcuts - oldnliftedcuts);
3625 sepadata->nunsucessfull = 0;
3629 SCIPdebugMsg(scip,
"no cuts added (%d allowed)\n", sepadata->maxsepacutsround);
3630 ++sepadata->nunsucessfull;
3652 sepadata->nunsucessfull = 0;
3653 sepadata->lastnode = -1;
3658 sepaExeclpOddcycle,
NULL,
3661 assert(sepa !=
NULL);
3671 "should the search method by Groetschel, Lovasz, Schrijver be used? Otherwise use levelgraph method by Hoffman, Padberg.",
3674 "should odd cycle cuts be lifted?",
3677 "maximal number of oddcycle cuts separated per separation round",
3680 "maximal number of oddcycle cuts separated per separation round in the root node",
3685 "maximal number of oddcycle separation rounds per node (-1: unlimited)",
3688 "maximal number of oddcycle separation rounds in the root node (-1: unlimited)",
3691 "factor for scaling of the arc-weights",
3694 "add links between a variable and its negated",
3697 "try to repair violated cycles with double appearance of a variable",
3700 "separate triangles found as 3-cycles or repaired larger cycles",
3703 "even if a variable is already covered by a cut, still try it as start node for a cycle search",
3706 "even if a variable is already covered by a cut, still allow another cut to cover it too",
3709 "choose lifting candidate by coef*lpvalue or only by coef",
3712 "calculate lifting coefficient of every candidate in every step (or only if its chosen)",
3715 "use sorted variable array (unsorted(0),maxlp(1),minlp(2),maxfrac(3),minfrac(4))",
3718 "sort level of the root neighbors by fractionality (maxfrac)",
3721 "percentage of variables to try the chosen method on [0-100]",
3724 "offset of variables to try the chosen method on (additional to the percentage of testvars)",
3727 "percentage of nodes allowed in the same level of the level graph [0-100]",
3730 "offset of nodes allowed in the same level of the level graph (additional to the percentage of levelnodes)",
3733 "maximal number of levels in level graph",
3736 "maximal number of oddcycle cuts generated per chosen variable as root of the level graph",
3739 "maximal number of oddcycle cuts generated in every level of the level graph",
3742 "minimal weight on an edge (in level graph or bipartite graph)",
3745 "number of unsuccessful calls at current node",
3748 "maximal number of other cuts s.t. separation is applied (-1 for direct call)",
enum SCIP_Result SCIP_RESULT
static void checkBlocking(unsigned int a, unsigned int b, unsigned int c, unsigned int i, unsigned int *cycle, unsigned int ncyclevars, SCIP_VAR **vars, unsigned int nbinvars, unsigned int *lifted, unsigned int *nlifted, GRAPHDATA *graphdata, SCIP_Bool *myi)
static SCIP_DECL_SEPAEXECLP(sepaExeclpOddcycle)
static SCIP_RETCODE separateHeur(SCIP *scip, SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata, SCIP_SOL *sol, SCIP_RESULT *result)
SCIP_VAR ** SCIPcliqueGetVars(SCIP_CLIQUE *clique)
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
static SCIP_RETCODE generateOddCycleCut(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_VAR **vars, unsigned int nbinvars, unsigned int startnode, unsigned int *pred, unsigned int ncyclevars, unsigned int *incut, SCIP_Real *vals, SCIP_SEPADATA *sepadata, GRAPHDATA *graphdata, SCIP_RESULT *result)
Definitions for Disjkstra's shortest path algorithm.
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
DIJKSTRA_GRAPH * dijkstragraph
SCIP_RETCODE SCIPgetRealParam(SCIP *scip, const char *name, SCIP_Real *value)
#define DEFAULT_MAXROUNDSROOT
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
SCIP_CLIQUE ** SCIPvarGetCliques(SCIP_VAR *var, SCIP_Bool varfixing)
#define DEFAULT_LPLIFTCOEF
static SCIP_RETCODE addArc(SCIP *scip, LEVELGRAPH *graph, unsigned int u, unsigned int v, unsigned int level, unsigned int weight, unsigned int *nAdj, SCIP_Bool *success)
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
void SCIPsplitFilename(char *filename, char **path, char **name, char **extension, char **compression)
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
#define DEFAULT_MAXSEPACUTSROOT
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
#define DEFAULT_MULTIPLECUTS
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
#define DEFAULT_OFFSETNODESLEVEL
const char * SCIPsepaGetName(SCIP_SEPA *sepa)
enum SCIP_Retcode SCIP_RETCODE
SCIP_Real SCIPsepaGetTime(SCIP_SEPA *sepa)
int SCIPvarGetProbindex(SCIP_VAR *var)
unsigned int dijkstraPairCutoff(const DIJKSTRA_GRAPH *G, unsigned int source, unsigned int target, unsigned long long cutoff, unsigned long long *dist, unsigned int *pred, unsigned int *entry, unsigned int *order)
#define SCIPfreeBlockMemory(scip, ptr)
#define DEFAULT_MAXPERNODESLEVEL
static SCIP_RETCODE liftOddCycleCut(SCIP *scip, unsigned int *nlifted, unsigned int *lifted, unsigned int *liftcoef, SCIP_SEPADATA *sepadata, GRAPHDATA *graphdata, SCIP_VAR **vars, unsigned int nbinvars, unsigned int startnode, unsigned int *pred, unsigned int ncyclevars, SCIP_Real *vals, SCIP_RESULT *result)
int SCIPgetNCutsFoundRound(SCIP *scip)
#define DEFAULT_SORTSWITCH
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
void SCIPsortDownRealInt(SCIP_Real *realarray, int *intarray, int len)
#define SCIPfreeBufferArray(scip, ptr)
#define SCIPallocBlockMemory(scip, ptr)
int SCIPgetNLPBranchCands(SCIP *scip)
SCIP_RETCODE SCIPsetSepaCopy(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPACOPY((*sepacopy)))
#define DEFAULT_MAXSEPACUTS
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)
#define SEPA_MAXBOUNDDIST
int SCIPvarGetNCliques(SCIP_VAR *var, SCIP_Bool varfixing)
static SCIP_DECL_SEPAINIT(sepaInitOddcycle)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
SCIP_SEPADATA * SCIPsepaGetData(SCIP_SEPA *sepa)
#define DEFAULT_ADDSELFARCS
static SCIP_RETCODE cleanCycle(SCIP *scip, unsigned int *pred, SCIP_Bool *incycle, unsigned int *incut, unsigned int x, unsigned int startnode, unsigned int nbinvars, unsigned int *ncyclevars, SCIP_Bool repaircycles, SCIP_Bool allowmultiplecuts, SCIP_Bool *success)
const char * SCIPgetProbName(SCIP *scip)
#define DEFAULT_ALLOWMULTIPLECUTS
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
#define DEFAULT_INCLUDETRIANGLES
SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
static SCIP_DECL_SEPACOPY(sepaCopyOddcycle)
static SCIP_RETCODE separateGLS(SCIP *scip, SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata, SCIP_SOL *sol, SCIP_RESULT *result)
#define DEFAULT_SORTROOTNEIGHBORS
static SCIP_RETCODE findUnblockedShortestPathToRoot(SCIP *scip, int scale, LEVELGRAPH *graph, unsigned int startnode, unsigned int *distance, unsigned int *queue, SCIP_Bool *inQueue, int *parentTreeBackward, unsigned int root, SCIP_Bool *blocked)
static SCIP_RETCODE addGLSCliques(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_VAR **vars, unsigned int varsidx, unsigned int dijkindex, SCIP_Real *vals, unsigned int nbinvars, unsigned int ncliques, DIJKSTRA_GRAPH *graph, unsigned int *narcs, unsigned int maxarcs, SCIP_Bool original, SCIP_Bool *emptygraph, unsigned int *arraysize, SCIP_Bool *success)
int SCIPsepaGetNCallsAtNode(SCIP_SEPA *sepa)
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
const char * SCIPvarGetName(SCIP_VAR *var)
#define DEFAULT_MAXREFERENCE
void SCIPsepaSetData(SCIP_SEPA *sepa, SCIP_SEPADATA *sepadata)
#define DEFAULT_REPAIRCYCLES
DIJKSTRA_Bool dijkstraGraphIsValid(const DIJKSTRA_GRAPH *G)
SCIP_RETCODE SCIPsetSepaInitsol(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAINITSOL((*sepainitsol)))
static SCIP_DECL_SEPAINITSOL(sepaInitsolOddcycle)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
SCIP_RETCODE SCIPaddCut(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool *infeasible)
#define DEFAULT_MAXCUTSROOT
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)
unsigned int dijkstraPairCutoffIgnore(const DIJKSTRA_GRAPH *G, unsigned int source, unsigned int target, unsigned int *ignore, unsigned long long cutoff, unsigned long long *dist, unsigned int *pred, unsigned int *entry, unsigned int *order)
#define SCIPallocBufferArray(scip, ptr, num)
#define DEFAULT_PERCENTTESTVARS
public data structures and miscellaneous methods
SCIP_RETCODE SCIPchgRowRhs(SCIP *scip, SCIP_ROW *row, SCIP_Real rhs)
#define DEFAULT_MAXUNSUCESSFULL
int SCIPgetDepth(SCIP *scip)
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
SCIP_Bool * SCIPcliqueGetValues(SCIP_CLIQUE *clique)
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)
static unsigned int getCoef(SCIP *scip, unsigned int i, unsigned int *cycle, unsigned int ncyclevars, SCIP_VAR **vars, unsigned int nbinvars, unsigned int *lifted, unsigned int *nlifted, GRAPHDATA *graphdata, SCIP_Bool *myi)
SCIP_RETCODE SCIPwriteCliqueGraph(SCIP *scip, const char *fname, SCIP_Bool writenodeweights)
#define DEFAULT_SCALEFACTOR
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
int SCIPgetNBinVars(SCIP *scip)
#define DEFAULT_MAXNLEVELS
static SCIP_Bool isNeighbor(SCIP_VAR **vars, unsigned int nbinvars, GRAPHDATA *graphdata, unsigned int a, unsigned int b)
static SCIP_RETCODE insertSortedRootNeighbors(SCIP *scip, LEVELGRAPH *graph, unsigned int nbinvars, unsigned int ncurlevel, unsigned int u, SCIP_Real *vals, SCIP_VAR **vars, SCIP_SEPADATA *sepadata, unsigned int *nnewlevel, SCIP_Bool *inlevelgraph, unsigned int level, unsigned int *newlevel, SCIP_Bool *success)
static SCIP_DECL_SEPAFREE(sepaFreeOddcycle)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
static SCIP_RETCODE checkArraySizesHeur(SCIP *scip, LEVELGRAPH *graph, unsigned int *size, int **targetArray, unsigned int **weightArray, unsigned int **sourceAdjArray, unsigned int **targetAdjArray, SCIP_Bool *success)
static SCIP_RETCODE checkArraySizesGLS(SCIP *scip, unsigned int maxarcs, unsigned int *arraysize, DIJKSTRA_GRAPH *graph, SCIP_Bool *success)
SCIP_RETCODE SCIPsetSepaFree(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAFREE((*sepafree)))
SCIP_RETCODE SCIPsetSepaInit(SCIP *scip, SCIP_SEPA *sepa, SCIP_DECL_SEPAINIT((*sepainit)))
SCIP_Longint SCIPgetMemUsed(SCIP *scip)
void SCIProwChgRank(SCIP_ROW *row, int rank)
#define DEFAULT_RECALCLIFTCOEF
int SCIPgetNCliques(SCIP *scip)
int SCIPgetNImplications(SCIP *scip)
SCIP_Longint SCIPgetMemExternEstim(SCIP *scip)
SCIP_Bool SCIPisStopped(SCIP *scip)
#define DEFAULT_OFFSETTESTVARS
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
#define DEFAULT_CUTTHRESHOLD
void SCIPsortRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
static SCIP_RETCODE blockRootPath(SCIP *scip, LEVELGRAPH *graph, unsigned int startnode, SCIP_Bool *inlevelgraph, SCIP_Bool *blocked, int *parentTree, unsigned int root)
int SCIPcliqueGetNVars(SCIP_CLIQUE *clique)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
#define BMSclearMemoryArray(ptr, num)
static SCIP_RETCODE addNextLevelCliques(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_VAR **vars, SCIP_Real *vals, unsigned int u, LEVELGRAPH *graph, unsigned int level, SCIP_Bool *inlevelgraph, unsigned int *newlevel, unsigned int *nnewlevel, unsigned int *nAdj, SCIP_Bool *success)
SCIP_RETCODE SCIPincludeSepaOddcycle(SCIP *scip)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE createNextLevel(SCIP *scip, SCIP_SEPADATA *sepadata, SCIP_VAR **vars, SCIP_Real *vals, LEVELGRAPH *graph, unsigned int level, SCIP_Bool *inlevelgraph, unsigned int *curlevel, unsigned int ncurlevel, unsigned int *newlevel, unsigned int *nnewlevel, SCIP_Bool *success)
#define DEFAULT_LIFTODDCYCLES
SCIP_Longint SCIPgetNLPs(SCIP *scip)
#define DEFAULT_MAXCUTSLEVEL
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
static SCIP_RETCODE findShortestPathToRoot(SCIP *scip, int scale, LEVELGRAPH *graph, unsigned int startnode, unsigned int *distance, unsigned int *queue, SCIP_Bool *inQueue, int *parentTree)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
#define DEFAULT_MAXROUNDS
struct SCIP_SepaData SCIP_SEPADATA
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)
#define SCIPreallocBufferArray(scip, ptr, num)