27 using namespace Ipopt;
28 using namespace Couenne;
31 void CouenneFeasPump::initIpoptApp () {
38 app_ = IpoptApplicationFactory ();
40 ApplicationReturnStatus status = app_ -> Initialize ();
42 app_ -> Options () -> SetIntegerValue (
"max_iter", 1000);
43 app_ -> Options () -> SetIntegerValue
44 (
"print_level", (problem_ -> Jnlst () -> ProduceOutput (J_ITERSUMMARY,
J_NLPHEURISTIC) ? 4 :
45 problem_ -> Jnlst () -> ProduceOutput (J_MOREDETAILED,
J_NLPHEURISTIC) ? 5 : 0));
47 app_ -> Options () -> SetStringValue (
"fixed_variable_treatment",
"make_parameter");
50 app_ -> Options () -> SetStringValue (
"sb",
"yes",
false,
true);
52 if (status != Solve_Succeeded)
53 printf (
"FP: Error in initialization\n");
71 numberSolvePerLevel_ (5),
81 compDistInt_ (FP_DIST_INT),
82 milpCuttingPlane_ (FP_CUT_NONE),
84 maxIter_ (COIN_INT_MAX),
87 tabuMgt_ (FP_TABU_NONE),
97 options -> GetIntegerValue (
"feas_pump_iter",
maxIter_,
"couenne.");
99 options -> GetIntegerValue (
"feas_pump_milpmethod",
milpMethod_,
"couenne.");
101 options -> GetNumericValue (
"feas_pump_mult_dist_nlp",
multDistNLP_,
"couenne.");
102 options -> GetNumericValue (
"feas_pump_mult_hess_nlp",
multHessNLP_,
"couenne.");
103 options -> GetNumericValue (
"feas_pump_mult_objf_nlp",
multObjFNLP_,
"couenne.");
105 options -> GetNumericValue (
"feas_pump_mult_dist_milp",
multDistMILP_,
"couenne.");
106 options -> GetNumericValue (
"feas_pump_mult_hess_milp",
multHessMILP_,
"couenne.");
107 options -> GetNumericValue (
"feas_pump_mult_objf_milp",
multObjFMILP_,
"couenne.");
109 options -> GetNumericValue (
"feas_pump_fademult",
fadeMult_,
"couenne.");
111 options -> GetStringValue (
"feas_pump_convcuts", s,
"couenne.");
118 options -> GetIntegerValue (
"feas_pump_nseprounds",
nSepRounds_,
"couenne.");
120 options -> GetStringValue (
"feas_pump_vardist", s,
"couenne.");
126 options -> GetIntegerValue (
"feas_pump_milpmethod",
milpMethod_,
"couenne.");
127 options -> GetIntegerValue (
"feas_pump_poolcomp", compareTerm,
"couenne.");
129 options -> GetStringValue (
"feas_pump_tabumgt", s,
"couenne.");
136 options -> GetStringValue (
"feas_pump_usescip", s,
"couenne.");
144 problem_ -> Jnlst () -> Printf (J_ERROR,
J_COUENNE,
"Warning: you have set feas_pump_usescip to true, but SCIP is not installed.\n");
154 setHeuristicName (
"Couenne Feasibility Pump");
175 CbcHeuristic::operator= (rhs);
208 for (std::set <CouenneFPsolution, compareSol>::const_iterator i = rhs.
tabuPool_.begin ();
241 const double *iS = iSol;
250 (
nlp_ -> optHessian () == NULL)) {
257 for (
int i=0; i<
problem_ -> nVars (); ++i, ++iS) {
259 if (
problem_ -> Var (i) -> Multiplicity () <= 0)
291 int *row =
nlp_ -> optHessian () -> row ();
292 int *col =
nlp_ -> optHessian () -> col ();
293 double *val =
nlp_ -> optHessian () -> val ();
295 int num =
nlp_ -> optHessian () -> num ();
302 for (
int i=0; i<
problem_ -> nVars (); ++i)
303 if (!((
problem_ -> Var (i) -> Multiplicity () <= 0) ||
308 nActualTerms = (nActualTerms == 0) ? 1 : (1 / sqrt (nActualTerms));
311 for (
int i=0; i<num; ++i, ++val)
312 if (*row++ == *col++)
313 trace_H += *val * *val;
315 trace_H = (trace_H <
COUENNE_EPS) ? 1 : (1 / sqrt (trace_H));
317 row =
nlp_ -> optHessian () -> row ();
318 col =
nlp_ -> optHessian () -> col ();
319 val =
nlp_ -> optHessian () -> val ();
322 for (
int i=0; i<num; ++i, ++row, ++col, ++val) {
324 if ((
problem_ -> Var (*row) -> Multiplicity () <= 0) ||
325 (
problem_ -> Var (*col) -> Multiplicity () <= 0))
339 if (2. * *val * trace_H == 1.)
348 mlist [0] =
new exprConst (2. * *val * trace_H);
352 list [nTerms++] =
new exprMul (mlist, 3);
355 }
else if (*col == *row) {
360 if (trace_H * *val +
multDistNLP () * nActualTerms == 1.)
415 list = CoinCopyOfArray (tmp, nTerms);
434 for (
int i =
problem_ -> nVars (); i--;)
437 (
problem_ -> Var (i) -> Multiplicity () > 0)) {
447 (rUp < rDn + 0.5) ? rUp :
448 (rUp - value < value - rDn) ? rUp : rDn;
450 #define INT_NLP_BRACKET 1e-6
462 bool retval =
problem_ -> btCore (chg_bds);
473 roptions -> AddStringOption4
474 (
"feas_pump_heuristic",
475 "Apply the nonconvex Feasibility Pump",
477 "no",
"never called",
478 "yes",
"called any time Cbc calls heuristics",
479 "once",
"call it at most once",
480 "only",
"Call it exactly once and then exit",
481 "An implementation of the Feasibility Pump for nonconvex MINLPs");
483 roptions -> AddBoundedNumberOption
484 (
"feas_pump_fademult",
485 "decrease/increase rate of multipliers",
488 1,
"1 keeps initial multipliers from one call to the next; any <1 multiplies ALL of them");
490 roptions -> AddLowerBoundedIntegerOption
492 "Specify the logarithm of the number of feasibility pumps to perform"
493 " on average for each level of given depth of the tree.",
495 3,
"Solve as many nlp's at the nodes for each level of the tree. "
496 "Nodes are randomly selected. If for a "
497 "given level there are less nodes than this number nlp are solved for every nodes. "
498 "For example, if parameter is 8 NLPs are solved for all node until level 8, "
499 "then for half the node at level 9, 1/4 at level 10.... "
500 "Set to -1 to perform at all nodes.");
502 roptions -> AddLowerBoundedIntegerOption
504 "Number of iterations in the main Feasibility Pump loop (default: 10)",
506 10,
"-1 means no limit");
513 std::string terms [] = {
"dist",
"hess",
"objf"};
514 std::string types [] = {
"nlp",
"milp"};
516 for (
int j=0;
j<3;
j++)
517 for (
int i=0; i<2; i++) {
519 sprintf (option,
"feas_pump_mult_%s_%s", terms [
j].c_str (), types [i].c_str ());
520 sprintf (help,
"Weight of the %s in the distance function of the %s problem",
521 !(strcmp (
"dist", terms [
j].c_str ())) ?
"distance" :
522 !(strcmp (
"hess", terms [
j].c_str ())) ?
"Hessian" :
"original objective function", types [i].c_str ());
524 roptions -> AddBoundedNumberOption
528 0.,
"0: neglected; 1: full weight; a in ]0,1[: weight is a^k where k is the FP iteration; a in ]-1,0[: weight is 1-|a|^k");
531 roptions -> AddStringOption3
532 (
"feas_pump_vardist",
533 "Distance computed on integer-only or on both types of variables, in different flavors.",
535 "integer",
"Only compute the distance based on integer coordinates (use post-processing if numerical errors occur)",
536 "all",
"Compute the distance using continuous and integer variables",
537 "int-postprocess",
"Use a post-processing fixed-IP LP to determine a closest-point solution");
539 roptions -> AddStringOption4
540 (
"feas_pump_convcuts",
541 "Separate MILP-feasible, MINLP-infeasible solution during or after MILP solver.",
543 "integrated",
"Done within the MILP solver in a branch-and-cut fashion",
544 "external",
"Done after the MILP solver, in a Benders-like fashion",
545 "postcut",
"Do one round of cuts and proceed with NLP",
546 "none",
"Just proceed to the NLP");
548 roptions -> AddBoundedIntegerOption
549 (
"feas_pump_nseprounds",
550 "Number of rounds of convexification cuts. Must be at least 1",
554 roptions -> AddStringOption4
555 (
"feas_pump_tabumgt",
556 "Retrieval of MILP solutions when the one returned is unsatisfactory",
558 "pool",
"Use a solution pool and replace unsatisfactory solution with Euclidean-closest in pool",
559 "perturb",
"Randomly perturb unsatisfactory solution",
560 "cut",
"Separate convexification cuts",
561 "none",
"Bail out of feasibility pump");
563 roptions -> AddStringOption2
564 (
"feas_pump_usescip",
565 "Should SCIP be used to solve the MILPs?",
571 "no",
"Use Cbc's branch-and-cut to solve the MILP",
572 "yes",
"Use SCIP's branch-and-cut or heuristics (see feas_pump_milpmethod option) to solve the MILP",
575 roptions -> AddBoundedIntegerOption
576 (
"feas_pump_milpmethod",
577 "How should the integral solution be constructed?",
579 "0: automatic, 1: aggressive heuristics, large node limit, 2: default, node limit, 3: RENS, 4: Objective Feasibility Pump, 5: MINLP rounding heuristic, 6: rounding, -1: solve MILP completely");
581 roptions -> AddBoundedIntegerOption
582 (
"feas_pump_poolcomp",
583 "Priority field to compare solutions in FP pool",
586 0: total number of infeasible objects (integer and nonlinear); \
587 1: maximum infeasibility (integer or nonlinear); \
588 2: objective value; \
589 3: compare value of all variables; \
590 4: compare value of all integers (RECOMMENDED).");
Cut Generator for linear convexifications.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions >)
initialize options to be read later
Ipopt::IpoptApplication * app_
Ipopt Application pointer for solving NLPs.
double multDistMILP_
weight of distance in MILP
CouenneCutGenerator * couenneCG_
CouenneCutGenerator for linearization cuts.
expression * updateNLPObj(const double *)
set new expression as the NLP objective function using argument as point to minimize distance from...
double multObjFNLP_
weight of objective in NLP
int maxIter_
Maximum iterations per call.
status of lower/upper bound of a variable, to be checked/modified in bound tightening ...
int nCalls_
How often should it be called.
double multObjFMILP_
weight of objective in MILP
void setLower(ChangeStatus lower)
double multObjFNLP() const
weight of objective in NLP
Power of an expression (binary operator), with constant.
CouenneFeasPump & operator=(const CouenneFeasPump &rhs)
Assignment operator.
int nSepRounds_
Number of separation rounds for MILP convexification cuts.
bool IsValid(const OSSmartPtr< U > &smart_ptr)
virtual CbcHeuristic * clone() const
Clone.
virtual ~CouenneFeasPump()
Destructor.
double multHessMILP_
weight of Hessian in MILP
enum fpCutPlane milpCuttingPlane_
Separate convexification cuts during or after MILP.
CouenneFPpool * pool_
Pool of solutions.
what_to_compare
what term to compare: the sum of infeasibilities, the sum of numbers of infeasible terms...
An implementation of the Feasibility pump that uses linearization and Ipopt to find the two sequences...
int milpMethod_
Which SCIP MILP method to use.
Class containing a solution with infeasibility evaluation.
double multDistNLP_
Weights in computing distance, in both MILP and NLP (must sum up to 1 for MILP and for NLP): ...
void setUpper(ChangeStatus upper)
Class for MINLP problems with symbolic information.
bool useSCIP_
Use SCIP instead of Cbc for solving MILPs.
expression clone (points to another expression)
int numberSolvePerLevel_
Number of NLPs solved for each given level of the tree.
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
enum fpCompDistIntType compDistInt_
Compute distance from integer variables only, not all variables.
std::set< CouenneFPsolution, compareSol > tabuPool_
Solutions to avoid.
double multHessNLP_
weight of Hessian in NLP
OsiSolverInterface * postlp_
LP relaxation of the MINLP used when fixing integer variables (used for compDistInt_ in FP_DIST_POST ...
CouenneFeasPump(CouenneProblem *couenne=NULL, CouenneCutGenerator *cg=NULL, Ipopt::SmartPtr< Ipopt::OptionsList > options=NULL)
Constructor with (optional) MINLP pointer.
enum fpTabuMgtPolicy tabuMgt_
Tabu management policy: none, use from pool, random perturbation of current solution.
const Ipopt::EJournalCategory J_NLPHEURISTIC(Ipopt::J_USER5)
void initIpoptApp()
Common code for initializing non-smartptr ipopt application.
double multDistNLP() const
Return Weights in computing distance, in both MILP and NLP (must sum up to 1 for MILP and for NLP): ...
CouenneProblem * problem_
Couenne representation of the problem.
double fadeMult_
decrease factor for MILP/NLP multipliers of distance/Hessian/objective
const Ipopt::EJournalCategory J_COUENNE(Ipopt::J_USER8)
OsiSolverInterface * milp_
MILP relaxation of the MINLP (used to find integer, non-NLP-feasible solutions)
bool fixIntVariables(const double *sol)
admits a (possibly fractional) solution and fixes the integer components in the nonlinear problem for...
class for multiplications,
CouenneTNLP * nlp_
Continuous relaxation of the problem, with an interface for Ipopt only.
bool isInteger(CouNumber x)
is this number integer?