13 #include "CoinHelperFunctions.hpp"
27 using namespace Ipopt;
28 using namespace Couenne;
34 bool CouenneProblem::standardize () {
37 printf (
"Reformulation. current point: %d vars -------------------\n",
38 domain_.current () -> Dimension ());
39 for (
int i=0; i<domain_.current () -> Dimension (); i++)
40 printf (
"%3d %20g [%20g %20g]\n", i, domain_.x (i), domain_.lb (i), domain_.ub (i));
49 for (std::vector <exprVar *>::iterator i = variables_ . begin ();
50 i != variables_ .
end (); ++i)
51 graph_ -> insert (*i);
175 for (std::vector <CouenneObjective *>::iterator i = objectives_.begin ();
176 i != objectives_.end (); ++i) {
179 printf (
"Objective [code: %d]", (*i) -> Body () -> code ());
185 std::set <int> deplist;
192 constObjVal_ = (*i) -> Body () -> Value ();
196 exprAux *aux = (*i) -> standardize (
this);
199 printf (
" objective "); (*i) -> print ();
200 if (aux) {printf (
" admits aux "); aux -> print ();}
209 printf (
". New obj: "); (*i) -> print (); printf (
"\n");
226 commuted_ =
new bool [nVars ()];
227 CoinFillN (commuted_, nVars (),
false);
229 std::vector <std::vector <CouenneConstraint *>::iterator> iters2erase;
231 for (std::vector <CouenneConstraint *>::iterator i = constraints_.begin ();
232 i != constraints_.end (); ++i) {
235 printf (
"\nReformulating constraint: ");
240 conLb = (*((*i) -> Lb ())) (),
241 conUb = (*((*i) -> Ub ())) ();
249 if (eBody -> Linearity () <=
CONSTANT) {
257 "Constraint: all variables eliminated, but value %g out of bounds [%g,%g]: ",
258 bodyVal, conLb, conUb);
260 if (jnlst_ -> ProduceOutput (J_SUMMARY,
J_PROBLEM))
268 iters2erase.push_back (i);
273 exprAux *aux = (*i) -> standardize (
this);
276 printf (
" reformulated: aux w[%d] ", aux ? (aux -> Index ()) : -2);
286 aux -> top_level () =
true;
330 iters2erase.push_back (i);
335 if (jnlst_ -> ProduceOutput (J_ALL,
J_REFORMULATE)) {printf (
" --> "); (*i) -> print (); printf (
"\n\n");}
342 for (
unsigned int i = iters2erase.size (); i--;)
343 constraints_. erase (iters2erase [i]);
347 printf (
"Done with standardization (careful, bounds below can be nonsense):\n");
357 if ((bonBase_ -> options () -> GetIntegerValue (
"sdp_cuts", freq,
"couenne.")) &&
360 sdpCutGen_ =
new CouenneSdpCuts (
this, jnlst_, bonBase_ -> options ());
365 #define ANTICIPATE_DELETE_REDUND
366 #ifdef ANTICIPATE_DELETE_REDUND
378 std::string delete_redund;
380 if (bonBase_) bonBase_ -> options () -> GetStringValue (
"delete_redundant", delete_redund,
"couenne.");
381 else delete_redund =
"yes";
383 if (delete_redund ==
"yes")
386 for (std::vector <exprVar *>::iterator i = variables_.begin ();
387 i != variables_.end (); ++i)
389 if (((*i) -> Multiplicity () > 0) && ((*i) -> Type () ==
AUX) && ((*i) -> sign () == expression::AUX_EQ)) {
391 int type = (*i) -> Image () -> Type ();
393 if ((type ==
VAR) || (type ==
AUX)) {
408 indStays = (*i) -> Image () -> Index (),
409 indLeaves = (*i) -> Index ();
411 if (indStays == indLeaves)
420 *varStays = variables_ [indStays],
421 *varLeaves = variables_ [indLeaves];
425 varStays -> lb () = varLeaves -> lb () = CoinMax (varStays -> lb (), varLeaves -> lb ());
426 varStays -> ub () = varLeaves -> ub () = CoinMin (varStays -> ub (), varLeaves -> ub ());
431 varStays -> lb () = ceil (varStays -> lb ());
432 varStays -> ub () = floor (varStays -> ub ());
434 if (varStays -> Type () ==
AUX)
435 varStays -> setInteger (
true);
438 variables_ [indStays] = varStays =
new exprIVar (indStays, &domain_);
439 auxiliarize (varStays);
444 auxiliarize (varLeaves, varStays);
447 varLeaves -> zeroMult ();
455 for (std::vector <exprVar *>::iterator i = variables_. begin ();
456 i != variables_.
end (); ++i)
458 if (((*i) -> Multiplicity () > 0) &&
459 ((*i) -> Type () ==
AUX)) {
462 *image = (*i) -> Image (),
463 *simpl = image -> simplify ();
468 (subst = simpl -> standardize (
this))) {
469 if ((subst -> Type () ==
VAR) ||
470 (subst -> Type () ==
AUX))
475 if (simpl && simpl != subst) {
479 delete (*i) -> Image ();
480 (*i) -> Image (simpl);
484 }
while (has_changed);
494 domain_.current () -> resize (nVars ());
497 graph_ -> createOrder ();
500 assert (graph_ -> checkCycles () ==
false);
505 numbering_ =
new int [
n];
506 std::set <DepNode *, compNode> vertices = graph_ -> Vertices ();
508 for (std::set <DepNode *, compNode>::iterator i = vertices.begin ();
509 i != vertices.end (); ++i)
511 numbering_ [(*i) -> Order ()] = (*i) -> Index ();
517 for (
int i = 0; i < nVars (); i++) {
519 int ord = numbering_ [i];
521 if (variables_ [ord] -> Multiplicity () <= 0)
524 if (variables_ [ord] -> Type () ==
AUX) {
529 if (variables_ [ord] -> Index () >= nOrigVars_) {
531 domain_.lb (ord) = -COIN_DBL_MAX;
532 domain_.ub (ord) = COIN_DBL_MAX;
538 variables_ [ord] -> crossBounds ();
543 printf (
":::: %3d %10g [%10g, %10g]",
544 ord, domain_.x (ord), domain_.lb (ord), domain_.ub (ord));
548 domain_.x (ord) = (*(variables_ [ord] -> Image ())) ();
549 domain_.lb (ord) = (*(variables_ [ord] -> Lb ())) ();
550 domain_.ub (ord) = (*(variables_ [ord] -> Ub ())) ();
559 printf (
" --> %10g [%10g, %10g] [",
560 domain_.x (ord), domain_.lb (ord), domain_.ub (ord));
561 variables_ [ord] -> Lb () -> print (); printf (
",");
562 variables_ [ord] -> Ub () -> print (); printf (
"]\n");
565 bool integer = variables_ [ord] ->
isInteger ();
568 domain_.lb (ord) = ceil (domain_.lb (ord) -
COUENNE_EPS);
569 domain_.ub (ord) = floor (domain_.ub (ord) +
COUENNE_EPS);
574 #ifndef ANTICIPATE_DELETE_REDUND
580 std::string delete_redund;
582 if (bonBase_) bonBase_ -> options () -> GetStringValue (
"delete_redundant", delete_redund,
"couenne.");
583 else delete_redund =
"yes";
585 if (delete_redund ==
"yes")
588 for (std::vector <exprVar *>::iterator i = variables_.begin ();
589 i != variables_.end (); ++i)
591 if (((*i) -> Type () ==
AUX) && ((*i) -> sign () == expression::AUX_EQ)) {
593 int type = (*i) -> Image () -> Type ();
595 if ((type ==
VAR) || (type ==
AUX)) {
610 indStays = (*i) -> Image () -> Index (),
611 indLeaves = (*i) -> Index ();
613 if (indStays == indLeaves)
622 *varStays = variables_ [indStays],
623 *varLeaves = variables_ [indLeaves];
627 varStays -> lb () = varLeaves -> lb () = CoinMax (varStays -> lb (), varLeaves -> lb ());
628 varStays -> ub () = varLeaves -> ub () = CoinMin (varStays -> ub (), varLeaves -> ub ());
633 varStays -> lb () = ceil (varStays -> lb ());
634 varStays -> ub () = floor (varStays -> ub ());
636 if (varStays -> Type () ==
AUX)
637 varStays -> setInteger (
true);
640 variables_ [indStays] = varStays =
new exprIVar (indStays, &domain_);
641 auxiliarize (varStays);
646 auxiliarize (varLeaves, varStays);
649 varLeaves -> zeroMult ();
660 for (
int ii=0; ii < nVars (); ii++) {
662 int i = numbering_ [ii];
664 if ((Var (i) -> Multiplicity () > 0) &&
665 (Var (i) -> Type () ==
AUX) &&
667 (Var (i) -> sign () == expression::AUX_EQ))
668 Var (i) -> setInteger (
true);
705 delete [] commuted_; commuted_ = NULL;
706 delete graph_; graph_ = NULL;
#define COUENNE_BOUND_PREC
void replace(CouenneProblem *p, int wind, int xind)
These are cuts of the form.
Class for MINLP problems with symbolic information.
expression clone (points to another expression)
const Ipopt::EJournalCategory J_REFORMULATE(Ipopt::J_USER7)
double CouNumber
main number type in Couenne
const Ipopt::EJournalCategory J_PROBLEM(Ipopt::J_USER4)
bool isInteger(CouNumber x)
is this number integer?