/** creates the node selector for best first search and includes it in SCIP */ SCIP_RETCODE SCIPincludeNodeselBfs( SCIP* scip /**< SCIP data structure */ ) { SCIP_NODESELDATA* nodeseldata; SCIP_NODESEL* nodesel; /* allocate and initialize node selector data; this has to be freed in the destructor */ SCIP_CALL( SCIPallocMemory(scip, &nodeseldata) ); /* include node selector */ SCIP_CALL( SCIPincludeNodeselBasic(scip, &nodesel, NODESEL_NAME, NODESEL_DESC, NODESEL_STDPRIORITY, NODESEL_MEMSAVEPRIORITY, nodeselSelectBfs, nodeselCompBfs, nodeseldata) ); assert(nodesel != NULL); SCIP_CALL( SCIPsetNodeselCopy(scip, nodesel, nodeselCopyBfs) ); SCIP_CALL( SCIPsetNodeselFree(scip, nodesel, nodeselFreeBfs) ); /* add node selector parameters */ SCIP_CALL( SCIPaddIntParam(scip, "nodeselection/bfs/minplungedepth", "minimal plunging depth, before new best node may be selected (-1 for dynamic setting)", &nodeseldata->minplungedepth, TRUE, MINPLUNGEDEPTH, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "nodeselection/bfs/maxplungedepth", "maximal plunging depth, before new best node is forced to be selected (-1 for dynamic setting)", &nodeseldata->maxplungedepth, TRUE, MAXPLUNGEDEPTH, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "nodeselection/bfs/maxplungequot", "maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) where plunging is performed", &nodeseldata->maxplungequot, TRUE, MAXPLUNGEQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates the reoptsols primal heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurReoptsols( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create reoptsols primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecReoptsols, heurdata) ); assert(heur != NULL); /* set non fundamental callbacks via setter functions */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyReoptsols) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeReoptsols) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitReoptsols) ); SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitReoptsols) ); SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolReoptsols) ); SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolReoptsols) ); /* parameters */ SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxsols", "maximal number solutions which should be checked. (-1: all)", &heurdata->maxsols, TRUE, 1000, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxruns", "check solutions of the last k runs. (-1: all)", &heurdata->maxruns, TRUE, -1, -1, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates the fix-and-infer primal heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurFixandinfer( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create Fixandinfer primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecFixandinfer, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyFixandinfer) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeFixandinfer) ); /* fixandinfer heuristic parameters */ SCIP_CALL( SCIPaddIntParam(scip, "heuristics/fixandinfer/proprounds", "maximal number of propagation rounds in probing subproblems (-1: no limit, 0: auto)", &heurdata->proprounds, TRUE, DEFAULT_PROPROUNDS, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/fixandinfer/minfixings", "minimal number of fixings to apply before dive may be aborted", &heurdata->minfixings, TRUE, DEFAULT_MINFIXINGS, 0, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates the rootsoldiving heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurRootsoldiving( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create Rootsoldiving primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecRootsoldiving, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyRootsoldiving) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeRootsoldiving) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitRootsoldiving) ); SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitRootsoldiving) ); /* rootsoldiving heuristic parameters */ SCIP_CALL( SCIPaddRealParam(scip, "heuristics/rootsoldiving/minreldepth", "minimal relative depth to start diving", &heurdata->minreldepth, TRUE, DEFAULT_MINRELDEPTH, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/rootsoldiving/maxreldepth", "maximal relative depth to start diving", &heurdata->maxreldepth, TRUE, DEFAULT_MAXRELDEPTH, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/rootsoldiving/maxlpiterquot", "maximal fraction of diving LP iterations compared to node LP iterations", &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/rootsoldiving/maxlpiterofs", "additional number of allowed LP iterations", &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/rootsoldiving/maxsols", "total number of feasible solutions found up to which heuristic is called (-1: no limit)", &heurdata->maxsols, TRUE, DEFAULT_MAXSOLS, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/rootsoldiving/depthfac", "maximal diving depth: number of binary/integer variables times depthfac", &heurdata->depthfac, TRUE, DEFAULT_DEPTHFAC, 0.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/rootsoldiving/depthfacnosol", "maximal diving depth factor if no feasible solution was found yet", &heurdata->depthfacnosol, TRUE, DEFAULT_DEPTHFACNOSOL, 0.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/rootsoldiving/alpha", "soft rounding factor to fade out objective coefficients", &heurdata->alpha, TRUE, DEFAULT_ALPHA, 0.0, 1.0, NULL, NULL) ); return SCIP_OKAY; }
/** creates the handler for stp constraints and includes it in SCIP */ SCIP_RETCODE SCIPincludeConshdlrStp( SCIP* scip /**< SCIP data structure */ ) { SCIP_CONSHDLRDATA* conshdlrdata; SCIP_CONSHDLR* conshdlr; /* create stp constraint handler data */ SCIP_CALL( SCIPallocMemory(scip, &conshdlrdata) ); conshdlr = NULL; /* include constraint handler */ SCIP_CALL( SCIPincludeConshdlrBasic(scip, &conshdlr, CONSHDLR_NAME, CONSHDLR_DESC, CONSHDLR_ENFOPRIORITY, CONSHDLR_CHECKPRIORITY, CONSHDLR_EAGERFREQ, CONSHDLR_NEEDSCONS, consEnfolpStp, consEnfopsStp, consCheckStp, consLockStp, conshdlrdata) ); assert(conshdlr != NULL); SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyStp, consCopyStp) ); SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteStp) ); SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransStp) ); SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropStp, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP, CONSHDLR_PROP_TIMING) ); SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpStp, NULL, CONSHDLR_SEPAFREQ, CONSHDLR_SEPAPRIORITY, CONSHDLR_DELAYSEPA) ); SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeStp) ); SCIP_CALL( SCIPaddBoolParam(scip, "constraints/stp/backcut", "Try Back-Cuts", &conshdlrdata->backcut, TRUE, DEFAULT_BACKCUT, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "constraints/stp/creepflow", "Use Creep-Flow", &conshdlrdata->creepflow, TRUE, DEFAULT_CREEPFLOW, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "constraints/stp/disjunctcut", "Only disjunct Cuts", &conshdlrdata->disjunctcut, TRUE, DEFAULT_DISJUNCTCUT, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "constraints/stp/nestedcut", "Try Nested-Cuts", &conshdlrdata->nestedcut, TRUE, DEFAULT_NESTEDCUT, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "constraints/stp/flowsep", "Try Flow-Cuts", &conshdlrdata->flowsep, TRUE, DEFAULT_FLOWSEP, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "constraints/"CONSHDLR_NAME"/maxrounds", "maximal number of separation rounds per node (-1: unlimited)", &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "constraints/"CONSHDLR_NAME"/maxroundsroot", "maximal number of separation rounds per node in the root node (-1: unlimited)", &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "constraints/"CONSHDLR_NAME"/maxsepacuts", "maximal number of cuts separated per separation round", &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "constraints/"CONSHDLR_NAME"/maxsepacutsroot", "maximal number of cuts separated per separation round in the root node", &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates the pseudo cost branching rule and includes it in SCIP */ SCIP_RETCODE SCIPincludeBranchrulePscost( SCIP* scip /**< SCIP data structure */ ) { SCIP_BRANCHRULEDATA* branchruledata; SCIP_BRANCHRULE* branchrule; /* create pscost branching rule data */ SCIP_CALL( SCIPallocMemory(scip, &branchruledata) ); /* include allfullstrong branching rule */ SCIP_CALL( SCIPincludeBranchruleBasic(scip, &branchrule, BRANCHRULE_NAME, BRANCHRULE_DESC, BRANCHRULE_PRIORITY, BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchruledata) ); assert(branchrule != NULL); /* set non-fundamental callbacks via specific setter functions*/ SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyPscost) ); SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreePscost) ); SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpPscost) ); SCIP_CALL( SCIPsetBranchruleExecExt(scip, branchrule, branchExecextPscost) ); SCIP_CALL( SCIPaddCharParam(scip, "branching/"BRANCHRULE_NAME"/strategy", "strategy for utilizing pseudo-costs of external branching candidates (multiply as in pseudo costs 'u'pdate rule, or by 'd'omain reduction, or by domain reduction of 's'ibling, or by 'v'ariable score)", &branchruledata->strategy, FALSE, BRANCHRULE_STRATEGY_DEFAULT, BRANCHRULE_STRATEGIES, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "branching/"BRANCHRULE_NAME"/minscoreweight", "weight for minimum of scores of a branching candidate when building weighted sum of min/max/sum of scores", &branchruledata->scoreminweight, TRUE, BRANCHRULE_SCOREMINWEIGHT_DEFAULT, -SCIPinfinity(scip), SCIPinfinity(scip), NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "branching/"BRANCHRULE_NAME"/maxscoreweight", "weight for maximum of scores of a branching candidate when building weighted sum of min/max/sum of scores", &branchruledata->scoremaxweight, TRUE, BRANCHRULE_SCOREMAXWEIGHT_DEFAULT, -SCIPinfinity(scip), SCIPinfinity(scip), NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "branching/"BRANCHRULE_NAME"/sumscoreweight", "weight for sum of scores of a branching candidate when building weighted sum of min/max/sum of scores", &branchruledata->scoresumweight, TRUE, BRANCHRULE_SCORESUMWEIGHT_DEFAULT, -SCIPinfinity(scip), SCIPinfinity(scip), NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "branching/"BRANCHRULE_NAME"/nchildren", "number of children to create in n-ary branching", &branchruledata->nchildren, FALSE, BRANCHRULE_NCHILDREN_DEFAULT, 2, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "branching/"BRANCHRULE_NAME"/narymaxdepth", "maximal depth where to do n-ary branching, -1 to turn off", &branchruledata->narymaxdepth, FALSE, BRANCHRULE_NARYMAXDEPTH_DEFAULT, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "branching/"BRANCHRULE_NAME"/naryminwidth", "minimal domain width in children when doing n-ary branching, relative to global bounds", &branchruledata->naryminwidth, FALSE, BRANCHRULE_NARYMINWIDTH_DEFAULT, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "branching/"BRANCHRULE_NAME"/narywidthfactor", "factor of domain width in n-ary branching when creating nodes with increasing distance from branching value", &branchruledata->narywidthfactor, FALSE, BRANCHRULE_NARYWIDTHFAC_DEFAULT, 1.0, SCIP_REAL_MAX, 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 objpscostdiving heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurObjpscostdiving( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; /* create heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include heuristic */ SCIP_CALL( SCIPincludeHeur(scip, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurCopyObjpscostdiving, heurFreeObjpscostdiving, heurInitObjpscostdiving, heurExitObjpscostdiving, heurInitsolObjpscostdiving, heurExitsolObjpscostdiving, heurExecObjpscostdiving, heurdata) ); /* objpscostdiving heuristic parameters */ SCIP_CALL( SCIPaddRealParam(scip, "heuristics/objpscostdiving/minreldepth", "minimal relative depth to start diving", &heurdata->minreldepth, TRUE, DEFAULT_MINRELDEPTH, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/objpscostdiving/maxreldepth", "maximal relative depth to start diving", &heurdata->maxreldepth, TRUE, DEFAULT_MAXRELDEPTH, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/objpscostdiving/maxlpiterquot", "maximal fraction of diving LP iterations compared to total iteration number", &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/objpscostdiving/maxlpiterofs", "additional number of allowed LP iterations", &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/objpscostdiving/maxsols", "total number of feasible solutions found up to which heuristic is called (-1: no limit)", &heurdata->maxsols, TRUE, DEFAULT_MAXSOLS, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/objpscostdiving/depthfac", "maximal diving depth: number of binary/integer variables times depthfac", &heurdata->depthfac, TRUE, DEFAULT_DEPTHFAC, 0.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/objpscostdiving/depthfacnosol", "maximal diving depth factor if no feasible solution was found yet", &heurdata->depthfacnosol, TRUE, DEFAULT_DEPTHFACNOSOL, 0.0, SCIP_REAL_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates the random branching rule and includes it in SCIP */ SCIP_RETCODE SCIPincludeBranchruleRandom( SCIP* scip /**< SCIP data structure */ ) { SCIP_BRANCHRULEDATA* branchruledata; SCIP_BRANCHRULE* branchrule; /* create random branching rule data */ SCIP_CALL( SCIPallocMemory(scip, &branchruledata) ); branchruledata->seed = 0; /* include allfullstrong branching rule */ SCIP_CALL( SCIPincludeBranchruleBasic(scip, &branchrule, BRANCHRULE_NAME, BRANCHRULE_DESC, BRANCHRULE_PRIORITY, BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchruledata) ); assert(branchrule != NULL); /* set non-fundamental callbacks via specific setter functions*/ SCIP_CALL( SCIPsetBranchruleCopy(scip, branchrule, branchCopyRandom) ); SCIP_CALL( SCIPsetBranchruleFree(scip, branchrule, branchFreeRandom) ); SCIP_CALL( SCIPsetBranchruleInit(scip, branchrule, branchInitRandom) ); SCIP_CALL( SCIPsetBranchruleExecLp(scip, branchrule, branchExeclpRandom) ); SCIP_CALL( SCIPsetBranchruleExecExt(scip, branchrule, branchExecextRandom) ); SCIP_CALL( SCIPsetBranchruleExecPs(scip, branchrule, branchExecpsRandom) ); SCIP_CALL( SCIPaddIntParam(scip, "branching/" BRANCHRULE_NAME "/seed", "initial random seed value", &branchruledata->initseed, FALSE, DEFAULT_INITSEED, 0, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates the node selector for best estimate search and includes it in SCIP */ SCIP_RETCODE SCIPincludeNodeselEstimate( SCIP* scip /**< SCIP data structure */ ) { SCIP_NODESELDATA* nodeseldata; SCIP_NODESEL* nodesel; /* allocate and initialize node selector data; this has to be freed in the destructor */ SCIP_CALL( SCIPallocMemory(scip, &nodeseldata) ); /* include node selector */ SCIP_CALL( SCIPincludeNodeselBasic(scip, &nodesel, NODESEL_NAME, NODESEL_DESC, NODESEL_STDPRIORITY, NODESEL_MEMSAVEPRIORITY, nodeselSelectEstimate, nodeselCompEstimate, nodeseldata) ); assert(nodesel != NULL); SCIP_CALL( SCIPsetNodeselCopy(scip, nodesel, nodeselCopyEstimate) ); SCIP_CALL( SCIPsetNodeselFree(scip, nodesel, nodeselFreeEstimate) ); /* add node selector parameters */ SCIP_CALL( SCIPaddIntParam(scip, "nodeselection/estimate/minplungedepth", "minimal plunging depth, before new best node may be selected (-1 for dynamic setting)", &nodeseldata->minplungedepth, TRUE, DEFAULT_MINPLUNGEDEPTH, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "nodeselection/estimate/maxplungedepth", "maximal plunging depth, before new best node is forced to be selected (-1 for dynamic setting)", &nodeseldata->maxplungedepth, TRUE, DEFAULT_MAXPLUNGEDEPTH, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "nodeselection/estimate/maxplungequot", "maximal quotient (estimate - lowerbound)/(cutoffbound - lowerbound) where plunging is performed", &nodeseldata->maxplungequot, TRUE, DEFAULT_MAXPLUNGEQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "nodeselection/estimate/bestnodefreq", "frequency at which the best node instead of the best estimate is selected (0: never)", &nodeseldata->bestnodefreq, FALSE, DEFAULT_BESTNODEFREQ, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "nodeselection/estimate/breadthfirstdepth", "depth until breadth-fisrt search is applied", &nodeseldata->breadthfirstdepth, FALSE, DEFAULT_BREADTHFIRSTDEPTH, -1, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates the node selector for hybrid best estimate / best bound search and includes it in SCIP */ SCIP_RETCODE SCIPincludeNodeselHybridestim( SCIP* scip /**< SCIP data structure */ ) { SCIP_NODESELDATA* nodeseldata; SCIP_NODESEL* nodesel; /* allocate and initialize node selector data; this has to be freed in the destructor */ SCIP_CALL( SCIPallocMemory(scip, &nodeseldata) ); /* include node selector */ SCIP_CALL( SCIPincludeNodeselBasic(scip, &nodesel, NODESEL_NAME, NODESEL_DESC, NODESEL_STDPRIORITY, NODESEL_MEMSAVEPRIORITY, nodeselSelectHybridestim, nodeselCompHybridestim, nodeseldata) ); assert(nodesel != NULL); SCIP_CALL( SCIPsetNodeselCopy(scip, nodesel, nodeselCopyHybridestim) ); SCIP_CALL( SCIPsetNodeselFree(scip, nodesel, nodeselFreeHybridestim) ); /* add node selector parameters */ SCIP_CALL( SCIPaddIntParam(scip, "nodeselection/hybridestim/minplungedepth", "minimal plunging depth, before new best node may be selected (-1 for dynamic setting)", &nodeseldata->minplungedepth, TRUE, MINPLUNGEDEPTH, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "nodeselection/hybridestim/maxplungedepth", "maximal plunging depth, before new best node is forced to be selected (-1 for dynamic setting)", &nodeseldata->maxplungedepth, TRUE, MAXPLUNGEDEPTH, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "nodeselection/hybridestim/maxplungequot", "maximal quotient (estimate - lowerbound)/(cutoffbound - lowerbound) where plunging is performed", &nodeseldata->maxplungequot, TRUE, MAXPLUNGEQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "nodeselection/hybridestim/bestnodefreq", "frequency at which the best node instead of the hybrid best estimate / best bound is selected (0: never)", &nodeseldata->bestnodefreq, FALSE, BESTNODEFREQ, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "nodeselection/hybridestim/estimweight", "weight of estimate value in node selection score (0: pure best bound search, 1: pure best estimate search)", &nodeseldata->estimweight, TRUE, ESTIMWEIGHT, 0.0, 1.0, NULL, NULL) ); return SCIP_OKAY; }
/** creates the guideddiving heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurGuideddiving( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create Guideddiving primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecGuideddiving, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyGuideddiving) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeGuideddiving) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitGuideddiving) ); SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitGuideddiving) ); /* guideddiving heuristic parameters */ SCIP_CALL( SCIPaddRealParam(scip, "heuristics/guideddiving/minreldepth", "minimal relative depth to start diving", &heurdata->minreldepth, TRUE, DEFAULT_MINRELDEPTH, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/guideddiving/maxreldepth", "maximal relative depth to start diving", &heurdata->maxreldepth, TRUE, DEFAULT_MAXRELDEPTH, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/guideddiving/maxlpiterquot", "maximal fraction of diving LP iterations compared to node LP iterations", &heurdata->maxlpiterquot, FALSE, DEFAULT_MAXLPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/guideddiving/maxlpiterofs", "additional number of allowed LP iterations", &heurdata->maxlpiterofs, FALSE, DEFAULT_MAXLPITEROFS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/guideddiving/maxdiveubquot", "maximal quotient (curlowerbound - lowerbound)/(cutoffbound - lowerbound) where diving is performed (0.0: no limit)", &heurdata->maxdiveubquot, TRUE, DEFAULT_MAXDIVEUBQUOT, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/guideddiving/maxdiveavgquot", "maximal quotient (curlowerbound - lowerbound)/(avglowerbound - lowerbound) where diving is performed (0.0: no limit)", &heurdata->maxdiveavgquot, TRUE, DEFAULT_MAXDIVEAVGQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/guideddiving/backtrack", "use one level of backtracking if infeasibility is encountered?", &heurdata->backtrack, FALSE, DEFAULT_BACKTRACK, NULL, NULL) ); return SCIP_OKAY; }
/** creates the zirounding primal heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurZirounding( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create zirounding primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecZirounding, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyZirounding) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeZirounding) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitZirounding) ); SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitZirounding) ); SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolZirounding) ); /* add zirounding primal heuristic parameters */ SCIP_CALL( SCIPaddIntParam(scip, "heuristics/zirounding/maxroundingloops", "determines maximum number of rounding loops", &heurdata->maxroundingloops, TRUE, DEFAULT_MAXROUNDINGLOOPS, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/zirounding/stopziround", "flag to determine if Zirounding is deactivated after a certain percentage of unsuccessful calls", &heurdata->stopziround, TRUE, DEFAULT_STOPZIROUND, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip,"heuristics/zirounding/stoppercentage", "if percentage of found solutions falls below this parameter, Zirounding will be deactivated", &heurdata->stoppercentage, TRUE, DEFAULT_STOPPERCENTAGE, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/zirounding/minstopncalls", "determines the minimum number of calls before percentage-based deactivation of Zirounding is applied", &heurdata->minstopncalls, TRUE, DEFAULT_MINSTOPNCALLS, 1, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** includes the ppm file reader in SCIP */ SCIP_RETCODE SCIPincludeReaderPpm( SCIP* scip /**< SCIP data structure */ ) { SCIP_READERDATA* readerdata; SCIP_READER* reader; /* create ppm reader data */ SCIP_CALL( SCIPallocMemory(scip, &readerdata) ); initReaderdata(readerdata); /* include reader */ SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) ); assert(reader != NULL); /* set non fundamental callbacks via setter functions */ SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyPpm) ); SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreePpm) ); SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWritePpm) ); /* add ppm reader parameters */ SCIP_CALL( SCIPaddBoolParam(scip, "reading/ppmreader/rgbrelativ", "should the coloring values be relativ or absolute", &readerdata->rgb_relativ, FALSE, DEFAULT_PPM_RGB_RELATIVE, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "reading/ppmreader/rgbascii", "should the output format be binary(P6) (otherwise plain(P3) format)", &readerdata->rgb_ascii, FALSE, DEFAULT_PPM_RGB_ASCII, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "reading/ppmreader/coefficientlimit", "splitting coefficients in this number of intervals", &readerdata->coef_limit, FALSE, DEFAULT_PPM_COEF_LIMIT, 3, 16, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "reading/ppmreader/rgblimit", "maximal color value", &readerdata->rgb_limit, FALSE, DEFAULT_PPM_RGB_LIMIT, 0, 255, NULL, NULL) ); return SCIP_OKAY; }
/** creates the rounding heuristic with infeasibility recovering and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurRounding( SCIP* scip /**< SCIP data structure */, SCIP_HEUR** heu ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create Rounding primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecRounding, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ /* SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyRounding) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeRounding) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitRounding) ); SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitRounding) ); SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolRounding) ); SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolRounding) ); */ /* add rounding primal heuristic parameters */ SCIP_CALL( SCIPaddIntParam(scip, "heuristics/""special_rounding""/successfactor", "number of calls per found solution that are considered as standard success, a higher factor causes the heuristic to be called more often", &heurdata->successfactor, TRUE, DEFAULT_SUCCESSFACTOR, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/""special_rounding""/oncepernode", "should the heuristic only be called once per node?", &heurdata->oncepernode, TRUE, DEFAULT_ONCEPERNODE, NULL, NULL) ); *heu = heur; return SCIP_OKAY; }
/** creates the rand rounding heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurRandrounding( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecRandrounding, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyRandrounding) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitRandrounding) ); SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitRandrounding) ); SCIP_CALL( SCIPsetHeurInitsol(scip, heur, heurInitsolRandrounding) ); SCIP_CALL( SCIPsetHeurExitsol(scip, heur, heurExitsolRandrounding) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeRandrounding) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/oncepernode", "should the heuristic only be called once per node?", &heurdata->oncepernode, TRUE, DEFAULT_ONCEPERNODE, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/usesimplerounding", "should the heuristic apply the variable lock strategy of simple rounding, if possible?", &heurdata->usesimplerounding, TRUE, DEFAULT_USESIMPLEROUNDING, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/" HEUR_NAME "/propagateonlyroot", "should the probing part of the heuristic be applied exclusively at the root node?", &heurdata->propagateonlyroot, TRUE, DEFAULT_PROPAGATEONLYROOT, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/" HEUR_NAME "/maxproprounds", "limit of rounds for each propagation call", &heurdata->maxproprounds, TRUE, DEFAULT_MAXPROPROUNDS, -1, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates the random branching rule and includes it in SCIP */ SCIP_RETCODE SCIPincludeBranchruleRandom( SCIP* scip /**< SCIP data structure */ ) { SCIP_BRANCHRULEDATA* branchruledata; /* create random branching rule data */ SCIP_CALL( SCIPallocMemory(scip, &branchruledata) ); branchruledata->seed = 0; /* include branching rule */ SCIP_CALL( SCIPincludeBranchrule(scip, BRANCHRULE_NAME, BRANCHRULE_DESC, BRANCHRULE_PRIORITY, BRANCHRULE_MAXDEPTH, BRANCHRULE_MAXBOUNDDIST, branchCopyRandom, branchFreeRandom, branchInitRandom, branchExitRandom, branchInitsolRandom, branchExitsolRandom, branchExeclpRandom, branchExecextRandom, branchExecpsRandom, branchruledata) ); SCIP_CALL( SCIPaddIntParam(scip, "branching/"BRANCHRULE_NAME"/seed", "initial random seed value", &branchruledata->initseed, FALSE, DEFAULT_INITSEED, 0, INT_MAX, NULL, NULL) ); return SCIP_OKAY; }
/** creates the localbranching primal heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurLocalbranching( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create Localbranching primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecLocalbranching, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyLocalbranching) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeLocalbranching) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitLocalbranching) ); /* add localbranching primal heuristic parameters */ SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/nodesofs", "number of nodes added to the contingent of the total nodes", &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/neighborhoodsize", "radius (using Manhattan metric) of the incumbent's neighborhood to be searched", &heurdata->neighborhoodsize, FALSE, DEFAULT_NEIGHBORHOODSIZE, 1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/nodesquot", "contingent of sub problem nodes in relation to the number of nodes of the original problem", &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/lplimfac", "factor by which the limit on the number of LP depends on the node limit", &heurdata->lplimfac, TRUE, DEFAULT_LPLIMFAC, 1.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/minnodes", "minimum number of nodes required to start the subproblem", &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/maxnodes", "maximum number of nodes to regard in the subproblem", &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/nwaitingnodes", "number of nodes without incumbent change that heuristic should wait", &heurdata->nwaitingnodes, TRUE, DEFAULT_NWAITINGNODES, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/minimprove", "factor by which localbranching should at least improve the incumbent", &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/uselprows", "should subproblem be created out of the rows in the LP rows?", &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/copycuts", "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?", &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) ); return SCIP_OKAY; }
/** creates the rapidlearning separator and includes it in SCIP */ SCIP_RETCODE SCIPincludeSepaRapidlearning( SCIP* scip /**< SCIP data structure */ ) { SCIP_SEPADATA* sepadata; /* create rapidlearning separator data */ SCIP_CALL( SCIPallocMemory(scip, &sepadata) ); /* include separator */ SCIP_CALL( SCIPincludeSepa(scip, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST, SEPA_USESSUBSCIP, SEPA_DELAY, sepaCopyRapidlearning, sepaFreeRapidlearning, sepaInitRapidlearning, sepaExitRapidlearning, sepaInitsolRapidlearning, sepaExitsolRapidlearning, sepaExeclpRapidlearning, sepaExecsolRapidlearning, sepadata) ); /* add rapidlearning separator parameters */ SCIP_CALL( SCIPaddBoolParam(scip, "separating/"SEPA_NAME"/applyconflicts", "should the found conflicts be applied in the original SCIP?", &sepadata->applyconflicts, TRUE, DEFAULT_APPLYCONFLICTS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/"SEPA_NAME"/applybdchgs", "should the found global bound deductions be applied in the original SCIP?", &sepadata->applybdchgs, TRUE, DEFAULT_APPLYBDCHGS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/"SEPA_NAME"/applyinfervals", "should the inference values be used as initialization in the original SCIP?", &sepadata->applyinfervals, TRUE, DEFAULT_APPLYINFERVALS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/"SEPA_NAME"/reducedinfer", "should the inference values only be used when "SEPA_NAME" found other reductions?", &sepadata->reducedinfer, TRUE, DEFAULT_REDUCEDINFER, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/"SEPA_NAME"/applyprimalsol", "should the incumbent solution be copied to the original SCIP?", &sepadata->applyprimalsol, TRUE, DEFAULT_APPLYPRIMALSOL, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/"SEPA_NAME"/applysolved", "should a solved status be copied to the original SCIP?", &sepadata->applysolved, TRUE, DEFAULT_APPLYSOLVED, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/"SEPA_NAME"/contvars", "should rapid learning be applied when there are continuous variables?", &sepadata->contvars, TRUE, DEFAULT_CONTVARS, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "separating/"SEPA_NAME"/contvarsquot", "maximal portion of continuous variables to apply rapid learning", &sepadata->contvarsquot, TRUE, DEFAULT_CONTVARSQUOT, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "separating/"SEPA_NAME"/lpiterquot", "maximal fraction of LP iterations compared to node LP iterations", &sepadata->lpiterquot, TRUE, DEFAULT_LPITERQUOT, 0.0, SCIP_REAL_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/"SEPA_NAME"/maxnvars", "maximum problem size (variables) for which rapid learning will be called", &sepadata->maxnvars, TRUE, DEFAULT_MAXNVARS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/"SEPA_NAME"/maxnconss", "maximum problem size (constraints) for which rapid learning will be called", &sepadata->maxnconss, TRUE, DEFAULT_MAXNCONSS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/"SEPA_NAME"/maxnodes", "maximum number of nodes considered in rapid learning run", &sepadata->maxnodes, TRUE, DEFAULT_MAXNODES, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/"SEPA_NAME"/minnodes", "minimum number of nodes considered in rapid learning run", &sepadata->minnodes, TRUE, DEFAULT_MINNODES, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/"SEPA_NAME"/copycuts", "should all active cuts from cutpool be copied to constraints in subproblem?", &sepadata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) ); return SCIP_OKAY; }
/** creates the crossover primal heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurCrossover( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create Crossover primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecCrossover, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyCrossover) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeCrossover) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitCrossover) ); SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitCrossover) ); /* add crossover primal heuristic parameters */ SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/"HEUR_NAME"/nodesofs", "number of nodes added to the contingent of the total nodes", &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0LL, SCIP_LONGINT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/"HEUR_NAME"/maxnodes", "maximum number of nodes to regard in the subproblem", &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/"HEUR_NAME"/minnodes", "minimum number of nodes required to start the subproblem", &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/nusedsols", "number of solutions to be taken into account", &heurdata->nusedsols, FALSE, DEFAULT_NUSEDSOLS, 2, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddLongintParam(scip, "heuristics/"HEUR_NAME"/nwaitingnodes", "number of nodes without incumbent change that heuristic should wait", &heurdata->nwaitingnodes, TRUE, DEFAULT_NWAITINGNODES, 0LL, SCIP_LONGINT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/nodesquot", "contingent of sub problem nodes in relation to the number of nodes of the original problem", &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/minfixingrate", "minimum percentage of integer variables that have to be fixed", &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/minimprove", "factor by which Crossover should at least improve the incumbent", &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/randomization", "should the choice which sols to take be randomized?", &heurdata->randomization, TRUE, DEFAULT_RANDOMIZATION, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/dontwaitatroot", "should the nwaitingnodes parameter be ignored at the root node?", &heurdata->dontwaitatroot, TRUE, DEFAULT_DONTWAITATROOT, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/uselprows", "should subproblem be created out of the rows in the LP rows?", &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/copycuts", "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?", &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/permute", "should the subproblem be permuted to increase diversification?", &heurdata->permute, TRUE, DEFAULT_PERMUTE, NULL, NULL) ); return SCIP_OKAY; }
/** creates the closecuts separator and includes it in SCIP */ SCIP_RETCODE SCIPincludeSepaClosecuts( SCIP* scip /**< SCIP data structure */ ) { SCIP_SEPADATA* sepadata; /* create closecuts separator data */ SCIP_CALL( SCIPallocMemory(scip, &sepadata) ); sepadata->sepasol = NULL; sepadata->discardnode = -1; sepadata->nunsuccessful = 0; /* include separator */ SCIP_CALL( SCIPincludeSepa(scip, SEPA_NAME, SEPA_DESC, SEPA_PRIORITY, SEPA_FREQ, SEPA_MAXBOUNDDIST, SEPA_USESSUBSCIP, SEPA_DELAY, sepaCopyClosecuts, sepaFreeClosecuts, sepaInitClosecuts, sepaExitClosecuts, sepaInitsolClosecuts, sepaExitsolClosecuts, sepaExeclpClosecuts, sepaExecsolClosecuts, sepadata) ); /* add closecuts separator parameters */ SCIP_CALL( SCIPaddBoolParam(scip, "separating/closecuts/separelint", "generate close cuts w.r.t. relative interior point (best solution otherwise)?", &sepadata->separelint, TRUE, SCIP_DEFAULT_SEPARELINT, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "separating/closecuts/sepacombvalue", "convex combination value for close cuts", &sepadata->sepacombvalue, TRUE, SCIP_DEFAULT_SEPACOMBVALUE, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/closecuts/separootonly", "generate close cuts in the root only?", &sepadata->separootonly, TRUE, SCIP_DEFAULT_SEPAROOTONLY, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/closecuts/closethres", "threshold on number of generated cuts below which the ordinary separation is started", &sepadata->sepathreshold, TRUE, SCIP_DEFAULT_SEPATHRESHOLD, -1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/closecuts/inclobjcutoff", "include an objective cutoff when computing the relative interior?", &sepadata->inclobjcutoff, TRUE, SCIP_DEFAULT_INCLOBJCUTOFF, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "separating/closecuts/recomputerelint", "recompute relative interior point in each separation call?", &sepadata->recomputerelint, TRUE, SCIP_DEFAULT_RECOMPUTERELINT, NULL, NULL) ); SCIP_CALL( SCIPaddCharParam(scip, "separating/closecuts/relintnormtype", "type of norm to use when computing relative interior: 'o'ne norm, 's'upremum norm", &sepadata->relintnormtype, TRUE, SCIP_DEFAULT_RELINTNORMTYPE, "os", NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "separating/closecuts/maxunsuccessful", "turn off separation in current node after unsuccessful calls (-1 never turn off)", &sepadata->maxunsuccessful, TRUE, SCIP_DEFAULT_MAXUNSUCCESSFUL, -1, INT_MAX, NULL, NULL) ); 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; }
/** creates the mutation primal heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurMutation( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create Mutation primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecMutation, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyMutation) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeMutation) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitMutation) ); /* add mutation primal heuristic parameters */ SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/nodesofs", "number of nodes added to the contingent of the total nodes", &heurdata->nodesofs, FALSE, DEFAULT_NODESOFS, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/maxnodes", "maximum number of nodes to regard in the subproblem", &heurdata->maxnodes, TRUE, DEFAULT_MAXNODES, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/minnodes", "minimum number of nodes required to start the subproblem", &heurdata->minnodes, TRUE, DEFAULT_MINNODES, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/"HEUR_NAME"/nwaitingnodes", "number of nodes without incumbent change that heuristic should wait", &heurdata->nwaitingnodes, TRUE, DEFAULT_NWAITINGNODES, 0, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/nodesquot", "contingent of sub problem nodes in relation to the number of nodes of the original problem", &heurdata->nodesquot, FALSE, DEFAULT_NODESQUOT, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/minfixingrate", "percentage of integer variables that have to be fixed", &heurdata->minfixingrate, FALSE, DEFAULT_MINFIXINGRATE, SCIPsumepsilon(scip), 1.0-SCIPsumepsilon(scip), NULL, NULL) ); SCIP_CALL( SCIPaddRealParam(scip, "heuristics/"HEUR_NAME"/minimprove", "factor by which "HEUR_NAME" should at least improve the incumbent", &heurdata->minimprove, TRUE, DEFAULT_MINIMPROVE, 0.0, 1.0, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/uselprows", "should subproblem be created out of the rows in the LP rows?", &heurdata->uselprows, TRUE, DEFAULT_USELPROWS, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/"HEUR_NAME"/copycuts", "if uselprows == FALSE, should all active cuts from cutpool be copied to constraints in subproblem?", &heurdata->copycuts, TRUE, DEFAULT_COPYCUTS, NULL, NULL) ); return SCIP_OKAY; }
/** creates the octane primal heuristic and includes it in SCIP */ SCIP_RETCODE SCIPincludeHeurOctane( SCIP* scip /**< SCIP data structure */ ) { SCIP_HEURDATA* heurdata; SCIP_HEUR* heur; /* create Octane primal heuristic data */ SCIP_CALL( SCIPallocMemory(scip, &heurdata) ); /* include primal heuristic */ SCIP_CALL( SCIPincludeHeurBasic(scip, &heur, HEUR_NAME, HEUR_DESC, HEUR_DISPCHAR, HEUR_PRIORITY, HEUR_FREQ, HEUR_FREQOFS, HEUR_MAXDEPTH, HEUR_TIMING, HEUR_USESSUBSCIP, heurExecOctane, heurdata) ); assert(heur != NULL); /* set non-NULL pointers to callback methods */ SCIP_CALL( SCIPsetHeurCopy(scip, heur, heurCopyOctane) ); SCIP_CALL( SCIPsetHeurFree(scip, heur, heurFreeOctane) ); SCIP_CALL( SCIPsetHeurInit(scip, heur, heurInitOctane) ); SCIP_CALL( SCIPsetHeurExit(scip, heur, heurExitOctane) ); /* add octane primal heuristic parameters */ SCIP_CALL( SCIPaddIntParam(scip, "heuristics/octane/fmax", "number of 0-1-points to be tested as possible solutions by OCTANE", &heurdata->f_max, TRUE, DEFAULT_FMAX, 1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddIntParam(scip, "heuristics/octane/ffirst", "number of 0-1-points to be tested at first whether they violate a common row", &heurdata->f_first, TRUE, DEFAULT_FFIRST, 1, INT_MAX, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/octane/usefracspace", "execute OCTANE only in the space of fractional variables (TRUE) or in the full space?", &heurdata->usefracspace, TRUE, DEFAULT_USEFRACSPACE, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/octane/useobjray", "should the inner normal of the objective be used as one ray direction?", &heurdata->useobjray, TRUE, TRUE, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/octane/useavgray", "should the average of the basic cone be used as one ray direction?", &heurdata->useavgray, TRUE, TRUE, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/octane/usediffray", "should the difference between the root solution and the current LP solution be used as one ray direction?", &heurdata->usediffray, TRUE, FALSE, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/octane/useavgwgtray", "should the weighted average of the basic cone be used as one ray direction?", &heurdata->useavgwgtray, TRUE, TRUE, NULL, NULL) ); SCIP_CALL( SCIPaddBoolParam(scip, "heuristics/octane/useavgnbray", "should the weighted average of the nonbasic cone be used as one ray direction?", &heurdata->useavgnbray, TRUE, TRUE, NULL, NULL) ); return SCIP_OKAY; }