71#define PRESOL_NAME "tworowbnd"
72#define PRESOL_DESC "do bound tigthening by using two rows"
73#define PRESOL_PRIORITY -2000
74#define PRESOL_MAXROUNDS 0
75#define PRESOL_TIMING SCIP_PRESOLTIMING_EXHAUSTIVE
77#define DEFAULT_ENABLECOPY TRUE
78#define DEFAULT_MAXCONSIDEREDNONZEROS 100
79#define DEFAULT_MAXRETRIEVEFAILS 1000
80#define DEFAULT_MAXCOMBINEFAILS 1000
81#define DEFAULT_MAXHASHFAC 10
82#define DEFAULT_MAXPAIRFAC 1
95 int maxconsiderednonzeros;
121 uint64_t
a = (uint64_t)(
long)rowpair->
row1idx;
122 uint64_t
b = (uint64_t)(
long)rowpair->
row2idx;
123 return (
void*)((
a << 32) |
b);
134 return (
int)(hash >> 1);
149 if( (*pos) >= (*listsize) )
154 (*listsize) = newsize;
157 (*hashlist)[(*pos)] = hash;
158 (*rowidxlist)[(*pos)] = rowidx;
181 while(
i < len && list[
i] == list[
i - 1] )
218#ifdef SCIP_DEBUG_SINGLEROWLP
227 for(
i = 0;
i < len;
i++)
270 mincost =
MIN(mincost,
c[
i] /
a[
i]);
271 maxgain =
MAX(maxgain,
c[
i] /
a[
i]);
298 mincost =
MIN(mincost,
c[
i]/
a[
i]);
310 maxgain =
MAX(maxgain,
c[
i] /
a[
i]);
378#ifdef SCIP_DEBUG_SINGLEROWLP
379 SCIPdebugMsg(
scip,
"After preprocessing: obj = %g, b = %g, nvars = %d, mincost = %g, maxgain = %g\n", (*
obj),
b,
nvars, mincost, maxgain);
402 (*obj) +=
c[
i] *
a[
i];
407 (*obj) += mincost *
b;
439 (*obj) +=
c[
i] *
a[
i];
451 (*obj) += maxgain *
b;
457#ifdef SCIP_DEBUG_SINGLEROWLP
466 (*obj) += mincost *
b;
479#ifdef SCIP_DEBUG_SINGLEROWLP
486#ifdef SCIP_DEBUG_SINGLEROWLP
493 for(
i = 0;
i < k;
i++ )
495 (*obj) +=
c[
i] *
a[
i];
499#ifdef SCIP_DEBUG_SINGLEROWLP
515#ifdef SCIP_DEBUG_SINGLEROWLP
518 (*obj) += mincost *
b;
617 while(
i < row1len && j < row2len )
619 idx1 = row1idxptr[
i];
620 idx2 = row2idxptr[j];
624 coriginal[
nvars] = row1valptr[
i];
625 aoriginal[
nvars] = row2valptr[j];
626 newlbsoriginal[
nvars] = lbs[idx1];
627 newubsoriginal[
nvars] = ubs[idx1];
628 cangetbnd[idx1] =
FALSE;
633 ubs[idx1], row1valptr[
i], row2valptr[j],
nvars);
638 else if( idx1 < idx2 )
645 maxact -= row1valptr[
i] * ubs[idx1];
650 minact -= row1valptr[
i] * lbs[idx1];
657 maxact -= row1valptr[
i] * lbs[idx1];
662 minact -= row1valptr[
i] * ubs[idx1];
664 cangetbnd[idx1] =
TRUE;
666 if( maxinfs > 1 && mininfs > 1 )
673 SCIPdebugMsg(
scip,
"%g <= (%s) <= %g has coefs %g and 0.0, minact = %g, maxact = %g\n",
675 ubs[idx1], row1valptr[
i], minact, maxact);
680 coriginal[
nvars] = 0.0;
681 aoriginal[
nvars] = row2valptr[j];
682 newlbsoriginal[
nvars] = lbs[idx2];
683 newubsoriginal[
nvars] = ubs[idx2];
684 cangetbnd[idx2] =
FALSE;
689 ubs[idx2], row2valptr[j],
nvars);
696 idx1 = row1idxptr[
i];
702 maxact -= row1valptr[
i] * ubs[idx1];
707 minact -= row1valptr[
i] * lbs[idx1];
714 maxact -= row1valptr[
i] * lbs[idx1];
719 minact -= row1valptr[
i] * ubs[idx1];
721 cangetbnd[idx1] =
TRUE;
723 SCIPdebugMsg(
scip,
"%g <= (%s) <= %g has coefs %g and 0.0, minact = %g, maxact = %g\n",
725 ubs[idx1], row1valptr[
i], minact, maxact);
731 idx2 = row2idxptr[j];
732 coriginal[
nvars] = 0.0;
733 aoriginal[
nvars] = row2valptr[j];
734 newlbsoriginal[
nvars] = lbs[idx2];
735 newubsoriginal[
nvars] = ubs[idx2];
740 ubs[idx2], row2valptr[j],
nvars);
753 maxswapsolvable =
FALSE;
754 minswapsolvable =
FALSE;
760 acopy[
i] = aoriginal[
i];
761 ccopy[
i] = -coriginal[
i];
762 newlbscopy[
i] = newlbsoriginal[
i];
763 newubscopy[
i] = newubsoriginal[
i];
766 ccopy, newlbscopy, newubscopy,
nvars, &maxobj, &maxsolvable) );
773 if( mininfs == 0 || (mininfs == 1 && swaprow1) )
778 acopy[
i] = aoriginal[
i];
779 ccopy[
i] = coriginal[
i];
780 newlbscopy[
i] = newlbsoriginal[
i];
781 newubscopy[
i] = newubsoriginal[
i];
784 ccopy, newlbscopy, newubscopy,
nvars, &
minobj, &minsolvable) );
798 acopy[
i] = -aoriginal[
i];
799 ccopy[
i] = -coriginal[
i];
800 newlbscopy[
i] = newlbsoriginal[
i];
801 newubscopy[
i] = newubsoriginal[
i];
804 ccopy, newlbscopy, newubscopy,
nvars, &maxswapobj, &maxswapsolvable) );
811 if( mininfs == 0 || (mininfs == 1 && swaprow1) )
816 acopy[
i] = -aoriginal[
i];
817 ccopy[
i] = coriginal[
i];
818 newlbscopy[
i] = newlbsoriginal[
i];
819 newubscopy[
i] = newubsoriginal[
i];
822 ccopy, newlbscopy, newubscopy,
nvars, &minswapobj, &minswapsolvable) );
830 if( maxinfs <= 1 && (maxsolvable || maxswapsolvable) )
834 if( maxsolvable && maxswapsolvable )
836 else if( maxsolvable )
844 (*infeasible) =
TRUE;
849 else if( maxinfs == 0 )
851 for(
i = 0;
i < row1len;
i++ )
853 idx1 = row1idxptr[
i];
854 if( cangetbnd[idx1] )
859 newbnd =
SCIPceil(
scip, (activity + row1valptr[
i] * ubs[idx1]) / row1valptr[
i]);
861 newbnd = (activity + row1valptr[
i] * ubs[idx1]) / row1valptr[
i];
865#ifdef SCIP_DEBUG_BOUNDS
877 newbnd =
SCIPfloor(
scip, (activity + row1valptr[
i] * lbs[idx1]) / row1valptr[
i]);
879 newbnd = (activity + row1valptr[
i] * lbs[idx1]) / row1valptr[
i];
883#ifdef SCIP_DEBUG_BOUNDS
898 for(
i = 0;
i < row1len;
i++ )
900 idx1 = row1idxptr[
i];
901 if( cangetbnd[idx1] )
908 newbnd = activity / row1valptr[
i];
912#ifdef SCIP_DEBUG_BOUNDS
926 newbnd = activity / row1valptr[
i];
930#ifdef SCIP_DEBUG_BOUNDS
947 if( mininfs <= 1 && (minsolvable || minswapsolvable) )
952 if( minsolvable && minswapsolvable )
954 else if( minsolvable )
962 (*infeasible) =
TRUE;
967 else if( mininfs == 0 )
969 for(
i = 0;
i < row1len;
i++ )
971 idx1 = row1idxptr[
i];
972 if( cangetbnd[idx1] )
977 newbnd =
SCIPceil(
scip, (activity - row1valptr[
i] * ubs[idx1]) / (-row1valptr[
i]));
979 newbnd = (activity - row1valptr[
i] * ubs[idx1]) / (-row1valptr[
i]);
983#ifdef SCIP_DEBUG_BOUNDS
996 newbnd =
SCIPfloor(
scip, (activity - row1valptr[
i] * lbs[idx1]) / (-row1valptr[
i]));
998 newbnd = (activity - row1valptr[
i] * lbs[idx1]) / (-row1valptr[
i]);
1002#ifdef SCIP_DEBUG_BOUNDS
1017 for(
i = 0;
i < row1len;
i++ )
1019 idx1 = row1idxptr[
i];
1020 if( cangetbnd[idx1] )
1028 newbnd = activity / (-row1valptr[
i]);
1032#ifdef SCIP_DEBUG_BOUNDS
1046 newbnd = activity / (-row1valptr[
i]);
1050#ifdef SCIP_DEBUG_BOUNDS
1092#ifdef SCIP_DEBUG_2RB
1116 coriginal, ccopy, cangetbnd, lbs, ubs, newlbsoriginal, newlbscopy,
1117 newubsoriginal, newubscopy, success, &infeasible) );
1121 coriginal, ccopy, cangetbnd, lbs, ubs, newlbsoriginal, newlbscopy,
1122 newubsoriginal, newubscopy, success, &infeasible) );
1184 findNextBlock(hashlist1, lenhashlist1, &block1start, &block1end);
1185 findNextBlock(hashlist2, lenhashlist2, &block2start, &block2end);
1188 if( hashlist1[block1start] == hashlist2[block2start] )
1190 for(
i = block1start;
i < block1end;
i++ )
1192 for( j = block2start; j < block2end; j++ )
1194 if( rowidxlist1[
i] != rowidxlist2[j] )
1196 rowpair.
row1idx =
MIN(rowidxlist1[
i], rowidxlist2[j]);
1197 rowpair.
row2idx =
MAX(rowidxlist1[
i], rowidxlist2[j]);
1210 swaprow1, swaprow2, newlbs, newubs, &success) );
1220 if( ncombines >= maxcombines || combinefails >= presoldata->maxcombinefails )
1225 else if( retrievefails < presoldata->maxretrievefails )
1243 if( block1end < lenhashlist1 && block2end < lenhashlist2 )
1245 findNextBlock(hashlist1, lenhashlist1, &block1start, &block1end);
1246 findNextBlock(hashlist2, lenhashlist2, &block2start, &block2end);
1251 else if( hashlist1[block1start] < hashlist2[block2start] && block1end < lenhashlist1 )
1252 findNextBlock(hashlist1, lenhashlist1, &block1start, &block1end);
1253 else if( hashlist1[block1start] > hashlist2[block2start] && block2end < lenhashlist2 )
1254 findNextBlock(hashlist2, lenhashlist2, &block2start, &block2end);
1283 if( presoldata->enablecopy )
1314 presoldata->nchgbnds = 0;
1315 presoldata->nuselessruns = 0;
1379 if( presoldata->nuselessruns >= 5 )
1386 naddconss, ndelconss, nchgcoefs, nchgbds, nfixedvars) );
1431 for(
i = 0;
i < nrows;
i++)
1433 if( ((
SCIP_Longint)pospp) + posmm + pospm + posmp > maxhashes )
1440 for( j = 0; j < maxlen; j++)
1442 for( k = j+1; k < maxlen; k++)
1486#ifdef SCIP_DEBUG_HASHING
1488 for(
i = 0;
i < pospp;
i++)
1491 for(
i = 0;
i < posmm;
i++)
1494 for(
i = 0;
i < pospm;
i++)
1497 for(
i = 0;
i < posmp;
i++)
1500 SCIPdebugMsg(
scip,
"hashlist sizes: pp %d, mm %d, pm %d, mp %d \n", pospp, posmm, pospm, posmp);
1507#ifdef SCIP_DEBUG_HASHING
1509 for(
i = 0;
i < pospp;
i++)
1512 for(
i = 0;
i < posmm;
i++)
1515 for(
i = 0;
i < pospm;
i++)
1518 for(
i = 0;
i < posmp;
i++)
1532 newlbs[
i] = oldlbs[
i];
1533 newubs[
i] = oldubs[
i];
1537 if( pospp > 0 && posmm > 0 )
1541 rowidxlistmm, newlbs, newubs) );
1545 if( pospm > 0 && posmp > 0 )
1549 rowidxlistmp, newlbs, newubs) );
1553 oldnchgbds = *nchgbds;
1554 oldnfixedvars = *nfixedvars;
1592 if( bndwastightened )
1609 if( bndwastightened )
1618 if( *nchgbds > oldnchgbds || *nfixedvars > oldnfixedvars )
1621 presoldata->nuselessruns = 0;
1623 else if( infeasible )
1629 presoldata->nuselessruns++;
1670 presolExecTworowbnd,
1681 "presolving/tworowbnd/enablecopy",
1682 "should tworowbnd presolver be copied to sub-SCIPs?",
1685 "presolving/tworowbnd/maxconsiderednonzeros",
1686 "maximal number of considered non-zeros within one row (-1: no limit)",
1689 "presolving/tworowbnd/maxretrievefails",
1690 "maximal number of consecutive useless hashtable retrieves",
1693 "presolving/tworowbnd/maxcombinefails",
1694 "maximal number of consecutive useless row combines",
1697 "presolving/tworowbnd/maxhashfac",
1698 "Maximum number of hashlist entries as multiple of number of rows in the problem (-1: no limit)",
1701 "presolving/tworowbnd/maxpairfac",
1702 "Maximum number of processed row pairs as multiple of the number of rows in the problem (-1: no limit)",
Constraint handler for linear constraints in their most general form, .
#define SCIP_STRINGEQ(name, reference, retcode)
SCIP_Bool SCIPisStopped(SCIP *scip)
void SCIPhashsetFree(SCIP_HASHSET **hashset, BMS_BLKMEM *blkmem)
SCIP_Bool SCIPhashsetExists(SCIP_HASHSET *hashset, void *element)
SCIP_RETCODE SCIPhashsetInsert(SCIP_HASHSET *hashset, BMS_BLKMEM *blkmem, void *element)
SCIP_RETCODE SCIPhashsetCreate(SCIP_HASHSET **hashset, BMS_BLKMEM *blkmem, int size)
#define SCIPhashTwo(a, b)
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)
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)
SCIP_RETCODE SCIPincludePresolTworowbnd(SCIP *scip)
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
int SCIPcalcMemGrowSize(SCIP *scip, int num)
#define SCIPallocBufferArray(scip, ptr, num)
#define SCIPfreeBufferArray(scip, ptr)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
#define SCIPfreeBlockMemory(scip, ptr)
#define SCIPallocBlockMemory(scip, ptr)
SCIP_RETCODE SCIPsetPresolFree(SCIP *scip, SCIP_PRESOL *presol,)
void SCIPpresolSetData(SCIP_PRESOL *presol, SCIP_PRESOLDATA *presoldata)
SCIP_PRESOLDATA * SCIPpresolGetData(SCIP_PRESOL *presol)
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol,)
SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
SCIP_RETCODE SCIPsetPresolInit(SCIP *scip, SCIP_PRESOL *presol,)
const char * SCIPpresolGetName(SCIP_PRESOL *presol)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
SCIP_Bool SCIPvarIsNonimpliedIntegral(SCIP_VAR *var)
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
const char * SCIPvarGetName(SCIP_VAR *var)
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
void SCIPselectWeightedReal(SCIP_Real *realarray, SCIP_Real *weights, SCIP_Real capacity, int len, int *medianpos)
void SCIPsortIntInt(int *intarray1, int *intarray2, int len)
void SCIPsortIntReal(int *intarray, SCIP_Real *realarray, int len)
assert(minobj< SCIPgetCutoffbound(scip))
int SCIPmatrixGetRowNNonzs(SCIP_MATRIX *matrix, int row)
const char * SCIPmatrixGetRowName(SCIP_MATRIX *matrix, int row)
SCIP_Real SCIPmatrixGetRowLhs(SCIP_MATRIX *matrix, int row)
const char * SCIPmatrixGetColName(SCIP_MATRIX *matrix, int col)
SCIP_Real * SCIPmatrixGetRowValPtr(SCIP_MATRIX *matrix, int row)
SCIP_Real SCIPmatrixGetRowRhs(SCIP_MATRIX *matrix, int row)
SCIP_RETCODE SCIPmatrixCreate(SCIP *scip, SCIP_MATRIX **matrixptr, SCIP_Bool onlyifcomplete, SCIP_Bool *initialized, SCIP_Bool *complete, SCIP_Bool *infeasible, int *naddconss, int *ndelconss, int *nchgcoefs, int *nchgbds, int *nfixedvars)
int SCIPmatrixGetNColumns(SCIP_MATRIX *matrix)
void SCIPmatrixFree(SCIP *scip, SCIP_MATRIX **matrix)
SCIP_VAR * SCIPmatrixGetVar(SCIP_MATRIX *matrix, int col)
int * SCIPmatrixGetRowIdxPtr(SCIP_MATRIX *matrix, int row)
int SCIPmatrixGetNRows(SCIP_MATRIX *matrix)
#define DEFAULT_MAXCONSIDEREDNONZEROS
#define DEFAULT_MAXHASHFAC
#define DEFAULT_MAXCOMBINEFAILS
#define DEFAULT_MAXRETRIEVEFAILS
#define DEFAULT_MAXPAIRFAC
#define DEFAULT_ENABLECOPY
static SCIP_RETCODE addEntry(SCIP *scip, int *pos, int *listsize, int **hashlist, int **rowidxlist, int hash, int rowidx)
static SCIP_RETCODE transformAndSolve(SCIP *scip, SCIP_MATRIX *matrix, int row1idx, int row2idx, SCIP_Bool swaprow1, SCIP_Bool swaprow2, SCIP_Real *aoriginal, SCIP_Real *acopy, SCIP_Real *coriginal, SCIP_Real *ccopy, SCIP_Bool *cangetbnd, SCIP_Real *lbs, SCIP_Real *ubs, SCIP_Real *newlbsoriginal, SCIP_Real *newlbscopy, SCIP_Real *newubsoriginal, SCIP_Real *newubscopy, SCIP_Bool *success, SCIP_Bool *infeasible)
static int hashIndexPair(int idx1, int idx2)
static SCIP_RETCODE solveSingleRowLP(SCIP *scip, SCIP_Real *a, SCIP_Real b, SCIP_Real *c, SCIP_Real *lbs, SCIP_Real *ubs, int len, SCIP_Real *obj, SCIP_Bool *solvable)
static SCIP_RETCODE processHashlists(SCIP *scip, SCIP_PRESOLDATA *presoldata, SCIP_MATRIX *matrix, int *hashlist1, int *hashlist2, int lenhashlist1, int lenhashlist2, int *rowidxlist1, int *rowidxlist2, SCIP_Real *newlbs, SCIP_Real *newubs)
static void * encodeRowPair(ROWPAIR *rowpair)
static void findNextBlock(int *list, int len, int *start, int *end)
static SCIP_RETCODE applyLPboundTightening(SCIP *scip, SCIP_MATRIX *matrix, int row1, int row2, SCIP_Bool swaprow1, SCIP_Bool swaprow2, SCIP_Real *lbs, SCIP_Real *ubs, SCIP_Bool *success)
do bound tightening by using two rows
public methods for matrix
struct SCIP_Matrix SCIP_MATRIX
struct SCIP_HashSet SCIP_HASHSET
#define SCIP_DECL_PRESOLCOPY(x)
struct SCIP_PresolData SCIP_PRESOLDATA
#define SCIP_DECL_PRESOLFREE(x)
struct SCIP_Presol SCIP_PRESOL
#define SCIP_DECL_PRESOLINIT(x)
#define SCIP_DECL_PRESOLEXEC(x)
enum SCIP_Retcode SCIP_RETCODE