52 #define PRESOL_NAME "domcol"
53 #define PRESOL_DESC "dominated column presolver"
54 #define PRESOL_PRIORITY 20000000
55 #define PRESOL_MAXROUNDS -1
56 #define PRESOL_DELAY TRUE
58 #define DEFAULT_NUMMINPAIRS 1024
59 #define DEFAULT_NUMMAXPAIRS 1048576
61 #define DEFAULT_PREDBNDSTR FALSE
62 #define DEFAULT_SINGCOLSTUFF TRUE
69 struct SCIP_PresolData
97 struct ConstraintMatrix
116 const char** rowname;
125 int* minactivityneginf;
126 int* minactivityposinf;
127 int* maxactivityneginf;
128 int* maxactivityposinf;
144 assert(scip !=
NULL);
145 assert(vars !=
NULL);
146 assert(scalars !=
NULL);
147 assert(*vars !=
NULL);
148 assert(*scalars !=
NULL);
149 assert(nvars !=
NULL);
150 assert(constant !=
NULL);
154 if( requiredsize > *nvars )
161 assert(requiredsize <= *nvars);
188 assert(vars !=
NULL);
189 assert(vals !=
NULL);
191 rowidx = matrix->nrows;
192 rangedorequality =
FALSE;
197 matrix->lhs[rowidx] = -rhs;
199 matrix->isrhsinfinite[rowidx] =
TRUE;
204 matrix->lhs[rowidx] = lhs;
205 matrix->rhs[rowidx] = rhs;
206 matrix->isrhsinfinite[rowidx] =
SCIPisInfinity(scip, matrix->rhs[rowidx]);
209 rangedorequality =
TRUE;
215 matrix->rowname[rowidx] = name;
218 matrix->rowmatbeg[rowidx] = matrix->nnonzs;
221 if( rangedorequality )
225 for( j = 0; j < nvars; j++ )
227 matrix->rowmatval[matrix->nnonzs] = factor * vals[j];
229 assert(matrix->vars[probindex] == vars[j]);
231 matrix->nuplocks[probindex]++;
232 matrix->ndownlocks[probindex]++;
234 assert(0 <= probindex && probindex < matrix->ncols);
235 matrix->rowmatind[matrix->nnonzs] = probindex;
242 for( j = 0; j < nvars; j++ )
245 matrix->rowmatval[matrix->nnonzs] = factor * vals[j];
247 assert(matrix->vars[probindex] == vars[j]);
249 if( matrix->rowmatval[matrix->nnonzs] > 0 )
250 matrix->ndownlocks[probindex]++;
253 assert(matrix->rowmatval[matrix->nnonzs] < 0);
254 matrix->nuplocks[probindex]++;
257 assert(0 <= probindex && probindex < matrix->ncols);
258 matrix->rowmatind[matrix->nnonzs] = probindex;
263 matrix->rowmatcnt[rowidx] = matrix->nnonzs - matrix->rowmatbeg[rowidx];
291 assert(scip !=
NULL);
292 assert(matrix !=
NULL);
293 assert(vars !=
NULL || nvars == 0);
307 activeconstant = 0.0;
319 for( v = 0; v < nactivevars; v++ )
328 lhs -= activeconstant;
330 rhs -= activeconstant;
333 if( nactivevars > 0 )
336 SCIP_CALL(
addRow(scip, matrix, name, activevars, activevals, nactivevars, lhs, rhs) );
338 SCIP_CALL(
addRow(scip, matrix, activevars, activevals, nactivevars, lhs, rhs) );
363 assert(scip !=
NULL);
364 assert(matrix !=
NULL);
365 assert(matrix->colmatval !=
NULL);
366 assert(matrix->colmatind !=
NULL);
367 assert(matrix->colmatbeg !=
NULL);
368 assert(matrix->colmatcnt !=
NULL);
369 assert(matrix->rowmatval !=
NULL);
370 assert(matrix->rowmatind !=
NULL);
371 assert(matrix->rowmatbeg !=
NULL);
372 assert(matrix->rowmatcnt !=
NULL);
378 for( i = 0; i < matrix->nrows; i++ )
380 rowpnt = matrix->rowmatind + matrix->rowmatbeg[i];
381 rowend = rowpnt + matrix->rowmatcnt[i];
382 for( ; rowpnt < rowend; rowpnt++ )
385 (matrix->colmatcnt[colidx])++;
389 matrix->colmatbeg[0] = 0;
390 for( i = 0; i < matrix->ncols-1; i++ )
392 matrix->colmatbeg[i+1] = matrix->colmatbeg[i] + matrix->colmatcnt[i];
395 for( i = 0; i < matrix->nrows; i++ )
397 rowpnt = matrix->rowmatind + matrix->rowmatbeg[i];
398 rowend = rowpnt + matrix->rowmatcnt[i];
399 valpnt = matrix->rowmatval + matrix->rowmatbeg[i];
401 for( ; rowpnt < rowend; rowpnt++, valpnt++ )
403 assert(*rowpnt < matrix->ncols);
405 matrix->colmatval[matrix->colmatbeg[colidx] + fillidx[colidx]] = *valpnt;
406 matrix->colmatind[matrix->colmatbeg[colidx] + fillidx[colidx]] = i;
430 assert(scip !=
NULL);
431 assert(matrix !=
NULL);
433 for( row = 0; row < matrix->nrows; row++ )
435 matrix->minactivity[row] = 0;
436 matrix->maxactivity[row] = 0;
437 matrix->minactivityneginf[row] = 0;
438 matrix->minactivityposinf[row] = 0;
439 matrix->maxactivityneginf[row] = 0;
440 matrix->maxactivityposinf[row] = 0;
442 rowpnt = matrix->rowmatind + matrix->rowmatbeg[row];
443 rowend = rowpnt + matrix->rowmatcnt[row];
444 valpnt = matrix->rowmatval + matrix->rowmatbeg[row];
446 for( ; rowpnt < rowend; rowpnt++, valpnt++ )
455 assert(matrix->ncols > col);
464 matrix->maxactivityposinf[row]++;
466 matrix->maxactivity[row] += val * matrix->ub[col];
469 matrix->minactivityneginf[row]++;
471 matrix->minactivity[row] += val * matrix->lb[col];
477 matrix->maxactivityneginf[row]++;
479 matrix->maxactivity[row] += val * matrix->lb[col];
482 matrix->minactivityposinf[row]++;
484 matrix->minactivity[row] += val * matrix->ub[col];
502 const char* conshdlrname;
517 assert(scip !=
NULL);
518 assert(matrixptr !=
NULL);
519 assert(initialized !=
NULL);
521 *initialized =
FALSE;
532 for( i = 0; i < nconshdlrs; ++i )
538 if( nconshdlrconss > 0 )
542 if( (strcmp(conshdlrname,
"linear") != 0) && (strcmp(conshdlrname,
"setppc") != 0)
543 && (strcmp(conshdlrname,
"logicor") != 0) && (strcmp(conshdlrname,
"knapsack") != 0)
544 && (strcmp(conshdlrname,
"varbound") != 0) )
546 SCIPdebugMessage(
"unsupported constraint type <%s>: aborting domcol presolver\n", conshdlrname);
551 nconss += nconshdlrconss;
555 if( i < nconshdlrs || nconss == 0 )
566 for( i = nvars - 1; i >= 0; --i )
582 matrix->ncols = nvars;
600 for( v = 0; v < matrix->ncols; v++ )
602 var = matrix->vars[v];
632 for( i = 0; i < nconshdlrs; ++i )
647 if( strcmp(conshdlrname,
"linear") == 0 )
649 for( c = 0; c < nconshdlrconss && (c % 1000 != 0 || !
SCIPisStopped(scip)); ++c )
651 cons = conshdlrconss[c];
665 else if( strcmp(conshdlrname,
"setppc") == 0 )
667 for( c = 0; c < nconshdlrconss && (c % 1000 != 0 || !
SCIPisStopped(scip)); ++c )
672 cons = conshdlrconss[c];
702 else if( strcmp(conshdlrname,
"logicor") == 0 )
704 for( c = 0; c < nconshdlrconss && (c % 1000 != 0 || !
SCIPisStopped(scip)); ++c )
706 cons = conshdlrconss[c];
718 else if( strcmp(conshdlrname,
"knapsack") == 0 )
720 if( nconshdlrconss > 0 )
728 for( c = 0; c < nconshdlrconss && (c % 1000 != 0 || !
SCIPisStopped(scip)); ++c )
732 cons = conshdlrconss[c];
738 if( nvars > valssize )
740 valssize = (int) (1.5 * nvars);
744 for( v = 0; v < nvars; v++ )
761 else if( strcmp(conshdlrname,
"varbound") == 0 )
763 if( nconshdlrconss > 0 )
772 for( c = 0; c < nconshdlrconss && (c % 1000 != 0 || !
SCIPisStopped(scip)); ++c )
774 cons = conshdlrconss[c];
798 assert(nconshdlrconss == 0);
802 assert(matrix->nrows <= nconss);
803 assert(matrix->nnonzs <= nnonzstmp);
827 assert(scip !=
NULL);
828 assert(matrix !=
NULL);
830 if( (*matrix) !=
NULL )
832 assert((*matrix)->colmatval !=
NULL);
833 assert((*matrix)->colmatind !=
NULL);
834 assert((*matrix)->colmatbeg !=
NULL);
835 assert((*matrix)->colmatcnt !=
NULL);
836 assert((*matrix)->lb !=
NULL);
837 assert((*matrix)->ub !=
NULL);
838 assert((*matrix)->nuplocks !=
NULL);
839 assert((*matrix)->ndownlocks !=
NULL);
841 assert((*matrix)->rowmatval !=
NULL);
842 assert((*matrix)->rowmatind !=
NULL);
843 assert((*matrix)->rowmatbeg !=
NULL);
844 assert((*matrix)->rowmatcnt !=
NULL);
845 assert((*matrix)->lhs !=
NULL);
846 assert((*matrix)->rhs !=
NULL);
848 assert((*matrix)->rowname !=
NULL);
880 (*matrix)->nrows = 0;
881 (*matrix)->ncols = 0;
882 (*matrix)->nnonzs = 0;
914 if( !matrix->isrhsinfinite &&
915 SCIPisEQ(scip, matrix->lhs[row], matrix->rhs[row]))
919 else if( !matrix->isrhsinfinite &&
920 !
SCIPisEQ(scip, matrix->lhs[row], matrix->rhs[row]))
929 rowpnt = matrix->rowmatind + matrix->rowmatbeg[row];
930 rowend = rowpnt + matrix->rowmatcnt[row];
931 valpnt = matrix->rowmatval + matrix->rowmatbeg[row];
933 SCIPdebugPrintf(
"\n(L:%g) [%c] %g <=", (matrix->minactivityposinf[row] + matrix->minactivityneginf[row] > 0) ? -
SCIPinfinity(scip) : matrix->minactivity[row], relation, matrix->lhs[row]);
934 for(; (rowpnt < rowend); rowpnt++, valpnt++)
942 SCIPdebugPrintf(
" <= %g (U:%g)", (matrix->maxactivityposinf[row] + matrix->maxactivityneginf[row] > 0) ?
SCIPinfinity(scip) : matrix->rhs[row], matrix->maxactivity[row]);
959 numrows = matrix->colmatcnt[col];
963 colpnt = matrix->colmatind + matrix->colmatbeg[col];
964 colend = colpnt + matrix->colmatcnt[col];
965 for( i = 0; (colpnt < colend); colpnt++, i++ )
972 for( i = 0; i < numrows; i++ )
1018 SCIPdebugPrintf(
"\n\n### [%c], obj:%g->%g,\t%s[idx:%d](nrows:%d)->%s[idx:%d](nrows:%d)\twclb=%g, ub'=%g, ub=%g",
1020 SCIPvarGetName(dominatingvar), dominatingidx, matrix->colmatcnt[dominatingidx],
1021 SCIPvarGetName(dominatedvar), dominatedidx, matrix->colmatcnt[dominatedidx],
1024 SCIP_CALL( printRowsOfCol(scip, matrix, dominatingidx) );
1057 assert(scip !=
NULL);
1058 assert(matrix !=
NULL);
1059 assert(row < matrix->nrows);
1060 assert(minresactivity !=
NULL);
1061 assert(maxresactivity !=
NULL);
1063 var = matrix->vars[col];
1064 upperboundvar = matrix->vars[upperboundcol];
1065 assert(var !=
NULL);
1066 assert(upperboundvar !=
NULL);
1071 maxactinf = matrix->maxactivityposinf[row] + matrix->maxactivityneginf[row];
1072 minactinf = matrix->minactivityposinf[row] + matrix->minactivityneginf[row];
1083 tmpminact = matrix->minactivity[row];
1084 tmpmaxact = matrix->maxactivity[row];
1097 if( upperboundcoef > 0.0 )
1101 assert(minactinf > 0);
1103 tmpminact += (upperboundcoef * ubupperboundvar);
1107 tmpminact = tmpminact - (upperboundcoef * lbupperboundvar) + (upperboundcoef * ubupperboundvar);
1115 assert(maxactinf > 0);
1117 tmpmaxact += (upperboundcoef * ubupperboundvar);
1121 tmpmaxact = tmpmaxact - (upperboundcoef * lbupperboundvar) + (upperboundcoef * ubupperboundvar);
1133 assert(maxactinf >= 1);
1134 if( maxactinf == 1 )
1136 *maxresactivity = tmpmaxact;
1146 *maxresactivity = tmpmaxact - coef * ub;
1151 assert(minactinf >= 1);
1152 if( minactinf == 1 )
1154 *minresactivity = tmpminact;
1164 *minresactivity = tmpminact - coef * lb;
1172 assert(maxactinf >= 1);
1173 if( maxactinf == 1 )
1175 *maxresactivity = tmpmaxact;
1185 *maxresactivity = tmpmaxact - coef * lb;
1190 assert(minactinf >= 1);
1191 if( minactinf == 1 )
1193 *minresactivity = tmpminact;
1203 *minresactivity = tmpminact - coef * ub;
1234 assert(scip !=
NULL);
1235 assert(matrix !=
NULL);
1236 assert(row < matrix->nrows);
1237 assert(minresactivity !=
NULL);
1238 assert(maxresactivity !=
NULL);
1240 var = matrix->vars[col];
1241 lowerboundvar = matrix->vars[lowerboundcol];
1242 assert(var !=
NULL);
1243 assert(lowerboundvar !=
NULL);
1248 maxactinf = matrix->maxactivityposinf[row] + matrix->maxactivityneginf[row];
1249 minactinf = matrix->minactivityposinf[row] + matrix->minactivityneginf[row];
1260 tmpminact = matrix->minactivity[row];
1261 tmpmaxact = matrix->maxactivity[row];
1274 if( lowerboundcoef > 0.0 )
1278 assert(maxactinf > 0);
1280 tmpmaxact += (lowerboundcoef * lblowerboundvar);
1284 tmpmaxact = tmpmaxact - (lowerboundcoef * ublowerboundvar) + (lowerboundcoef * lblowerboundvar);
1292 assert(minactinf > 0);
1294 tmpminact += (lowerboundcoef * lblowerboundvar);
1298 tmpminact = tmpminact - (lowerboundcoef * ublowerboundvar) + (lowerboundcoef * lblowerboundvar);
1310 assert(maxactinf >= 1);
1311 if( maxactinf == 1 )
1313 *maxresactivity = tmpmaxact;
1323 *maxresactivity = tmpmaxact - coef * ub;
1328 assert(minactinf >= 1);
1329 if( minactinf == 1 )
1331 *minresactivity = tmpminact;
1341 *minresactivity = tmpminact - coef * lb;
1349 assert(maxactinf >= 1);
1350 if( maxactinf == 1 )
1352 *maxresactivity = tmpmaxact;
1362 *maxresactivity = tmpmaxact - coef * lb;
1367 assert(minactinf >= 1);
1368 if( minactinf == 1 )
1370 *minresactivity = tmpminact;
1380 *minresactivity = tmpminact - coef * ub;
1413 assert(scip !=
NULL);
1414 assert(matrix !=
NULL);
1415 assert(0 <= row && row < matrix->nrows);
1416 assert(0 <= coldominating && coldominating < matrix->ncols);
1417 assert(0 <= coldominated && coldominated < matrix->ncols);
1419 assert(ubcalculated !=
NULL);
1420 assert(calculatedub !=
NULL);
1421 assert(wclbcalculated !=
NULL);
1422 assert(calculatedwclb !=
NULL);
1423 assert(lbcalculated !=
NULL);
1424 assert(calculatedlb !=
NULL);
1425 assert(wcubcalculated !=
NULL);
1426 assert(calculatedwcub !=
NULL);
1429 assert(matrix->vars[coldominated] !=
NULL);
1431 *ubcalculated =
FALSE;
1432 *wclbcalculated =
FALSE;
1433 *lbcalculated =
FALSE;
1434 *wcubcalculated =
FALSE;
1442 lhs = matrix->lhs[row];
1443 rhs = matrix->rhs[row];
1449 &minresactivity, &maxresactivity, &success);
1464 if( valdominated > 0.0 )
1469 *calculatedlb = (lhs - maxresactivity)/valdominated;
1470 *lbcalculated =
TRUE;
1476 *calculatedwclb = (lhs - minresactivity)/valdominated;
1477 *wclbcalculated =
TRUE;
1483 *wclbcalculated =
TRUE;
1487 if( !matrix->isrhsinfinite[row] )
1492 *calculatedub = (rhs - minresactivity)/valdominated;
1493 *ubcalculated =
TRUE;
1499 *calculatedwcub = (rhs - maxresactivity)/valdominated;
1500 *wcubcalculated =
TRUE;
1506 *wcubcalculated =
TRUE;
1515 *calculatedub = (lhs - maxresactivity)/valdominated;
1516 *ubcalculated =
TRUE;
1522 *calculatedwcub = (lhs - minresactivity)/valdominated;
1523 *wcubcalculated =
TRUE;
1529 *wcubcalculated =
TRUE;
1533 if( !matrix->isrhsinfinite[row] )
1538 *calculatedlb = (rhs - minresactivity)/valdominated;
1539 *lbcalculated =
TRUE;
1545 *calculatedwclb = (rhs - maxresactivity)/valdominated;
1546 *wclbcalculated =
TRUE;
1552 *wclbcalculated =
TRUE;
1588 assert(scip !=
NULL);
1589 assert(matrix !=
NULL);
1590 assert(0 <= row && row < matrix->nrows);
1591 assert(0 <= coldominating && coldominating < matrix->ncols);
1592 assert(0 <= coldominated && coldominated < matrix->ncols);
1594 assert(ubcalculated !=
NULL);
1595 assert(calculatedub !=
NULL);
1596 assert(wclbcalculated !=
NULL);
1597 assert(calculatedwclb !=
NULL);
1598 assert(lbcalculated !=
NULL);
1599 assert(calculatedlb !=
NULL);
1600 assert(wcubcalculated !=
NULL);
1601 assert(calculatedwcub !=
NULL);
1604 assert(matrix->vars[coldominating] !=
NULL);
1606 *ubcalculated =
FALSE;
1607 *wclbcalculated =
FALSE;
1608 *lbcalculated =
FALSE;
1609 *wcubcalculated =
FALSE;
1617 lhs = matrix->lhs[row];
1618 rhs = matrix->rhs[row];
1624 &minresactivity, &maxresactivity, &success);
1639 if( valdominating > 0.0 )
1644 *calculatedlb = (lhs - maxresactivity)/valdominating;
1645 *lbcalculated =
TRUE;
1651 *calculatedwclb = (lhs - minresactivity)/valdominating;
1652 *wclbcalculated =
TRUE;
1658 *wclbcalculated =
TRUE;
1662 if( !matrix->isrhsinfinite[row] )
1667 *calculatedub = (rhs - minresactivity)/valdominating;
1668 *ubcalculated =
TRUE;
1674 *calculatedwcub = (rhs - maxresactivity)/valdominating;
1675 *wcubcalculated =
TRUE;
1681 *wcubcalculated =
TRUE;
1690 *calculatedub = (lhs - maxresactivity)/valdominating;
1691 *ubcalculated =
TRUE;
1697 *calculatedwcub = (lhs - minresactivity)/valdominating;
1698 *wcubcalculated =
TRUE;
1704 *wcubcalculated =
TRUE;
1708 if( !matrix->isrhsinfinite[row] )
1713 *calculatedlb = (rhs - minresactivity)/valdominating;
1714 *lbcalculated =
TRUE;
1720 *calculatedwclb = (rhs - maxresactivity)/valdominating;
1721 *wclbcalculated =
TRUE;
1727 *wclbcalculated =
TRUE;
1761 assert(scip !=
NULL);
1762 assert(matrix !=
NULL);
1763 assert(row < matrix->nrows);
1764 assert(col1 < matrix->ncols);
1765 assert(col2 < matrix->ncols);
1766 assert(upperbound !=
NULL);
1767 assert(wclowerbound !=
NULL);
1768 assert(lowerbound !=
NULL);
1769 assert(wcupperbound !=
NULL);
1776 if( predictdominating )
1780 &ubcalculated, &newub, &wclbcalculated, &newwclb,
1781 &lbcalculated, &newlb, &wcubcalculated, &newwcub) );
1787 &ubcalculated, &newub, &wclbcalculated, &newwclb,
1788 &lbcalculated, &newlb, &wcubcalculated, &newwcub) );
1794 if( newub < *upperbound )
1795 *upperbound = newub;
1797 if( wclbcalculated )
1799 if( newwclb > *wclowerbound )
1800 *wclowerbound = newwclb;
1804 if( newlb > *lowerbound )
1805 *lowerbound = newlb;
1807 if( wcubcalculated )
1809 if( newwcub < *wcupperbound )
1810 *wcupperbound = newwcub;
1851 assert(scip !=
NULL);
1852 assert(matrix !=
NULL);
1853 assert(pclass !=
NULL);
1854 assert(varineq !=
NULL);
1867 classsizes[0] = matrix->ncols;
1869 for( t = 1; t < matrix->ncols; ++t )
1870 pcset[pcsetfill++] = t;
1873 for( r = 0; r < matrix->nrows; ++r )
1876 if( !matrix->isrhsinfinite[r] )
1878 rowpnt = matrix->rowmatind + matrix->rowmatbeg[r];
1879 rowend = rowpnt + matrix->rowmatcnt[r];
1880 valpnt = matrix->rowmatval + matrix->rowmatbeg[r];
1883 for( ; (rowpnt < rowend); rowpnt++, valpnt++ )
1895 varineq[colidx] =
TRUE;
1897 if( scale[colidx] == 0.0 )
1898 scale[colidx] = aij;
1899 assert(scale[colidx] != 0.0);
1901 colindices[i] = colidx;
1902 values[i] = aij / scale[colidx];
1903 pc = pclass[colidx];
1904 assert(pc < matrix->ncols);
1907 assert(classsizes[pc] > 0);
1909 if( classsizes[pc] == 0 )
1911 assert(pcsetfill < matrix->ncols);
1912 pcset[pcsetfill++] = pc;
1933 while( k < i && pcs[k] == startpc )
1937 if( k - startk > 1 )
1938 SCIPsortRealInt(&(values[startk]), &(colindices[startk]), k - startk);
1943 assert(startk + t < i);
1944 startval = values[startk + t];
1948 while( t < k - startk &&
SCIPisEQ(scip, startval, values[startk + t]) )
1952 newpclass = pcset[0];
1953 assert(pcsetfill > 0);
1954 pcset[0] = pcset[--pcsetfill];
1957 for( m = startk + startt; m < startk + t; m++ )
1960 assert(colindices[m] < matrix->ncols);
1961 assert(newpclass < matrix->ncols);
1963 pclass[colindices[m]] = newpclass;
1964 classsizes[newpclass]++;
1967 if( t == k - startk )
1971 if( k == matrix->rowmatcnt[r] )
2015 if( varstofix[dominatingidx] ==
NOFIX )
2029 newub = dominatingub;
2038 SCIPdebugMessage(
"[ub]\tupper bound for dominating variable <%s> changed: [%.17f,%.17f] -> [%.17f,%.17f]\n",
2057 newlb = dominatinglb;
2066 SCIPdebugMessage(
"[lb]\tlower bound of dominating variable <%s> changed: [%.17f,%.17f] -> [%.17f,%.17f]\n",
2086 newlb = dominatingwcub;
2095 SCIPdebugMessage(
"[wcub]\tlower bound of dominating variable <%s> changed: [%.17f,%.17f] -> [%.17f,%.17f]\n",
2103 if( varstofix[dominatedidx] ==
NOFIX )
2116 newub = dominatedub;
2122 SCIPdebugMessage(
"[ub]\tupper bound of dominated variable <%s> changed: [%.17f,%.17f] -> [%.17f,%.17f]\n",
2142 newub = dominatedwclb;
2151 SCIPdebugMessage(
"[wclb]\tupper bound of dominated variable <%s> changed: [%.17f,%.17f] -> [%.17f,%.17f]\n",
2169 newlb = dominatedlb;
2175 SCIPdebugMessage(
"[lb]\tlower bound of dominated variable <%s> changed: [%.17f,%.17f] -> [%.17f,%.17f]\n",
2214 if( varstofix[dominatedidx] ==
NOFIX && matrix->colmatcnt[dominatingidx] == 1
2215 && matrix->colmatcnt[dominatedidx] == 1 )
2223 row = *(matrix->colmatind + matrix->colmatbeg[dominatedidx]);
2225 if(
SCIPisEQ(scip, matrix->lhs[row], matrix->rhs[row]) &&
2228 varstofix[dominatedidx] =
FIXATLB;
2247 varstofix[dominatedidx] =
FIXATLB;
2265 varstofix[dominatedidx] =
FIXATLB;
2278 varstofix[dominatingidx] =
FIXATUB;
2290 varstofix[dominatingidx] =
FIXATUB;
2303 varstofix[dominatedidx] =
FIXATLB;
2314 varstofix[dominatingidx] =
FIXATUB;
2319 assert(!onlyoneone);
2344 SCIP_Real tmpwclowerbounddominatingcol1;
2345 SCIP_Real tmpwclowerbounddominatingcol2;
2348 SCIP_Real tmpwcupperbounddominatingcol1;
2349 SCIP_Real tmpwcupperbounddominatingcol2;
2375 assert(scip !=
NULL);
2376 assert(matrix !=
NULL);
2377 assert(presoldata !=
NULL);
2378 assert(searchcols !=
NULL);
2379 assert(varstofix !=
NULL);
2380 assert(nfixings !=
NULL);
2381 assert(ndomrelations !=
NULL);
2382 assert(nchgbds !=
NULL);
2385 oldnfixings = *nfixings;
2388 for( cnt1 = 0; cnt1 < searchsize; cnt1++ )
2391 col1 = searchcols[cnt1];
2393 if( varstofix[col1] ==
FIXATLB )
2398 for( cnt2 = cnt1+1; cnt2 < searchsize; cnt2++ )
2401 col2 = searchcols[cnt2];
2414 col1domcol2 = col1domcol2 && (varstofix[col2] ==
NOFIX);
2415 col2domcol1 = col2domcol1 && (varstofix[col1] ==
NOFIX);
2423 col1domcol2 =
FALSE;
2424 col2domcol1 =
FALSE;
2429 if( paircnt == presoldata->numcurrentpairs )
2431 assert(*nfixings >= oldnfixings);
2432 if( *nfixings == oldnfixings )
2435 presoldata->numcurrentpairs >>= 1;
2436 if( presoldata->numcurrentpairs < presoldata->numminpairs )
2437 presoldata->numcurrentpairs = presoldata->numminpairs;
2442 oldnfixings = *nfixings;
2446 presoldata->numcurrentpairs <<= 1;
2447 if( presoldata->numcurrentpairs > presoldata->nummaxpairs )
2448 presoldata->numcurrentpairs = presoldata->nummaxpairs;
2452 if( !col1domcol2 && !col2domcol1 )
2456 vals1 = matrix->colmatval + matrix->colmatbeg[col1];
2457 rows1 = matrix->colmatind + matrix->colmatbeg[col1];
2458 nrows1 = matrix->colmatcnt[col1];
2460 vals2 = matrix->colmatval + matrix->colmatbeg[col2];
2461 rows2 = matrix->colmatind + matrix->colmatbeg[col2];
2462 nrows2 = matrix->colmatcnt[col2];
2466 if( nrows1 == 0 || nrows2 == 0 )
2468 col1domcol2 =
FALSE;
2469 col2domcol1 =
FALSE;
2475 tmpupperbounddominatingcol2 = tmpupperbounddominatingcol1;
2477 tmpwclowerbounddominatingcol2 = tmpwclowerbounddominatingcol1;
2479 tmplowerbounddominatingcol2 = tmplowerbounddominatingcol1;
2481 tmpwcupperbounddominatingcol2 = tmpwcupperbounddominatingcol1;
2485 tmpupperbounddominatedcol2 = tmpupperbounddominatedcol1;
2487 tmpwclowerbounddominatedcol2 = tmpwclowerbounddominatedcol1;
2489 tmplowerbounddominatedcol2 = tmplowerbounddominatedcol1;
2491 tmpwcupperbounddominatedcol2 = tmpwcupperbounddominatedcol1;
2494 while( (col1domcol2 || col2domcol1) && (r1 < nrows1 || r2 < nrows2))
2496 assert((r1 >= nrows1-1) || (rows1[r1] < rows1[r1+1]));
2497 assert((r2 >= nrows2-1) || (rows2[r2] < rows2[r2+1]));
2500 if( r1 < nrows1 && (r2 == nrows2 || rows1[r1] < rows2[r2]) )
2503 if( !matrix->isrhsinfinite[rows1[r1]] )
2506 col2domcol1 =
FALSE;
2507 col1domcol2 =
FALSE;
2512 if( vals1[r1] > 0.0 )
2513 col2domcol1 =
FALSE;
2515 col1domcol2 =
FALSE;
2521 else if( r2 < nrows2 && (r1 == nrows1 || rows1[r1] > rows2[r2]) )
2524 if( !matrix->isrhsinfinite[rows2[r2]] )
2527 col2domcol1 =
FALSE;
2528 col1domcol2 =
FALSE;
2533 if( vals2[r2] < 0.0 )
2534 col2domcol1 =
FALSE;
2536 col1domcol2 =
FALSE;
2544 assert(r1 < nrows1 && r2 < nrows2);
2545 assert(rows1[r1] == rows2[r2]);
2548 if( !matrix->isrhsinfinite[rows1[r1]] )
2551 if( !
SCIPisEQ(scip, vals1[r1], vals2[r2]) )
2553 col2domcol1 =
FALSE;
2554 col1domcol2 =
FALSE;
2559 if( !onlyoneone && (matrix->minactivityposinf[rows1[r1]] + matrix->minactivityneginf[rows1[r1]] == 0)
2560 &&
SCIPisFeasGE(scip, matrix->minactivity[rows1[r1]] +
MIN(vals1[r1], vals2[r2]), matrix->rhs[rows1[r1]]) )
2569 if( vals1[r1] > vals2[r2] )
2570 col2domcol1 =
FALSE;
2571 else if( vals1[r1] < vals2[r2] )
2572 col1domcol2 =
FALSE;
2578 if( !onlyoneone && ((vals1[r1] < 0 && vals2[r2] < 0) || (vals1[r1] > 0 && vals2[r2] > 0)) )
2584 col1, vals1[r1], col2, vals2[r2],
TRUE,
2585 &tmpupperbounddominatingcol1, &tmpwclowerbounddominatingcol1,
2586 &tmplowerbounddominatingcol1, &tmpwcupperbounddominatingcol1) );
2590 col1, vals1[r1], col2, vals2[r2],
FALSE,
2591 &tmpupperbounddominatedcol1, &tmpwclowerbounddominatedcol1,
2592 &tmplowerbounddominatedcol1, &tmpwcupperbounddominatedcol1) );
2599 col2, vals2[r2], col1, vals1[r1],
TRUE,
2600 &tmpupperbounddominatingcol2, &tmpwclowerbounddominatingcol2,
2601 &tmplowerbounddominatingcol2, &tmpwcupperbounddominatingcol2) );
2605 col2, vals2[r2], col1, vals1[r1],
FALSE,
2606 &tmpupperbounddominatedcol2, &tmpwclowerbounddominatedcol2,
2607 &tmplowerbounddominatedcol2, &tmpwcupperbounddominatedcol2) );
2617 col1domcol2 = col1domcol2 && r2 == nrows2;
2618 col2domcol1 = col2domcol1 && r1 == nrows1;
2620 if( !col1domcol2 && !col2domcol1 )
2624 while( r1 < nrows1 )
2626 if( !matrix->isrhsinfinite[rows1[r1]] )
2628 col2domcol1 =
FALSE;
2629 col1domcol2 =
FALSE;
2634 if( !col1domcol2 && !col2domcol1 )
2636 while( r2 < nrows2 )
2638 if( !matrix->isrhsinfinite[rows2[r2]] )
2640 col2domcol1 =
FALSE;
2641 col1domcol2 =
FALSE;
2647 if( col1domcol2 || col2domcol1 )
2650 if( col1domcol2 && col2domcol1 )
2654 col2domcol1 =
FALSE;
2656 col1domcol2 =
FALSE;
2666 tmpupperbounddominatingcol1, tmpwclowerbounddominatingcol1,
2667 tmplowerbounddominatingcol1, tmpwcupperbounddominatingcol1,
2668 matrix->vars[col2], col2,
2669 varstofix, onlybinvars, onlyoneone, nfixings) );
2671 if( presoldata->predbndstr )
2674 tmpupperbounddominatingcol1,
2675 tmplowerbounddominatingcol1, tmpwcupperbounddominatingcol1,
2676 matrix->vars[col2], col2,
2677 tmpupperbounddominatedcol1, tmpwclowerbounddominatedcol1,
2678 tmplowerbounddominatedcol1,
2679 varstofix, nchgbds) );
2682 else if( col2domcol1 )
2685 tmpupperbounddominatingcol2, tmpwclowerbounddominatingcol2,
2686 tmplowerbounddominatingcol2, tmpwcupperbounddominatingcol2,
2687 matrix->vars[col1], col1,
2688 varstofix, onlybinvars, onlyoneone, nfixings) );
2690 if( presoldata->predbndstr )
2693 tmpupperbounddominatingcol2,
2694 tmplowerbounddominatingcol2, tmpwcupperbounddominatingcol2,
2695 matrix->vars[col1], col1,
2696 tmpupperbounddominatedcol2, tmpwclowerbounddominatedcol2,
2697 tmplowerbounddominatedcol2,
2698 varstofix, nchgbds) );
2701 if( varstofix[col1] ==
FIXATLB )
2741 assert(scip !=
NULL);
2742 assert(matrix !=
NULL);
2743 assert(varsprocessed !=
NULL);
2744 assert(varstofix !=
NULL);
2745 assert(nfixings !=
NULL);
2757 for( col = 0; col < matrix->ncols; col++ )
2762 row = *(matrix->colmatind + matrix->colmatbeg[col]);
2763 if( rowprocessed[row] )
2766 rowprocessed[row] =
TRUE;
2768 if( matrix->isrhsinfinite[row] )
2776 rowpnt = matrix->rowmatind + matrix->rowmatbeg[row];
2777 rowend = rowpnt + matrix->rowmatcnt[row];
2778 valpnt = matrix->rowmatval + matrix->rowmatbeg[row];
2780 for( ; (rowpnt < rowend); rowpnt++, valpnt++ )
2784 var = matrix->vars[colidx];
2785 assert(var !=
NULL);
2799 colnozerolb[fillcnt] = 1;
2805 colindices[fillcnt] = colidx;
2806 colcoeffs[fillcnt] = val;
2840 for( k = fillcnt - 1; k >= 0; k-- )
2843 idx = colindices[k];
2846 if( colnozerolb[k] )
2855 if(
SCIPisGE(scip, value, matrix->lhs[row] - constant1 + boundoffset) )
2858 varsprocessed[idx] =
TRUE;
2861 else if(
SCIPisGE(scip, matrix->lhs[row], constant2) )
2864 varsprocessed[idx] =
TRUE;
2869 if( colnozerolb[k] )
2870 constant1 -= boundoffset;
2873 if( colnozerolb[k] )
2874 constant2 -= boundoffset;
2881 if( matrix->isrhsinfinite[row] )
2889 rowpnt = matrix->rowmatind + matrix->rowmatbeg[row];
2890 rowend = rowpnt + matrix->rowmatcnt[row];
2891 valpnt = matrix->rowmatval + matrix->rowmatbeg[row];
2893 for( ; (rowpnt < rowend); rowpnt++, valpnt++ )
2897 var = matrix->vars[colidx];
2898 assert(var !=
NULL);
2913 colnozerolb[fillcnt] = 1;
2917 colindices[fillcnt] = colidx;
2918 colcoeffs[fillcnt] = val;
2954 for( k = 0; k < fillcnt; k++ )
2957 idx = colindices[k];
2960 if( colnozerolb[k] )
2969 if(
SCIPisLE(scip, value, matrix->lhs[row] - constant1 + boundoffset) )
2972 varsprocessed[idx] =
TRUE;
2975 else if(
SCIPisLE(scip, matrix->lhs[row], constant2) )
2978 varsprocessed[idx] =
TRUE;
2983 if( colnozerolb[k] )
2984 constant1 -= boundoffset;
2987 if( colnozerolb[k] )
2988 constant2 -= boundoffset;
3009 #ifdef SCIP_STATISTIC
3018 assert(presoldata !=
NULL);
3020 printf(
"### Stuffing: %d fixings ###\n",presoldata->nfixingsstuffing);
3021 printf(
"### Domcol: %d fixings ###\n", presoldata->nfixingsdomcol);
3023 presoldata->nfixingsstuffing = 0;
3024 presoldata->nfixingsdomcol = 0;
3034 assert(scip !=
NULL);
3035 assert(presol !=
NULL);
3052 assert(presoldata !=
NULL);
3068 assert(result !=
NULL);
3080 assert(presoldata !=
NULL);
3084 initialized =
FALSE;
3090 int nfixingsstuffing;
3108 int nconvarsfixed = 0;
3109 int nintvarsfixed = 0;
3110 int nbinvarsfixed = 0;
3121 nfixingsstuffing = 0;
3123 nvars = matrix->ncols;
3124 nrows = matrix->nrows;
3137 for( r = 0; r < nrows; ++r )
3139 rowidxsorted[r] = r;
3140 rowsparsity[r] = matrix->rowmatcnt[r];
3146 for( v = 0; v < nvars; v++ )
3153 presoldata->numcurrentpairs = presoldata->nummaxpairs;
3159 if( presoldata->singcolstuffing )
3162 #ifdef SCIP_STATISTIC
3163 presoldata->nfixingsstuffing += nfixingsstuffing;
3187 pclassstart = pclass[pc];
3188 while( pc < nvars && pclassstart == pclass[pc] )
3190 varidx = colidx[pc];
3193 if( !varsprocessed[varidx] && varineq[varidx] )
3198 consearchcols[nconfill++] = varidx;
3202 binsearchcols[nbinfill++] = varidx;
3207 intsearchcols[nintfill++] = varidx;
3217 varstofix, &nfixings, &ndomrelations, nchgbds) );
3219 for( v = 0; v < nconfill; ++v )
3220 varsprocessed[consearchcols[v]] =
TRUE;
3222 varcount += nconfill;
3224 else if( nconfill == 1 )
3226 if( varineq[varidx] )
3227 varsprocessed[consearchcols[0]] =
TRUE;
3234 varstofix, &nfixings, &ndomrelations, nchgbds) );
3236 for( v = 0; v < nintfill; ++v )
3237 varsprocessed[intsearchcols[v]] =
TRUE;
3239 varcount += nintfill;
3241 else if( nintfill == 1 )
3243 if( varineq[varidx] )
3244 varsprocessed[intsearchcols[0]] =
TRUE;
3251 varstofix, &nfixings, &ndomrelations, nchgbds) );
3253 for( v = 0; v < nbinfill; ++v )
3254 varsprocessed[binsearchcols[v]] =
TRUE;
3256 varcount += nbinfill;
3258 else if( nbinfill == 1 )
3260 if( varineq[varidx] )
3261 varsprocessed[binsearchcols[0]] =
TRUE;
3265 if( varcount >= nvars )
3277 for( r = 0; r < nrows; ++r )
3289 rowidx = rowidxsorted[r];
3290 rowpnt = matrix->rowmatind + matrix->rowmatbeg[rowidx];
3291 rowend = rowpnt + matrix->rowmatcnt[rowidx];
3293 if( matrix->rowmatcnt[rowidx] == 1 )
3300 for( ; rowpnt < rowend; rowpnt++ )
3302 if( !(varsprocessed[*rowpnt]) )
3310 consearchcols[nconfill++] = varidx;
3314 binsearchcols[nbinfill++] = varidx;
3319 intsearchcols[nintfill++] = varidx;
3328 varstofix, &nfixings, &ndomrelations, nchgbds) );
3330 for( v = 0; v < nconfill; ++v )
3331 varsprocessed[consearchcols[v]] =
TRUE;
3333 varcount += nconfill;
3340 varstofix, &nfixings, &ndomrelations, nchgbds) );
3342 for( v = 0; v < nintfill; ++v )
3343 varsprocessed[intsearchcols[v]] =
TRUE;
3345 varcount += nintfill;
3352 varstofix, &nfixings, &ndomrelations, nchgbds) );
3354 for( v = 0; v < nbinfill; ++v )
3355 varsprocessed[binsearchcols[v]] =
TRUE;
3357 varcount += nbinfill;
3361 if( varcount >= nvars )
3366 #ifdef SCIP_STATISTIC
3367 presoldata->nfixingsdomcol += nfixings;
3370 if( (nfixings + nfixingsstuffing) > 0 )
3372 int oldnfixedvars = *nfixedvars;
3375 for( v = matrix->ncols - 1; v >= 0; --v )
3392 var = matrix->vars[v];
3426 else if( varstofix[v] ==
FIXATUB )
3430 var = matrix->vars[v];
3467 if( *result !=
SCIP_CUTOFF && *nfixedvars > oldnfixedvars )
3483 if( (nconvarsfixed + nintvarsfixed + nbinvarsfixed) > 0 )
3485 SCIPdebugMessage(
"### %d vars [%lld dom] ===>>> fixed [cont: %d, int: %d, bin: %d], %scutoff detected\n",
3486 matrix->ncols, ndomrelations, nconvarsfixed, nintvarsfixed, nbinvarsfixed, (*result !=
SCIP_CUTOFF) ?
"no " :
"");
3517 #ifdef SCIP_STATISTIC
3518 presoldata->nfixingsstuffing = 0;
3519 presoldata->nfixingsdomcol = 0;
3524 "presolving/domcol/numminpairs",
3525 "minimal number of pair comparisons",
3529 "presolving/domcol/nummaxpairs",
3530 "maximal number of pair comparisons",
3534 "presolving/domcol/predbndstr",
3535 "should predictive bound strengthening be applied?",
3539 "presolving/domcol/singcolstuffing",
3540 "should singleton columns stuffing be applied?",