/** creates a separator */ SCIP_RETCODE SCIPsepaCreate( SCIP_SEPA** sepa, /**< pointer to separator data structure */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ const char* name, /**< name of separator */ const char* desc, /**< description of separator */ int priority, /**< priority of separator (>= 0: before, < 0: after constraint handlers) */ int freq, /**< frequency for calling separator */ SCIP_Real maxbounddist, /**< maximal relative distance from current node's dual bound to primal bound compared * to best node's dual bound for applying separation */ SCIP_Bool usessubscip, /**< does the separator use a secondary SCIP instance? */ SCIP_Bool delay, /**< should separator be delayed, if other separators found cuts? */ SCIP_DECL_SEPACOPY ((*sepacopy)), /**< copy method of separator or NULL if you don't want to copy your plugin into sub-SCIPs */ SCIP_DECL_SEPAFREE ((*sepafree)), /**< destructor of separator */ SCIP_DECL_SEPAINIT ((*sepainit)), /**< initialize separator */ SCIP_DECL_SEPAEXIT ((*sepaexit)), /**< deinitialize separator */ SCIP_DECL_SEPAINITSOL ((*sepainitsol)), /**< solving process initialization method of separator */ SCIP_DECL_SEPAEXITSOL ((*sepaexitsol)), /**< solving process deinitialization method of separator */ SCIP_DECL_SEPAEXECLP ((*sepaexeclp)), /**< LP solution separation method of separator */ SCIP_DECL_SEPAEXECSOL ((*sepaexecsol)), /**< arbitrary primal solution separation method of separator */ SCIP_SEPADATA* sepadata /**< separator data */ ) { char paramname[SCIP_MAXSTRLEN]; char paramdesc[SCIP_MAXSTRLEN]; assert(sepa != NULL); assert(name != NULL); assert(desc != NULL); assert(freq >= -1); assert(0.0 <= maxbounddist && maxbounddist <= 1.0); assert(sepaexeclp != NULL || sepaexecsol != NULL); SCIP_ALLOC( BMSallocMemory(sepa) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*sepa)->name, name, strlen(name)+1) ); SCIP_ALLOC( BMSduplicateMemoryArray(&(*sepa)->desc, desc, strlen(desc)+1) ); (*sepa)->priority = priority; (*sepa)->freq = freq; (*sepa)->maxbounddist = maxbounddist; (*sepa)->usessubscip = usessubscip; (*sepa)->sepacopy = sepacopy; (*sepa)->sepafree = sepafree; (*sepa)->sepainit = sepainit; (*sepa)->sepaexit = sepaexit; (*sepa)->sepainitsol = sepainitsol; (*sepa)->sepaexitsol = sepaexitsol; (*sepa)->sepaexeclp = sepaexeclp; (*sepa)->sepaexecsol = sepaexecsol; (*sepa)->sepadata = sepadata; SCIP_CALL( SCIPclockCreate(&(*sepa)->setuptime, SCIP_CLOCKTYPE_DEFAULT) ); SCIP_CALL( SCIPclockCreate(&(*sepa)->sepaclock, SCIP_CLOCKTYPE_DEFAULT) ); (*sepa)->lastsepanode = -1; (*sepa)->ncalls = 0; (*sepa)->ncutoffs = 0; (*sepa)->ncutsfound = 0; (*sepa)->ncutsapplied = 0; (*sepa)->nconssfound = 0; (*sepa)->ndomredsfound = 0; (*sepa)->ncallsatnode = 0; (*sepa)->ncutsfoundatnode = 0; (*sepa)->lpwasdelayed = FALSE; (*sepa)->solwasdelayed = FALSE; (*sepa)->initialized = FALSE; /* add parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/priority", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "priority of separator <%s>", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*sepa)->priority, TRUE, priority, INT_MIN/4, INT_MAX/4, paramChgdSepaPriority, (SCIP_PARAMDATA*)(*sepa)) ); /*lint !e740*/ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/freq", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "frequency for calling separator <%s> (-1: never, 0: only in root node)", name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*sepa)->freq, FALSE, freq, -1, INT_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/maxbounddist", name); (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for applying separator <%s> (0.0: only on current best node, 1.0: on all nodes)", name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, paramdesc, &(*sepa)->maxbounddist, TRUE, maxbounddist, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "separating/%s/delay", name); SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname, "should separator be delayed, if other separators found cuts?", &(*sepa)->delay, TRUE, delay, NULL, NULL) ); /*lint !e740*/ return SCIP_OKAY; }
/** create a set of diving heuristic settings */ SCIP_RETCODE SCIPdivesetCreate( SCIP_DIVESET** diveset, /**< pointer to the freshly created diveset */ SCIP_HEUR* heur, /**< the heuristic to which this dive setting belongs */ const char* name, /**< name for the diveset, or NULL if the name of the heuristic should be used */ SCIP_SET* set, /**< global SCIP settings */ SCIP_MESSAGEHDLR* messagehdlr, /**< message handler */ BMS_BLKMEM* blkmem, /**< block memory for parameter settings */ SCIP_Real minreldepth, /**< minimal relative depth to start diving */ SCIP_Real maxreldepth, /**< maximal relative depth to start diving */ SCIP_Real maxlpiterquot, /**< maximal fraction of diving LP iterations compared to node LP iterations */ SCIP_Real maxdiveubquot, /**< maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) * where diving is performed (0.0: no limit) */ SCIP_Real maxdiveavgquot, /**< maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound) * where diving is performed (0.0: no limit) */ SCIP_Real maxdiveubquotnosol, /**< maximal UBQUOT when no solution was found yet (0.0: no limit) */ SCIP_Real maxdiveavgquotnosol,/**< maximal AVGQUOT when no solution was found yet (0.0: no limit) */ SCIP_Real lpresolvedomchgquot,/**< percentage of immediate domain changes during probing to trigger LP resolve */ int lpsolvefreq, /**< LP solve frequency for (0: only if enough domain reductions are found by propagation)*/ int maxlpiterofs, /**< additional number of allowed LP iterations */ SCIP_Bool backtrack, /**< use one level of backtracking if infeasibility is encountered? */ SCIP_Bool onlylpbranchcands, /**< should only LP branching candidates be considered instead of the slower but * more general constraint handler diving variable selection? */ SCIP_DIVETYPE divetypemask, /**< bit mask that represents the supported dive types by this dive set */ SCIP_DECL_DIVESETGETSCORE((*divesetgetscore)) /**< method for candidate score and rounding direction */ ) { char paramname[SCIP_MAXSTRLEN]; const char* divesetname; assert(diveset != NULL); assert(set != NULL); assert(divesetgetscore != NULL); assert(heur != NULL); SCIP_ALLOC( BMSallocMemory(diveset) ); /* for convenience, the name gets inferred from the heuristic to which the diveset is added if no name is provided */ divesetname = (name == NULL ? SCIPheurGetName(heur) : name); SCIP_ALLOC( BMSduplicateMemoryArray(&(*diveset)->name, divesetname, strlen(divesetname)+1) ); (*diveset)->heur = NULL; /* copy callbacks */ (*diveset)->divesetgetscore = divesetgetscore; SCIP_CALL( heurAddDiveset(heur, *diveset) ); (*diveset)->sol = NULL; (*diveset)->divetypemask = divetypemask; /* add collection of diving heuristic specific parameters */ (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/minreldepth", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "minimal relative depth to start diving", &(*diveset)->minreldepth, TRUE, minreldepth, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxreldepth", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal relative depth to start diving", &(*diveset)->maxreldepth, TRUE, maxreldepth, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxlpiterquot", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal fraction of diving LP iterations compared to node LP iterations", &(*diveset)->maxlpiterquot, FALSE, maxlpiterquot, 0.0, SCIP_REAL_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxlpiterofs", (*diveset)->name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, "additional number of allowed LP iterations", &(*diveset)->maxlpiterofs, FALSE, maxlpiterofs, 0, INT_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveubquot", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) where diving is performed (0.0: no limit)", &(*diveset)->maxdiveubquot, TRUE, maxdiveubquot, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveavgquot", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound) where diving is performed (0.0: no limit)", &(*diveset)->maxdiveavgquot, TRUE, maxdiveavgquot, 0.0, SCIP_REAL_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveubquotnosol", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal UBQUOT when no solution was found yet (0.0: no limit)", &(*diveset)->maxdiveubquotnosol, TRUE, maxdiveubquotnosol, 0.0, 1.0, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/maxdiveavgquotnosol", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "maximal AVGQUOT when no solution was found yet (0.0: no limit)", &(*diveset)->maxdiveavgquotnosol, TRUE, maxdiveavgquotnosol, 0.0, SCIP_REAL_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/backtrack", (*diveset)->name); SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname, "use one level of backtracking if infeasibility is encountered?", &(*diveset)->backtrack, FALSE, backtrack, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/lpresolvedomchgquot", (*diveset)->name); SCIP_CALL( SCIPsetAddRealParam(set, messagehdlr, blkmem, paramname, "percentage of immediate domain changes during probing to trigger LP resolve", &(*diveset)->lpresolvedomchgquot, FALSE, lpresolvedomchgquot, 0.0, SCIP_REAL_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/lpsolvefreq", (*diveset)->name); SCIP_CALL( SCIPsetAddIntParam(set, messagehdlr, blkmem, paramname, "LP solve frequency for diving heuristics (0: only after enough domain changes have been found)", &(*diveset)->lpsolvefreq, FALSE, lpsolvefreq, 0, INT_MAX, NULL, NULL) ); (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "heuristics/%s/onlylpbranchcands", (*diveset)->name); SCIP_CALL( SCIPsetAddBoolParam(set, messagehdlr, blkmem, paramname, "should only LP branching candidates be considered instead of the slower but " "more general constraint handler diving variable selection?", &(*diveset)->onlylpbranchcands, FALSE, onlylpbranchcands, NULL, NULL) ); SCIPdivesetReset(*diveset); return SCIP_OKAY; }