diff --git a/CHANGELOG b/CHANGELOG index a5093a743f..63b87bb46f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -90,6 +90,10 @@ Known bugs Features -------- +- added check for absolute and relative gap limits at end of synchronization in concurrent solving mode, in order to terminate earlier; + note that if the concurrent solve is stopped due to a gap limit, the "winner" solver will have an interrupted solution status and + its primal and dual bounds may not be the best possible ones (use SCIPgetConcurrentPrimalbound() and SCIPgetConcurrentDualbound() instead) + Performance improvements ------------------------ diff --git a/src/scip/struct_syncstore.h b/src/scip/struct_syncstore.h index d80b267f96..1a89988e31 100644 --- a/src/scip/struct_syncstore.h +++ b/src/scip/struct_syncstore.h @@ -57,6 +57,8 @@ struct SCIP_SyncStore * by all threads */ SCIP* mainscip; /**< the SCIP instance that was used for initializing the syncstore */ + SCIP_Real limit_gap; /**< relative gap limit in main SCIP */ + SCIP_Real limit_absgap; /**< absolute gap limit in main SCIP */ SCIP_Bool stopped; /**< flag to indicate if the solving is stopped */ SCIP_LOCK* lock; /**< lock to protect the syncstore data structure from data races */ diff --git a/src/scip/syncstore.c b/src/scip/syncstore.c index 1130b35252..446a5a476c 100644 --- a/src/scip/syncstore.c +++ b/src/scip/syncstore.c @@ -148,6 +148,8 @@ SCIP_RETCODE SCIPsyncstoreInit( syncstore = SCIPgetSyncstore(scip); assert(syncstore != NULL); syncstore->mainscip = scip; + SCIP_CALL( SCIPgetRealParam(scip, "limits/gap", &syncstore->limit_gap) ); + SCIP_CALL( SCIPgetRealParam(scip, "limits/absgap", &syncstore->limit_absgap) ); syncstore->lastsync = NULL; syncstore->nsolvers = SCIPgetNConcurrentSolvers(scip); @@ -492,7 +494,9 @@ SCIP_RETCODE SCIPsyncstoreFinishSync( if( (*syncdata)->syncedcount == syncstore->nsolvers ) { - if( (*syncdata)->status != SCIP_STATUS_UNKNOWN ) + if( (*syncdata)->status != SCIP_STATUS_UNKNOWN || + (SCIPgetConcurrentGap(syncstore->mainscip) <= syncstore->limit_gap) || + (SCIPgetConcurrentPrimalbound(syncstore->mainscip) - SCIPgetConcurrentDualbound(syncstore->mainscip) <= syncstore->limit_absgap) ) SCIPsyncstoreSetSolveIsStopped(syncstore, TRUE); syncstore->lastsync = *syncdata;