/** creates the impliedbounds separator and includes it in SCIP */ SCIP_RETCODE SCIPincludeSepaImpliedbounds( SCIP* scip /**< SCIP data structure */ ) { SCIP_SEPADATA* sepadata; SCIP_SEPA* sepa; /* create impliedbounds separator data */ SCIP_CALL( SCIPallocMemory(scip, &sepadata) ); assert(sepadata != NULL); /* include separator */ SCIP_CALL( SCIPincludeSepaBasic(scip, &sepa, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST, SEPA_USESSUBSCIP, SEPA_DELAY, sepaExeclpImpliedbounds, sepaExecsolImpliedbounds, sepadata) ); assert(sepa != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyImpliedbounds) ); SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeImpliedbounds) ); /* add separator parameters */ SCIP_CALL( SCIPaddBoolParam(scip, "separating/impliedbounds/usetwosizecliques", "should violated inequalities for cliques with 2 variables be separated?", &sepadata->usetwosizecliques, TRUE, DEFAULT_USETWOSIZECLIQUES, NULL, NULL) ); return SCIP_OKAY; }
/** creates the Strong CG cut separator and includes it in SCIP */ SCIP_RETCODE SCIPincludeSepaStrongcg( SCIP* scip /**< SCIP data structure */ ) { SCIP_SEPADATA* sepadata; SCIP_SEPA* sepa; /* create separator data */ SCIP_CALL( SCIPallocMemory(scip, &sepadata) ); sepadata->lastncutsfound = 0; /* include separator */ SCIP_CALL( SCIPincludeSepaBasic(scip, &sepa, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST, SEPA_USESSUBSCIP, SEPA_DELAY, sepaExeclpStrongcg, NULL, sepadata) ); assert(sepa != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyStrongcg) ); SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeStrongcg) ); /* add separator parameters */ SCIP_CALL( SCIPaddIntParam(scip, "separating/strongcg/maxrounds", "maximal number of strong CG separation rounds per node (-1: unlimited)", &sepadata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/strongcg/maxroundsroot", "maximal number of strong CG separation rounds in the root node (-1: unlimited)", &sepadata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/strongcg/maxsepacuts", "maximal number of strong CG cuts separated per separation round", &sepadata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/strongcg/maxsepacutsroot", "maximal number of strong CG cuts separated per separation round in the root node", &sepadata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "separating/strongcg/maxweightrange", "maximal valid range max(|weights|)/min(|weights|) of row weights", &sepadata->maxweightrange, TRUE, DEFAULT_MAXWEIGHTRANGE, 1.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/strongcg/dynamiccuts", "should generated cuts be removed from the LP if they are no longer tight?", &sepadata->dynamiccuts, FALSE, DEFAULT_DYNAMICCUTS, NULL, NULL) ); return SCIP_OKAY; }
/** creates the xyz separator and includes it in SCIP */ SCIP_RETCODE SCIPincludeSepaXyz( SCIP* scip /**< SCIP data structure */ ) { SCIP_SEPADATA* sepadata; SCIP_SEPA* sepa; /* create xyz separator data */ sepadata = NULL; /* TODO: (optional) create separator specific data here */ sepa = NULL; /* include separator */ #if 0 /* use SCIPincludeSepa() if you want to set all callbacks explicitly and realize (by getting compiler errors) when * new callbacks are added in future SCIP versions */ SCIP_CALL( SCIPincludeSepa(scip, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST, SEPA_USESSUBSCIP, SEPA_DELAY, sepaCopyXyz, sepaFreeXyz, sepaInitXyz, sepaExitXyz, sepaInitsolXyz, sepaExitsolXyz, sepaExeclpXyz, sepaExecsolXyz, sepadata) ); #else /* use SCIPincludeSepaBasic() plus setter functions if you want to set callbacks one-by-one and your code should * compile independent of new callbacks being added in future SCIP versions */ SCIP_CALL( SCIPincludeSepaBasic(scip, &sepa, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST, SEPA_USESSUBSCIP, SEPA_DELAY, sepaExeclpXyz, sepaExecsolXyz, sepadata) ); assert(sepa != NULL); /* set non fundamental callbacks via setter functions */ SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyXyz) ); SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeXyz) ); SCIP_CALL( SCIPsetSepaInit(scip, sepa, sepaInitXyz) ); SCIP_CALL( SCIPsetSepaExit(scip, sepa, sepaExitXyz) ); SCIP_CALL( SCIPsetSepaInitsol(scip, sepa, sepaInitsolXyz) ); SCIP_CALL( SCIPsetSepaExitsol(scip, sepa, sepaExitsolXyz) ); #endif /* add xyz separator parameters */ /* TODO: (optional) add separator specific parameters with SCIPaddTypeParam() here */ return SCIP_OKAY; }
/** creates the integer objective value separator and includes it in SCIP */ SCIP_RETCODE SCIPincludeSepaIntobj( SCIP* scip /**< SCIP data structure */ ) { SCIP_SEPADATA* sepadata; SCIP_EVENTHDLRDATA* eventhdlrdata; SCIP_SEPA* sepa; SCIP_EVENTHDLR* eventhdlr; /* create intobj separator data */ SCIP_CALL( sepadataCreate(scip, &sepadata) ); /* include separator */ SCIP_CALL( SCIPincludeSepaBasic(scip, &sepa, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST, SEPA_USESSUBSCIP, SEPA_DELAY, sepaExeclpIntobj, sepaExecsolIntobj, sepadata) ); assert(sepa != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyIntobj) ); SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeIntobj) ); SCIP_CALL( SCIPsetSepaExit(scip, sepa, sepaExitIntobj) ); SCIP_CALL( SCIPsetSepaExitsol(scip, sepa, sepaExitsolIntobj) ); /* include event handler for objective change events */ eventhdlr = NULL; eventhdlrdata = (SCIP_EVENTHDLRDATA*)sepadata; SCIP_CALL( SCIPincludeEventhdlrBasic(scip, &eventhdlr, EVENTHDLR_NAME, EVENTHDLR_DESC, eventExecIntobj, eventhdlrdata) ); assert(eventhdlr != NULL); SCIP_CALL( SCIPsetEventhdlrInit(scip, eventhdlr, eventInitIntobj) ); SCIP_CALL( SCIPsetEventhdlrExit(scip, eventhdlr, eventExitIntobj) ); return SCIP_OKAY; }
/** creates the Gomory MIR cut separator and includes it in SCIP */ SCIP_RETCODE SCIPincludeSepaGomory( SCIP* scip /**< SCIP data structure */ ) { SCIP_SEPADATA* sepadata; SCIP_SEPA* sepa; /* create separator data */ SCIP_CALL( SCIPallocMemory(scip, &sepadata) ); sepadata->lastncutsfound = 0; /* include separator */ SCIP_CALL( SCIPincludeSepaBasic(scip, &sepa, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST, SEPA_USESSUBSCIP, SEPA_DELAY, sepaExeclpGomory, NULL, sepadata) ); assert(sepa != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyGomory) ); SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeGomory) ); /* add separator parameters */ SCIP_CALL( SCIPaddIntParam(scip, "separating/gomory/maxrounds", "maximal number of gomory separation rounds per node (-1: unlimited)", &sepadata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/gomory/maxroundsroot", "maximal number of gomory separation rounds in the root node (-1: unlimited)", &sepadata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/gomory/maxsepacuts", "maximal number of gomory cuts separated per separation round", &sepadata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/gomory/maxsepacutsroot", "maximal number of gomory cuts separated per separation round in the root node", &sepadata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "separating/gomory/away", "minimal integrality violation of a basis variable in order to try Gomory cut", &sepadata->away, FALSE, DEFAULT_AWAY, 0.0, 0.5, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "separating/gomory/maxweightrange", "maximal valid range max(|weights|)/min(|weights|) of row weights", &sepadata->maxweightrange, TRUE, DEFAULT_MAXWEIGHTRANGE, 1.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/gomory/dynamiccuts", "should generated cuts be removed from the LP if they are no longer tight?", &sepadata->dynamiccuts, FALSE, DEFAULT_DYNAMICCUTS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/gomory/makeintegral", "try to scale cuts to integral coefficients", &sepadata->makeintegral, TRUE, DEFAULT_MAKEINTEGRAL, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/gomory/forcecuts", "if conversion to integral coefficients failed still use the cut", &sepadata->forcecuts, TRUE, DEFAULT_FORCECUTS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/gomory/separaterows", "separate rows with integral slack", &sepadata->separaterows, TRUE, DEFAULT_SEPARATEROWS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/gomory/delayedcuts", "should cuts be added to the delayed cut pool?", &sepadata->delayedcuts, TRUE, DEFAULT_DELAYEDCUTS, NULL, NULL) ); return SCIP_OKAY; }
/** creates the disjunctive cut separator and includes it in SCIP */ SCIP_RETCODE SCIPincludeSepaDisjunctive( SCIP* scip /**< SCIP data structure */ ) { SCIP_SEPADATA* sepadata = NULL; SCIP_SEPA* sepa = NULL; /* create separator data */ SCIP_CALL( SCIPallocMemory(scip, &sepadata) ); sepadata->conshdlr = NULL; sepadata->lastncutsfound = 0; /* include separator */ SCIP_CALL( SCIPincludeSepaBasic(scip, &sepa, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST, SEPA_USESSUBSCIP, SEPA_DELAY, sepaExeclpDisjunctive, NULL, sepadata) ); assert( sepa != NULL ); /* set non fundamental callbacks via setter functions */ SCIP_CALL( SCIPsetSepaCopy(scip, sepa, sepaCopyDisjunctive) ); SCIP_CALL( SCIPsetSepaFree(scip, sepa, sepaFreeDisjunctive) ); SCIP_CALL( SCIPsetSepaInitsol(scip, sepa, sepaInitsolDisjunctive) ); /* add separator parameters */ SCIP_CALL( SCIPaddBoolParam(scip, "separating/"SEPA_NAME"/strengthen", "strengthen cut if integer variables are present.", &sepadata->strengthen, TRUE, DEFAULT_STRENGTHEN, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxdepth", "node depth of separating bipartite disjunctive cuts (-1: no limit)", &sepadata->maxdepth, TRUE, DEFAULT_MAXDEPTH, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxrounds", "maximal number of separation rounds per iteration in a branching node (-1: no limit)", &sepadata->maxrounds, TRUE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxroundsroot", "maximal number of separation rounds in the root node (-1: no limit)", &sepadata->maxroundsroot, TRUE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxinvcuts", "maximal number of cuts investigated per iteration in a branching node", &sepadata->maxinvcuts, TRUE, DEFAULT_MAXINVCUTS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxinvcutsroot", "maximal number of cuts investigated per iteration in the root node", &sepadata->maxinvcutsroot, TRUE, DEFAULT_MAXINVCUTSROOT, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxconfsdelay", "delay separation if number of conflict graph edges is larger than predefined value (-1: no limit)", &sepadata->maxconfsdelay, TRUE, DEFAULT_MAXCONFSDELAY, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxrank", "maximal rank of a disj. cut that could not be scaled to integral coefficients (-1: unlimited)", &sepadata->maxrank, FALSE, DEFAULT_MAXRANK, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/" SEPA_NAME "/maxrankintegral", "maximal rank of a disj. cut that could be scaled to integral coefficients (-1: unlimited)", &sepadata->maxrankintegral, FALSE, DEFAULT_MAXRANKINTEGRAL, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "separating/" SEPA_NAME "/maxweightrange", "maximal valid range max(|weights|)/min(|weights|) of row weights", &sepadata->maxweightrange, TRUE, DEFAULT_MAXWEIGHTRANGE, 1.0, SCIP_REAL_MAX, NULL, NULL) ); return SCIP_OKAY; }