From f94244e4186d4dc1ba43ed0d4d3c61086cfca791 Mon Sep 17 00:00:00 2001 From: Dominik Kamp Date: Mon, 22 Jan 2024 10:19:39 +0100 Subject: [PATCH 1/5] Filter farkas solutions --- src/scip/conflict_general.c | 41 +++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/scip/conflict_general.c b/src/scip/conflict_general.c index 4aafd690dd..6b367eb6dd 100644 --- a/src/scip/conflict_general.c +++ b/src/scip/conflict_general.c @@ -1173,6 +1173,7 @@ SCIP_RETCODE SCIPgetFarkasProof( SCIP_ROW* row; int* localrowinds; int* localrowdepth; + SCIP_Real large; SCIP_Bool infdelta; int nlocalrows; int nrows; @@ -1201,7 +1202,7 @@ SCIP_RETCODE SCIPgetFarkasProof( */ if( !SCIPlpiHasDualRay(lpi) ) { - *valid = FALSE; + (*valid) = FALSE; return SCIP_OKAY; } @@ -1210,13 +1211,23 @@ SCIP_RETCODE SCIPgetFarkasProof( /* allocate temporary memory */ SCIP_CALL( SCIPsetAllocBufferArray(set, &dualfarkas, nrows) ); BMSclearMemoryArray(dualfarkas, nrows); + localrowinds = NULL; + localrowdepth = NULL; + nlocalrows = 0; /* get dual Farkas values of rows */ SCIP_CALL( SCIPlpiGetDualfarkas(lpi, dualfarkas) ); - localrowinds = NULL; - localrowdepth = NULL; - nlocalrows = 0; + /* check whether the Farkas solution is numerically stable */ + large = 1.0 / SCIPsetEpsilon(set); + for( r = 0; r < nrows; ++r ) + { + if( ABS(dualfarkas[r]) > large ) + { + (*valid) = FALSE; + goto TERMINATE; + } + } /* calculate the Farkas row */ (*valid) = TRUE; @@ -1347,7 +1358,7 @@ SCIP_RETCODE SCIPgetDualProof( SCIP_Real* redcosts; int* localrowinds; int* localrowdepth; - SCIP_Real maxabsdualsol; + SCIP_Real large; SCIP_Bool infdelta; int nlocalrows; int nrows; @@ -1399,20 +1410,14 @@ SCIP_RETCODE SCIPgetDualProof( #endif /* check whether the dual solution is numerically stable */ - maxabsdualsol = 0; - for( r = 0; r < nrows; r++ ) - { - SCIP_Real absdualsol = REALABS(dualsols[r]); - - if( absdualsol > maxabsdualsol ) - maxabsdualsol = absdualsol; - } - - /* don't consider dual solution with maxabsdualsol > 1e+07, this would almost cancel out the objective constraint */ - if( maxabsdualsol > 1e+07 ) + large = 1.0 / SCIPsetEpsilon(set); + for( r = 0; r < nrows; ++r ) { - (*valid) = FALSE; - goto TERMINATE; + if( ABS(dualsols[r]) > large ) + { + (*valid) = FALSE; + goto TERMINATE; + } } /* clear the proof */ From 88c2046c017a5527d60f668e9bb6876114477570 Mon Sep 17 00:00:00 2001 From: Dominik Kamp Date: Tue, 23 Jan 2024 18:15:07 +0100 Subject: [PATCH 2/5] Filter solutions tighter --- src/scip/conflict_general.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scip/conflict_general.c b/src/scip/conflict_general.c index 6b367eb6dd..d61cc1615c 100644 --- a/src/scip/conflict_general.c +++ b/src/scip/conflict_general.c @@ -1219,7 +1219,7 @@ SCIP_RETCODE SCIPgetFarkasProof( SCIP_CALL( SCIPlpiGetDualfarkas(lpi, dualfarkas) ); /* check whether the Farkas solution is numerically stable */ - large = 1.0 / SCIPsetEpsilon(set); + large = 1.0 / SCIPsetSumepsilon(set); for( r = 0; r < nrows; ++r ) { if( ABS(dualfarkas[r]) > large ) @@ -1410,7 +1410,7 @@ SCIP_RETCODE SCIPgetDualProof( #endif /* check whether the dual solution is numerically stable */ - large = 1.0 / SCIPsetEpsilon(set); + large = 1.0 / SCIPsetSumepsilon(set); for( r = 0; r < nrows; ++r ) { if( ABS(dualsols[r]) > large ) From 3f1cd3dc360deda28194d961c122bf95309c7cbd Mon Sep 17 00:00:00 2001 From: Dominik Kamp Date: Tue, 26 Mar 2024 22:58:46 +0100 Subject: [PATCH 3/5] Hardcode numerical limit --- src/scip/conflict_general.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/scip/conflict_general.c b/src/scip/conflict_general.c index d61cc1615c..6d47d55e52 100644 --- a/src/scip/conflict_general.c +++ b/src/scip/conflict_general.c @@ -1173,7 +1173,6 @@ SCIP_RETCODE SCIPgetFarkasProof( SCIP_ROW* row; int* localrowinds; int* localrowdepth; - SCIP_Real large; SCIP_Bool infdelta; int nlocalrows; int nrows; @@ -1202,7 +1201,7 @@ SCIP_RETCODE SCIPgetFarkasProof( */ if( !SCIPlpiHasDualRay(lpi) ) { - (*valid) = FALSE; + *valid = FALSE; return SCIP_OKAY; } @@ -1219,19 +1218,18 @@ SCIP_RETCODE SCIPgetFarkasProof( SCIP_CALL( SCIPlpiGetDualfarkas(lpi, dualfarkas) ); /* check whether the Farkas solution is numerically stable */ - large = 1.0 / SCIPsetSumepsilon(set); for( r = 0; r < nrows; ++r ) { - if( ABS(dualfarkas[r]) > large ) + if( REALABS(dualfarkas[r]) > 1e+7 ) { - (*valid) = FALSE; + *valid = FALSE; goto TERMINATE; } } /* calculate the Farkas row */ - (*valid) = TRUE; - (*validdepth) = 0; + *valid = TRUE; + *validdepth = 0; for( r = 0; r < nrows; ++r ) { @@ -1265,7 +1263,7 @@ SCIP_RETCODE SCIPgetFarkasProof( /* due to numerical reasons we want to stop */ if( REALABS(SCIPaggrRowGetRhs(farkasrow)) > NUMSTOP ) { - (*valid) = FALSE; + *valid = FALSE; goto TERMINATE; } } @@ -1321,7 +1319,7 @@ SCIP_RETCODE SCIPgetFarkasProof( } else { - (*valid) = FALSE; + *valid = FALSE; SCIPsetDebugMsg(set, " -> proof is not valid to due infinite activity delta\n"); } } @@ -1358,7 +1356,6 @@ SCIP_RETCODE SCIPgetDualProof( SCIP_Real* redcosts; int* localrowinds; int* localrowdepth; - SCIP_Real large; SCIP_Bool infdelta; int nlocalrows; int nrows; @@ -1397,7 +1394,7 @@ SCIP_RETCODE SCIPgetDualProof( retcode = SCIPlpiGetSol(lpi, NULL, primsols, dualsols, NULL, redcosts); if( retcode == SCIP_LPERROR ) /* on an error in the LP solver, just abort the conflict analysis */ { - (*valid) = FALSE; + *valid = FALSE; goto TERMINATE; } SCIP_CALL( retcode ); @@ -1410,12 +1407,11 @@ SCIP_RETCODE SCIPgetDualProof( #endif /* check whether the dual solution is numerically stable */ - large = 1.0 / SCIPsetSumepsilon(set); for( r = 0; r < nrows; ++r ) { - if( ABS(dualsols[r]) > large ) + if( REALABS(dualsols[r]) > 1e+7 ) { - (*valid) = FALSE; + *valid = FALSE; goto TERMINATE; } } @@ -1482,7 +1478,7 @@ SCIP_RETCODE SCIPgetDualProof( /* due to numerical reasons we want to stop */ if( REALABS(SCIPaggrRowGetRhs(farkasrow)) > NUMSTOP ) { - (*valid) = FALSE; + *valid = FALSE; goto TERMINATE; } } @@ -1538,7 +1534,7 @@ SCIP_RETCODE SCIPgetDualProof( } else { - (*valid) = FALSE; + *valid = FALSE; SCIPsetDebugMsg(set, " -> proof is not valid to due infinite activity delta\n"); } } From 20fbeec053ca30102c0e4732f0e710e3b880b08b Mon Sep 17 00:00:00 2001 From: Dominik Kamp Date: Wed, 27 Mar 2024 17:34:42 +0100 Subject: [PATCH 4/5] Define solution stop --- src/scip/conflict_general.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/scip/conflict_general.c b/src/scip/conflict_general.c index 6d47d55e52..d838fe5224 100644 --- a/src/scip/conflict_general.c +++ b/src/scip/conflict_general.c @@ -94,6 +94,10 @@ * 2^53 = 9007199254740992 */ #define NUMSTOP 9007199254740992.0 +/* because row violations might be magnified, we stop the infeasibility analysis if a dual weight is bigger than + * 10^7 = 10000000 + */ +#define SOLSTOP 10000000.0 /** returns the current number of conflict sets in the conflict set storage */ int SCIPconflictGetNConflicts( @@ -1220,7 +1224,7 @@ SCIP_RETCODE SCIPgetFarkasProof( /* check whether the Farkas solution is numerically stable */ for( r = 0; r < nrows; ++r ) { - if( REALABS(dualfarkas[r]) > 1e+7 ) + if( REALABS(dualfarkas[r]) > SOLSTOP ) { *valid = FALSE; goto TERMINATE; @@ -1409,7 +1413,7 @@ SCIP_RETCODE SCIPgetDualProof( /* check whether the dual solution is numerically stable */ for( r = 0; r < nrows; ++r ) { - if( REALABS(dualsols[r]) > 1e+7 ) + if( REALABS(dualsols[r]) > SOLSTOP ) { *valid = FALSE; goto TERMINATE; From 4db116f7033f3020ff12a9d70d697b6fe07db66e Mon Sep 17 00:00:00 2001 From: Dominik Kamp Date: Wed, 27 Mar 2024 17:39:46 +0100 Subject: [PATCH 5/5] Add bugfix to changelog --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index 50abbd4a52..9a7627246c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,7 @@ Fixed bugs - in SCIPsolveProbingLP() when objective has been changed do not return cutoff due to exceeding the cutoff bound - set probing LP to be a relaxation only when objective has not been changed - declare contradicting infinities in getMinActivity() and getMaxActivity() as non-tight +- reject farkas solution with large values to bound magnification of errors in SCIPgetFarkasProof() Miscellaneous -------------