19 #include "CoinPragma.hpp"
20 #include "CoinTime.hpp"
21 #include "CoinError.hpp"
29 #include "CbcCutGenerator.hpp"
35 using namespace Couenne;
38 #define PRINTED_PRECISION 1e-5
54 #include "lpiswitch.h"
57 #include "CoinSignal.hpp"
59 #undef printError // defined in SCIP, replaces error handling below...
64 static int nInterrupts = 0;
68 std::cerr <<
"[BREAK]" << std::endl;
80 int main (
int argc,
char *argv[]) {
83 srand ((
long) 42*666);
90 Couenne %s -- an Open-Source solver for Mixed Integer Nonlinear Optimization\n\
91 Mailing list: couenne@list.coin-or.org\n\
92 Instructions: http://www.coin-or.org/Couenne\n",
95 WindowsErrorPopupBlocker();
97 using namespace Ipopt;
101 SCIPlpiSwitchSetSolver(SCIP_LPISW_CLP);
104 char * pbName = NULL;
119 p -> addVariable (
false, p -> domain ());
120 p -> addVariable (
false, p -> domain ());
121 p -> addVariable (
false, p -> domain ());
122 p -> addVariable (
false, p -> domain ());
136 infeasible = !(couenne.InitializeCouenne (argv, p, NULL, ci, &bb));
141 if (couenne. cutGenerators () . size () > 0) {
143 for (std::list <Bonmin::BabSetupBase::CuttingMethod>::iterator
144 i = couenne.cutGenerators () . begin ();
145 !cg && (i != couenne.cutGenerators () .
end ());
148 cg = dynamic_cast <CouenneCutGenerator *> (i -> cgl);
157 cg -> setBabPtr (&bb);
161 printf (
"main(): ### ERROR: Can not get CouenneCutGenerator\n");
167 jnlst = couenne. couennePtr () -> Jnlst ();
168 prob = couenne. couennePtr () -> Problem ();
170 bb. setProblem (prob);
175 Loaded instance \"%s\"\n\
177 Variables: %8d (%d integer)\n\
178 Auxiliaries: %8d (%d integer)\n\n",
179 prob -> problemName ().c_str (),
180 prob -> nOrigCons (),
181 prob -> nOrigVars (),
182 prob -> nOrigIntVars (),
183 prob -> nVars () - prob -> nOrigVars (),
184 CoinMax (0, prob -> nIntVars () - prob -> nOrigIntVars ()));
186 double time_start = CoinCpuTime();
189 CouenneFeasibility feasibility;
190 bb.
model().setProblemFeasibility (feasibility);
193 couenne.options () -> SetIntegerValue (
"bb_log_level", 1);
194 couenne.options () -> SetIntegerValue (
"lp_log_level", 0);
195 couenne.options () -> SetIntegerValue (
"nlp_log_level", 0);
198 double timeLimit = 0;
199 couenne.options () -> GetNumericValue (
"time_limit", timeLimit,
"couenne.");
201 CoinMax (1., timeLimit - time_start));
208 double symmGroupSize = prob -> orbitalBranching () ? prob -> getNtyInfo () -> getGroupSize () : -1;
214 couenne.options () -> GetStringValue (
"feas_pump_heuristic", s,
"couenne.");
240 couenne.options () -> PrintUserOptions (liststr);
241 jnlst -> Printf (J_ERROR, J_MAIN,
"\nList of user-set options:\n\n%s", liststr.c_str());
248 char *filename =
new char [prob -> problemName (). length () + strlen ((
char *)
".sol") + 1],
253 strcpy (filename, prob -> problemName () . c_str ());
255 if ((lastdot = strrchr (filename,
'.')) != NULL)
258 strcat (filename,
".sol");
260 amplsol = fopen (filename,
"w");
262 if (amplsol != NULL) {
264 fprintf (amplsol,
"Couenne (%s %s): Infeasible\n\nOptions\n3\n0\n1\n0\n%d\n0\n%d\n0\nobjno 0 220\n",
265 prob -> problemName (). c_str (),
267 prob -> nOrigCons (),
268 prob -> nOrigVars ());
281 std::cout.precision (10);
286 if (cg) cg -> getStats (nr,
nt, st);
287 else printf (
"Warning, could not get pointer to CouenneCutGenerator\n");
291 #if defined (FM_TRACE_OPTSOL) || defined (FM_FRES)
292 double cbcLb = (
infeasible ? -COIN_DBL_MAX : bb.
model (). getBestPossibleObjValue ());
294 bool foundSol =
false;
297 #ifdef FM_TRACE_OPTSOL
307 double cbcObjVal =
infeasible ? COIN_DBL_MAX : bb.
model().getObjValue();
308 int modelNvars = prob -> nVars ();
311 const double *cbcSol =
infeasible ? NULL : bb.
model().getColSolution();
312 double *modCbcSol =
new double[modelNvars];
313 double modCbcSolVal= 1e100, modCbcSolMaxViol = 0;
314 bool cbcSolIsFeas =
false;
316 if(modelNvars != cp->
nVars()) {
317 printf(
"### ERROR: modelNvars: %d nVars: %d\n",
318 modelNvars, cp->
nVars());
332 cbcSolIsFeas = cp->
checkNLP2(cbcSol, 0,
false,
337 CoinCopyN(rs->
getModSol(cMS), cMS, modCbcSol);
341 int cMS = cp->
nVars();
342 cbcSolIsFeas = cp->
checkNLP(cbcSol, modCbcSolVal,
true);
343 CoinCopyN(cbcSol, cMS, modCbcSol);
349 const double *couenneSol = rs->
getSol();
350 double *modCouenneSol =
new double[modelNvars];
351 double modCouenneSolVal= 1e100, modCouenneSolMaxViol = 0;
352 bool couenneSolIsFeas =
false;
360 if(couenneSol != NULL) {
363 couenneSolIsFeas = cp->
checkNLP2(couenneSol, 0,
false,
366 CoinCopyN(rs->
getModSol(cMS), cMS, modCouenneSol);
370 int cMS = cp->
nVars();
371 couenneSolIsFeas = cp->
checkNLP(couenneSol, modCouenneSolVal,
true);
372 CoinCopyN(couenneSol, cMS, modCouenneSol);
378 retcomp = rs -> compareAndSave (modCbcSol, modCbcSolVal, modCbcSolMaxViol, cbcSolIsFeas,
379 modCouenneSol, modCouenneSolVal, modCouenneSolMaxViol, couenneSolIsFeas,
387 couenne.options () -> GetStringValue (
"save_soltext", saveSol,
"couenne.");
389 if (saveSol ==
"yes") {
391 char *txtFileName =
new char [20 + cp -> problemName () . length ()];
393 sprintf (txtFileName,
"%s-sol.txt", cp -> problemName (). c_str ());
395 FILE *txtSol = fopen (txtFileName,
"w");
397 if (txtSol == NULL) {
399 printf (
"Could not create file %s for solving solution\n", txtFileName);
403 cp -> domain () -> push (cp -> nOrigVars (), rs -> getSol (), NULL, NULL);
407 for (std::vector <exprVar *>::iterator it = cp ->
Variables (). begin ();
410 if ((*it) -> Index () >= cp -> nOrigVars ())
413 if ((*it) -> Multiplicity () == 0) {
415 if ((*it) -> Image ()) fprintf (txtSol,
"%d %e\n", (*it) -> Index (), (*(*it) -> Image ()) ());
416 else fprintf (txtSol,
"%d %e\n", (*it) -> Index (), 0);
418 }
else fprintf (txtSol,
"%d %e\n", (*it) -> Index (), (*(*it)) ());
421 cp -> domain () -> pop ();
426 delete [] txtFileName;
437 if(cbcLb > rs->
getVal()) {
445 delete[] modCouenneSol;
453 f_res = fopen(
"fres.xxx",
"r");
455 f_res = fopen(
"fres.xxx",
"w");
456 fprintf(f_res,
"END_OF_HEADER\n");
460 f_res = fopen(
"fres.xxx",
"a");
462 char *pbName, shortName[256];
464 pbName = strdup(cp -> problemName ().c_str ());
465 char *f_name_pos = strrchr(pbName,
'/');
466 if(f_name_pos != NULL) {
467 strcpy(shortName, &(f_name_pos[1]));
470 strcpy(shortName, pbName);
474 fprintf(f_res,
"%20s ", shortName);
475 if((cbcLb > 1e20) || (cbcLb < -1e20)) {
476 fprintf(f_res,
"%10.4g", cbcLb);
479 fprintf(f_res,
"%10.4f", cbcLb);
482 fprintf(f_res,
" %10.4f", printObj);
485 fprintf(f_res,
" *");
488 CoinCpuTime () - time_start);
497 couenne.options () -> GetNumericValue (
"couenne_check", global_opt,
"couenne.");
500 ub =
infeasible ? COIN_DBL_MAX : bb. model (). getObjValue (),
501 lb =
infeasible ? -COIN_DBL_MAX : bb. model (). getBestPossibleObjValue ();
503 if (cp -> getRecordBestSol () &&
504 cp -> getRecordBestSol () -> getHasSol () &&
505 (ub > cp -> getRecordBestSol () -> getVal ()))
506 ub = cp -> getRecordBestSol () -> getVal ();
513 *gapstr =
new char [40],
514 *lbstr =
new char [40],
515 *ubstr =
new char [40];
521 sprintf (lbstr,
"%10g", lb);
522 sprintf (ubstr,
"%10g", ub);
524 sprintf (gapstr,
"--");
527 sprintf (gapstr,
"%.2f%%", fabs (100. * (ub - lb) / (1. + fabs (lb))));
531 jnlst -> Printf (J_ERROR,
J_COUENNE,
"\n\
532 Linearization cuts added at root node: %8d\n\
533 Linearization cuts added in total: %8d (separation time: %gs)\n",
536 else jnlst -> Printf (J_ERROR,
J_COUENNE,
"Problem infeasible\n");
539 Total solve time: %8gs (%gs in branch-and-bound)\n\
541 Upper bound: %s (gap: %s)\n\
542 Branch-and-bound nodes: %8d\n",
543 CoinCpuTime () - time_start,
544 cg ? (CoinCpuTime () - CoinMax (time_start, cg -> rootTime ())) : CoinCpuTime () - time_start,
545 ((lb <= -8.9999e12) ||
561 double opt =
infeasible ? -COIN_DBL_MAX : bb.
model (). getBestPossibleObjValue ();
563 printf (
"Global Optimum Test on %-40s %s\n",
564 cp ? cp -> problemName ().c_str () :
"unknown",
565 (fabs (opt - global_opt) /
567 (
const char *)
"OK" : (
const char *)
"FAILED");
573 if (couenne.displayStats ()) {
575 if (cg && !cp) printf (
"Warning, could not get pointer to problem\n");
577 printf (
"Stats: %-15s %4d [var] %4d [int] %4d [con] %4d [aux] "
578 "%6d [root] %8d [tot] %6g [sep] %8g [time] %8g [bb] "
580 "%20e [lower] %20e [upper] %7d [nodes] %.0g [sg] %d [sgc]\n",
582 "%20e [lower] %20e [upper] %7d [nodes]\n",
584 cp ? cp -> problemName (). c_str () :
"unknown",
585 cp ? cp -> nOrigVars () : -1,
586 cp ? cp -> nOrigIntVars () : -1,
587 cp ? cp -> nOrigCons () : -1,
588 cp ? (cp -> nVars () -
589 cp -> nOrigVars ()) : -1,
591 CoinCpuTime () - time_start,
592 cg ? (CoinCpuTime () - cg -> rootTime ()) : CoinCpuTime (),
616 std::cerr<<E.className()<<
"::"<<E.methodName()
618 <<E.message()<<std::endl;
620 catch (CoinError &E) {
621 std::cerr<<E.className()<<
"::"<<E.methodName()
623 <<E.message()<<std::endl;
625 catch (Ipopt::OPTION_INVALID &E)
627 std::cerr<<
"Ipopt exception : "<<E.Message()<<std::endl;
Cut Generator for linear convexifications.
int nVars() const
Total number of variables.
int getCardModSol() const
int main(int argc, char *argv[])
void writeDiffFiles(const std::string prefix=std::string()) const
write files with differences between input model and this one
bool checkNLP2(const double *solution, const double obj, const bool careAboutObj, const bool stopAtFirstViol, const bool checkAll, const double precision) const
Return true if either solution or recomputed_solution obtained using getAuxs() from the original vari...
static int nSGcomputations
Error class to throw exceptions from OsiTMINLPInterface.
CouenneRecordBestSol * getRecordBestSol() const
returns recorded best solution
static void signal_handler(int whichSignal)
Class for MINLP problems with symbolic information.
void printError(std::ostream &os)
Print error message.
double getModSolVal() const
expression clone (points to another expression)
#define PRINTED_PRECISION
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
exprVar * Var(int i) const
Return pointer to i-th variable.
double getModSolMaxViol() const
static const int infeasible
We will throw this error when a problem is not solved.
double getFeasTol()
returns feasibility tolerance
int numNodes() const
return the total number of nodes explored.
bool checkNLP(const double *solution, double &obj, bool recompute=false) const
Check if solution is MINLP feasible.
The in-memory representation of the variables element.
const Ipopt::EJournalCategory J_COUENNE(Ipopt::J_USER8)
double * getModSol(const int expectedCard)
const CbcModel & model() const
Get cbc model used to solve.