OSCouenneSolver.cpp
Go to the documentation of this file.
1 /* $Id: OSCouenneSolver.cpp 5284 2017-12-08 13:52:50Z stefan $ */
17 #include <iostream>
18 
19 
20 //OS stuff
21 #include "OSDataStructures.h"
22 #include "OSParameters.h"
23 #include "OSMathUtil.h"
24 #include "OSOutput.h"
25 #include "OSCouenneSolver.h"
26 #include "BonBonminSetup.hpp"
27 //end OS stuff
28 
29 
30 // Couenne stuff
31 
32 #include "CouenneConfig.h"
33 #include "CouenneTypes.hpp"
34 #include "CouenneJournalist.hpp"
35 #include "CouenneExprClone.hpp"
36 #include "CouenneExprGroup.hpp"
37 #include "CouenneExprAbs.hpp"
38 #include "CouenneExprConst.hpp"
39 #include "CouenneExprCos.hpp"
40 #include "CouenneExprDiv.hpp"
41 #include "CouenneExprExp.hpp"
42 #include "CouenneExprInv.hpp"
43 #include "CouenneExprLog.hpp"
44 #include "CouenneExprMax.hpp"
45 #include "CouenneExprMin.hpp"
46 #include "CouenneExprMul.hpp"
47 #include "CouenneExprOpp.hpp"
48 #include "CouenneExprPow.hpp"
49 #include "CouenneExprSin.hpp"
50 #include "CouenneExprSub.hpp"
51 #include "CouenneExprSum.hpp"
52 #include "CouenneExprVar.hpp"
53 using namespace Couenne;
54 // end Couenne stuff
55 
56 
57 //Bonmin stuff
58 
60 #include "BonIpoptSolver.hpp"
61 
62 
63 #include "CoinTime.hpp"
64 #include "BonminConfig.h"
65 #include "BonCouenneInterface.hpp"
66 
67 
68 #include "BonCouenneSetup.hpp"
69 
70 
71 #ifdef COIN_HAS_FILTERSQP
72 #include "BonFilterSolver.hpp"
73 #endif
74 
75 #include "CbcCutGenerator.hpp"
76 #include "CouenneProblem.hpp"
77 #include "CouenneCutGenerator.hpp"
78 #include "CouenneBab.hpp"
79 
80 #include <cstddef>
81 #include <cstdlib>
82 #include <cctype>
83 #include <cassert>
84 #include <stack>
85 #include <string>
86 #include <iostream>
87 
88 
89 
90 using namespace Bonmin;
91 using namespace Couenne;
92 using std::endl;
93 using std::ostringstream;
94 
95 
97 {
98  using namespace Ipopt;
99  osrlwriter = new OSrLWriter();
100  osresult = new OSResult();
101  m_osilreader = NULL;
102  m_osolreader = NULL;
103  couenneErrorMsg = "";
104  couenne = NULL;
105  con_body = NULL;
106  obj_body = NULL;
107 }
108 
110 {
111 #ifndef NDEBUG
112  osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "inside CouenneSolver destructor\n");
113 #endif
114 
115  if(con_body != NULL)
116  {
117  //delete con_body;
118  }
119  if(obj_body != NULL)
120  {
121  //delete obj_body;
122  }
123  if(m_osilreader != NULL)
124  {
125  delete m_osilreader;
126  }
127  m_osilreader = NULL;
128  if(m_osolreader != NULL) delete m_osolreader;
129  m_osolreader = NULL;
130  delete osresult;
131  osresult = NULL;
132  delete osrlwriter;
133  osrlwriter = NULL;
134 #ifndef NDEBUG
135  osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_debug, "leaving CouenneSolver destructor\n");
136 #endif
137 
138 }
139 
140 
142 {
143  // Much of the following is taken from Stefan Vigerske
144  try
145  {
146  this->bCallbuildSolverInstance = true;
147  // do some initialization
148 
149  int i, j;
150  std::ostringstream outStr;
151 
152  if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
153  if(osinstance == NULL)
154  {
155  m_osilreader = new OSiLReader();
156  osinstance = m_osilreader->readOSiL( osil);
157  }
158 
160  //Ipopt::Journalist* jnlst = new Ipopt::Journalist();
161  //jnlst->AddFileJournal("console", "stdout", J_STRONGWARNING);
162  //couenne = new CouenneProblem(NULL, NULL, jnlst);
163  couenne = new CouenneProblem(NULL, NULL, NULL);
164  int n_allvars = osinstance->getVariableNumber();
165  if( n_allvars < 0 )throw ErrorClass("Couenne solver Cannot have a negatiave number of Variables");
166 #ifndef NDEBUG
167  outStr.str("");
168  outStr.clear();
169  outStr << "NUMBER OF VARIABLES = " << n_allvars << std::endl;
171 #endif
172  if(n_allvars > 0)
173  {
174  // create room for problem's variables and bounds
175  CouNumber *x_ = (CouNumber *) malloc ((n_allvars) * sizeof (CouNumber));
176  CouNumber *lb = NULL, *ub = NULL;
177 
178  // now get variable upper and lower bounds
181 
182  //declare the variable types
183  char *varType;
184  varType = osinstance->getVariableTypes();
185  for (i = 0; i < n_allvars; ++i)
186  {
187  if( (varType[i] == 'B') || (varType[i]) == 'I' )
188  {
189  couenne->addVariable(true, couenne->domain() );
190  }
191  else
192  {
193  couenne->addVariable(false, couenne->domain() );
194  }
195 
196  x_[i] = 0.;
197  }
198 
199  couenne->domain()->push(n_allvars, x_, lb, ub);
200  free(x_);
201  }
202 
203  // now for the objective function -- assume just one for now
204  //just worry about linear coefficients
205 
206  if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Couenne NEEDS AN OBJECTIVE FUNCTION");
207 
208  // Can't handle multiobjective problems properly --- especially nonlinear ones
209  if (osinstance->getObjectiveNumber() > 1)
210  throw ErrorClass("Solver cannot handle multiple objectives --- please delete all but one");
211 
212  //if(n_allvars > 0){
214  int nterms = sv->number;
215  exprGroup::lincoeff lin( nterms);
216  for ( i = 0; i < nterms; ++i)
217  {
218  lin[i].first = couenne->Var( sv->indexes[ i] );
219  if( osinstance->getObjectiveMaxOrMins()[0] == "min")
220  {
221  lin[i].second = sv->values[ i];
222  }
223  else
224  {
225  lin[i].second = -sv->values[ i];
226  }
227  }
228 
229 
231  if (exptree != NULL)
232  {
233  expression** nl = new expression*[1];
234  if( osinstance->getObjectiveMaxOrMins()[0] == "min")
235  {
236  nl[0] = createCouenneExpression( exptree->m_treeRoot );
237  }
238  else
239  {
240  nl[ 0] = new exprOpp(createCouenneExpression( exptree->m_treeRoot) );
241 
242  }
243  obj_body = new exprGroup(osinstance->getObjectiveConstants()[0], lin, nl, 1);
244  }
245  else
246  {
247  obj_body = new exprGroup(osinstance->getObjectiveConstants()[0], lin, NULL, 0);
248  }
249 
250  couenne->addObjective(obj_body, "min");
251 
252  // get the constraints in row format
253 
255 
256  int nconss = osinstance->getConstraintNumber();
257 
258  int row_nonz = 0;
259  int kount = 0;
260  double *rowlb = osinstance->getConstraintLowerBounds();
261  double *rowub = osinstance->getConstraintUpperBounds();
262 
263  for (i = 0; i < nconss; ++i)
264  {
265  row_nonz = 0;
266  if( sm) row_nonz = sm->starts[ i +1] - sm->starts[ i];
267  exprGroup::lincoeff con_lin( row_nonz);
268  for (j = 0; j < row_nonz; ++j)
269  {
270  con_lin[j].first = couenne->Var( sm->indexes[ kount] );
271  con_lin[j].second = sm->values[ kount];
272  kount++;
273  }
275  if (exptree != NULL)
276  {
277  expression** nl = new expression*[1];
278  nl[0] = createCouenneExpression(exptree->m_treeRoot);
279  con_body = new exprGroup(0., con_lin, nl, 1);
280  }
281  else
282  {
283  con_body = new exprGroup(0., con_lin, NULL, 0);
284  }
285 
286  if (rowlb[ i] == rowub[ i])
287  {
288  couenne->addEQConstraint(con_body, new exprConst( rowub[ i] ));
289  }
290  else if (rowlb[ i] == -OSDBL_MAX)
291  {
292  assert(rowub[ i] != -OSDBL_MAX);
293  couenne->addLEConstraint(con_body, new exprConst( rowub[ i] ));
294  }
295  else if (rowub[ i] == OSDBL_MAX)
296  {
297  assert(rowlb[ i] != OSDBL_MAX);
298  couenne->addGEConstraint(con_body, new exprConst( rowlb[ i] ));
299  }
300  else
301  couenne->addRNGConstraint(con_body, new exprConst( rowlb[ i]), new
302  exprConst( rowub[ i] ));
303  }
304  }
305  catch(const ErrorClass& eclass)
306  {
307  osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_error, "THERE IS AN ERROR\n");
309  osresult->setGeneralStatusType( "error");
310  osrl = osrlwriter->writeOSrL( osresult);
311  throw ErrorClass( osrl) ;
312  }
313 }//end buildSolverInstance()
314 
315 
317 {
318  unsigned int i;
319  std::ostringstream outStr;
320 
321  switch (node->inodeInt)
322  {
323  case OS_PLUS :
324  return new exprSum(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
325  case OS_SUM :
326  switch ( node->inumberOfChildren )
327  {
328  case 0:
329  return new exprConst(0.);
330  case 1:
331  return createCouenneExpression(node->m_mChildren[0]);
332  default:
333  expression** sumargs = new expression*[node->inumberOfChildren];
334  for(i = 0; i< node->inumberOfChildren; i++)
335  sumargs[i] = createCouenneExpression(node->m_mChildren[i]);
336  return new exprSum(sumargs, node->inumberOfChildren);
337  }
338  case OS_MINUS :
339  return new exprSub(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
340  case OS_NEGATE :
341  return new exprOpp(createCouenneExpression(node->m_mChildren[0]));
342  case OS_TIMES :
343  return new exprMul(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
344  case OS_DIVIDE :
345  // couenne does not like expressions of the form exp1/exp2 with exp1 a constant, so we write them as exp1 * 1/exp2
346  if (node->m_mChildren[0]->inodeInt == OS_NUMBER)
347  return new exprMul(createCouenneExpression(node->m_mChildren[0]), new exprInv(createCouenneExpression(node->m_mChildren[1])));
348  else
349  return new exprDiv(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
350  case OS_POWER :
351  // couenne does not like expressions of the form exp1 ^ exp2 with exp2 not a constant, so we write them as exp(log(exp1)*exp2)
352  if (node->m_mChildren[1]->inodeInt != OS_NUMBER)
353  return new exprExp(new exprMul(new exprLog(createCouenneExpression(node->m_mChildren[0])), createCouenneExpression(node->m_mChildren[1])));
354  else
355  return new exprPow(createCouenneExpression(node->m_mChildren[0]), createCouenneExpression(node->m_mChildren[1]));
356  case OS_PRODUCT:
357  switch ( node->inumberOfChildren )
358  {
359  case 0:
360  return new exprConst(1.);
361  case 1:
362  return createCouenneExpression(node->m_mChildren[0]);
363  default:
364  expression** args = new expression*[node->inumberOfChildren];
365  for( i = 0; i < node->inumberOfChildren; i++)
366  args[i] = createCouenneExpression(node->m_mChildren[i]);
367  expression* base = new exprMul(args, node->inumberOfChildren);
368  return base;
369  }
370  case OS_ABS :
371  return new exprAbs(createCouenneExpression(node->m_mChildren[0]));
372  case OS_SQUARE :
373  return new exprPow(createCouenneExpression(node->m_mChildren[0]), new exprConst(2.));
374  case OS_SQRT :
375  return new exprPow(createCouenneExpression(node->m_mChildren[0]), new exprConst(0.5));
376  case OS_LN :
377  return new exprLog(createCouenneExpression(node->m_mChildren[0]));
378  case OS_EXP :
379  return new exprExp(createCouenneExpression(node->m_mChildren[0]));
380  case OS_SIN :
381  return new exprSin(createCouenneExpression(node->m_mChildren[0]));
382  case OS_COS :
383  return new exprCos(createCouenneExpression(node->m_mChildren[0]));
384  case OS_MIN :
385  switch (node->inumberOfChildren)
386  {
387  case 0:
388  return new exprConst(0.);
389  case 1:
390  return createCouenneExpression(node->m_mChildren[0]);
391  default:
392  expression** args = new expression*[node->inumberOfChildren];
393  for( i = 0; i <node->inumberOfChildren; i++)
394  args[i] = createCouenneExpression(node->m_mChildren[i]);
395  expression* base = new exprMin(args, node->inumberOfChildren);
396  return base;
397  }
398  case OS_MAX :
399  switch (node->inumberOfChildren)
400  {
401  case 0:
402  return new exprConst(0.);
403  case 1:
404  return createCouenneExpression(node->m_mChildren[0]);
405  default:
406  expression** args = new expression*[node->inumberOfChildren];
407  for(i = 0; i < node->inumberOfChildren; i++)
408  args[i] = createCouenneExpression(node->m_mChildren[i]);
409  expression* base = new exprMax(args, node->inumberOfChildren);
410  return base;
411  }
412  case OS_NUMBER :
413  return new exprConst(((OSnLNodeNumber*)node)->value);
414  case OS_PI :
415  assert(false);
416  //TODO
417 // return new exprConst(PI);
418  case OS_VARIABLE :
419  {
420  OSnLNodeVariable* varnode = (OSnLNodeVariable*)node;
421  if (varnode->coef == 0.)
422  return new exprConst(0.);
423  if (varnode->coef == 1.)
424  return new exprClone(couenne->Variables()[varnode->idx]);
425  if (varnode->coef == -1.)
426  return new exprOpp(new exprClone(couenne->Variables()[varnode->idx]));
427  return new exprMul(new exprConst(varnode->coef), new exprClone(couenne->Variables()[varnode->idx]));
428  }
429  default:
430  outStr.str("");
431  outStr.clear();
432  outStr << node->getTokenName() << " NOT IMPLEMENTED!!" << endl;
434  break;
435  }
436 
437  return NULL;
438 }
439 
440 
442 {
443  std::ostringstream outStr;
444 
445  try
446  {
447  char *pEnd;
448  bSetSolverOptions = true;
449  couenneSetup.initializeOptionsAndJournalist();
450  //turn off a lot of output -- this can be overridden by using OSOptions
451  couenneSetup.options()->SetIntegerValue("bonmin.bb_log_level", 0);
452  couenneSetup.options()->SetIntegerValue("bonmin.nlp_log_level", 0 );
453  if(osoption == NULL && osol.length() > 0)
454  {
455  m_osolreader = new OSoLReader();
456  osoption = m_osolreader->readOSoL( osol);
457  }
458 
459  if(osoption != NULL && osoption->getNumberOfSolverOptions() > 0 )
460  {
461  int i;
462  std::vector<SolverOption*> optionsVector;
463  optionsVector = osoption->getSolverOptions( "couenne",true);
464  int num_bonmin_options = optionsVector.size();
465  std::string optionName;
466 
467  for(i = 0; i < num_bonmin_options; i++)
468  {
469  if(optionsVector[ i]->category == "ipopt")
470  {
471  optionName = optionsVector[ i]->name;
472  }
473  else
474  {
475  if(optionsVector[ i]->category == "bonmin" )
476  {
477  optionName = "bonmin."+optionsVector[ i]->name;
478  }
479  else
480  {
481  optionName = "couenne."+optionsVector[ i]->name;
482  }
483  }
484 
485  outStr.str("");
486  outStr.clear();
487  outStr << "found option " << optionName << " of type " << optionsVector[ i]->type << std::endl;
489 
490  if(optionsVector[ i]->type == "numeric" )
491  {
492  couenneSetup.options()->SetNumericValue(optionName, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
493  }
494  else if(optionsVector[ i]->type == "integer" )
495  {
496  couenneSetup.options()->SetIntegerValue(optionName, atoi( optionsVector[ i]->value.c_str() ) );
497  }
498  else if(optionsVector[ i]->type == "string" )
499  {
500  couenneSetup.options()->SetStringValue(optionName, optionsVector[ i]->value );
501  }
502  }
503  }
504  }
505 
506  catch(const ErrorClass& eclass)
507  {
508  osoutput->OSPrint(ENUM_OUTPUT_AREA_OSSolverInterfaces, ENUM_OUTPUT_LEVEL_error, "THERE IS AN ERROR\n");
510  osresult->setGeneralStatusType( "error");
511  osrl = osrlwriter->writeOSrL( osresult);
512  throw ErrorClass( osrl) ;
513  }
514 
515 }//end setSolverOptions()
516 
517 
518 using namespace Ipopt;
519 
520 
522 {
523 #define PRINTED_PRECISION 1e-5
524  const int infeasible = 1;
525  //double time_start = CoinCpuTime();
526  if( this->bCallbuildSolverInstance == false) buildSolverInstance();
527  if(this->bSetSolverOptions == false) setSolverOptions() ;
528  try
529  {
530 
531  //couenne->print();
532 
533  char **argv = NULL;
534 
535  bb.setProblem(couenne);
536 
537  //using namespace Ipopt;
538 
539  if(osoption == NULL && osol.length() > 0)
540  {
541  m_osolreader = new OSoLReader();
542  osoption = m_osolreader->readOSoL( osol);
543  }
544 
545 
546  tminlp = new BonminProblem( osinstance, osoption);
547 
548  CouenneInterface *ci = NULL;
549 
550  ci = new CouenneInterface();
551 
552  ci->initialize (couenneSetup.roptions(),//GetRawPtr(roptions),
553  couenneSetup.options(),//GetRawPtr( options),
554  couenneSetup.journalist(),//GetRawPtr(jnlst),
555  GetRawPtr( tminlp) );
556 
557  app_ = new Bonmin::IpoptSolver(couenneSetup.roptions(),//GetRawPtr(roptions),
558  couenneSetup.options(),//GetRawPtr( options),
559  couenneSetup.journalist()//GetRawPtr(jnlst),
560  );
561 
562  ci->setModel( GetRawPtr( tminlp) );
563  ci->setSolver( GetRawPtr( app_) );
564 
565  // initialize causes lots of memory leaks
566  bool setupInit = false;
567  setupInit = couenneSetup.InitializeCouenne(argv, couenne, NULL, ci);
568 
569 
570  if(setupInit == false)
571  {
572  std::string solutionDescription = "";
573  std::string message = "Couenne solver finishes to the end.";
574  int solIdx = 0;
575  if(osresult->setServiceName( "Couenne solver service") != true)
576  throw ErrorClass("OSResult error: setServiceName");
578  throw ErrorClass("OSResult error: setInstanceName");
580  throw ErrorClass("OSResult error: setVariableNumer");
581  if(osresult->setObjectiveNumber( 1) != true)
582  throw ErrorClass("OSResult error: setObjectiveNumber");
584  throw ErrorClass("OSResult error: setConstraintNumber");
585  if(osresult->setSolutionNumber( 1) != true)
586  throw ErrorClass("OSResult error: setSolutionNumer");
587  if(osresult->setGeneralMessage( message) != true)
588  throw ErrorClass("OSResult error: setGeneralMessage");
589  solutionDescription = "COUENNE INITIALIZE PROBLEM: \n There was a problem with Couenne Initialize: \n the problem could be infeasible \n there may be zero decision variables";
590  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
591  osresult->setGeneralStatusType("normal");
592  osrl = osrlwriter->writeOSrL( osresult);
593  return;
594 
595  }
596 
598  // see if we have an unbounded solution
599  // if we are not infeasible and not optimal and have no integer variables we are probably unbounded
600  if(( ci->isProvenPrimalInfeasible() == false) && (ci -> isProvenOptimal () == false)
602  {
603  std::string solutionDescription = "";
604  std::string message = "Success";
605  int solIdx = 0;
606  if(osresult->setServiceName( "Couenne solver service") != true)
607  throw ErrorClass("OSResult error: setServiceName");
609  throw ErrorClass("OSResult error: setInstanceName");
611  throw ErrorClass("OSResult error: setVariableNumer");
612  if(osresult->setObjectiveNumber( 1) != true)
613  throw ErrorClass("OSResult error: setObjectiveNumber");
615  throw ErrorClass("OSResult error: setConstraintNumber");
616  if(osresult->setSolutionNumber( 1) != true)
617  throw ErrorClass("OSResult error: setSolutionNumer");
618  if(osresult->setGeneralMessage( message) != true)
619  throw ErrorClass("OSResult error: setGeneralMessage");
620  solutionDescription = "CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
621  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
622  osresult->setGeneralStatusType("normal");
623  osrl = osrlwriter->writeOSrL( osresult);
624  return;
625  }
626 
627  bb ( couenneSetup); // do branch and bound
628 
629  CouenneCutGenerator *cg = NULL;
630 
631  if (bb.model (). cutGenerators ())
632  cg = dynamic_cast <CouenneCutGenerator *>
633  (bb.model (). cutGenerators () [0] -> generator ());
634 
635 
636  double global_opt;
637  couenneSetup.options () -> GetNumericValue ("couenne_check", global_opt, "couenne.");
638  double timeLimit = 0;
639  couenneSetup.options () -> GetNumericValue ("time_limit", timeLimit, "couenne.");
640 
641  // now put information in OSResult object
642  status = tminlp->status;
643  writeResult();
644  } //end try
645 
646  catch(const ErrorClass& eclass)
647  {
649  osresult->setGeneralStatusType( "error");
650  osrl = osrlwriter->writeOSrL( osresult);
651  throw ErrorClass( osrl) ;
652  }
653 
654  // Pietro's catch
655 
656  catch(TNLPSolver::UnsolvedError *E)
657  {
658  E->writeDiffFiles();
659  E->printError(std::cerr);
660  //There has been a failure to solve a problem with Ipopt.
661  //And we will output file with information on what has been changed in the problem to make it fail.
662  //Now depending on what algorithm has been called (B-BB or other) the failed problem may be at different place.
663  // const OsiSolverInterface &si1 = (algo > 0) ? nlpSolver : *model.solver();
664 
665  osresult->setGeneralMessage("Ipopt has failed to solve a problem");
666  osresult->setGeneralStatusType( "error");
667  osrl = osrlwriter->writeOSrL( osresult);
668  throw ErrorClass( osrl) ;
669  }
670 
672  {
673  ostringstream outStr;
674  outStr << E.className() << "::"<< E.methodName() << std::endl << E.message() << std::endl;
675 
676  osresult->setGeneralMessage(outStr.str());
677  osresult->setGeneralStatusType( "error");
678  osrl = osrlwriter->writeOSrL( osresult);
679  throw ErrorClass( osrl) ;
680  }
681 
682  catch(CoinError &E)
683  {
684  ostringstream outStr;
685  outStr << E.className() << "::"<< E.methodName() << std::endl << E.message() << std::endl;
686 
687  osresult->setGeneralMessage(outStr.str());
688  osresult->setGeneralStatusType( "error");
689  osrl = osrlwriter->writeOSrL( osresult);
690  throw ErrorClass( osrl);
691  }
692 
693  catch (Ipopt::OPTION_INVALID &E)
694  {
695  ostringstream outStr;
696  outStr << "Ipopt exception : " << E.Message() << std::endl;
697 
698  osresult->setGeneralMessage(outStr.str());
699  osresult->setGeneralStatusType( "error");
700  osrl = osrlwriter->writeOSrL( osresult);
701  throw ErrorClass( osrl);
702  }
703  catch (int generic_error)
704  {
705  if (generic_error == infeasible)
706  {
707  osresult->setGeneralMessage("generic error: problem infeasible");
708  osresult->setGeneralStatusType("error");
709  osrl = osrlwriter->writeOSrL( osresult);
710  throw ErrorClass( osrl);
711  }
712  }
713 
714 }//end solve()
715 
716 
718 {
719  double *x = NULL;
720  double *z = NULL;
721  int i = 0;
722  int solIdx = 0;
723  std::string solutionDescription = "";
724  std::string message = "Couenne solver finishes to the end.";
725 
726 
727  try
728  {
729  if(osinstance->getVariableNumber() > 0) x = new double[osinstance->getVariableNumber() ];
730  z = new double[1];
731 
732  // resultHeader information
733  if(osresult->setSolverInvoked( "COIN-OR Couenne") != true)
734  throw ErrorClass("OSResult error: setSolverInvoked");
735  if(osresult->setServiceName( OSgetVersionInfo()) != true)
736  throw ErrorClass("OSResult error: setServiceName");
738  throw ErrorClass("OSResult error: setInstanceName");
739 
740  // set basic problem parameters
742  throw ErrorClass("OSResult error: setVariableNumer");
743  if(osresult->setObjectiveNumber( 1) != true)
744  throw ErrorClass("OSResult error: setObjectiveNumber");
746  throw ErrorClass("OSResult error: setConstraintNumber");
747  if(osresult->setSolutionNumber( 1) != true)
748  throw ErrorClass("OSResult error: setSolutionNumer");
749  if(osresult->setGeneralMessage( message) != true)
750  throw ErrorClass("OSResult error: setGeneralMessage");
751 
752  switch( status)
753  {
754  case TMINLP::SUCCESS:
755  solutionDescription = "SUCCESS[COUENNE]: Algorithm terminated normally at a locally optimal point, satisfying the convergence tolerances.";
756  osresult->setSolutionStatus(solIdx, "locallyOptimal", solutionDescription);
757 
758  if(osinstance->getObjectiveNumber() > 0)
759  {
760  /* Retrieve the solution */
761  *(z + 0) = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.bestSolution()), true)[ 0];
762  // okay if equal to 9999000000000 we are probably unbounded
763  if(fabs(*(z + 0)) == 9.999e+12)
764  {
765  solutionDescription = "CONTINUOUS_UNBOUNDED [COUENNE]: Continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
766  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
767  break;
768  }
769  osresult->setObjectiveValuesDense(solIdx, z);
770  }
771 
772 
773  if(osinstance->getVariableNumber() > 0)
774  {
775  for(i=0; i < osinstance->getVariableNumber(); i++)
776  {
777  *(x + i) = bb.bestSolution()[i];
778  }
780  }
781 
782  break;
783 
784  case TMINLP::LIMIT_EXCEEDED:
785  solutionDescription = "LIMIT_EXCEEDED[COUENNE]: A resource limit was exceeded, we provide the current solution.";
786  osresult->setSolutionStatus(solIdx, "other", solutionDescription);
787  /* Retrieve the solution */
788  if(osinstance->getObjectiveNumber() > 0)
789  {
790  *(z + 0) = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(bb.model().getColSolution()), true)[ 0];
791  osresult->setObjectiveValuesDense(solIdx, z);
792  }
793 
794  if(osinstance->getVariableNumber() > 0)
795  {
796  for(i=0; i < osinstance->getVariableNumber(); i++)
797  {
798  *(x + i) = bb.model().getColSolution()[i];
799  }
801  }
802  break;
803 
804  case TMINLP::MINLP_ERROR:
805  solutionDescription = "MINLP_ERROR [COUENNE]: Algorithm stopped with unspecified error.";
806  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
807 
808  break;
809 
810  case TMINLP::CONTINUOUS_UNBOUNDED:
811  solutionDescription = "CONTINUOUS_UNBOUNDED [COUENNE]: The continuous relaxation is unbounded, the MINLP may or may not be unbounded.";
812  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
813 
814  break;
815 
816  case TMINLP::INFEASIBLE:
817  solutionDescription = "INFEASIBLE [COUENNE]: Problem may be infeasible.";
818  osresult->setSolutionStatus(solIdx, "infeasible", solutionDescription);
819  break;
820 
821  default:
822  solutionDescription = "OTHER[COUENNE]: other unknown solution status from Couenne solver";
823  osresult->setSolutionStatus(solIdx, "other", solutionDescription);
824  }//switch end
825 
826  osresult->setGeneralStatusType("normal");
827  osrl = osrlwriter->writeOSrL( osresult);
828  if(osinstance->getVariableNumber() > 0) delete[] x;
829  x = NULL;
830  delete[] z;
831  z = NULL;
832  }//end try
833 
834 
835  catch(const ErrorClass& eclass)
836  {
837  delete[] x;
838  x = NULL;
839  delete[] z;
840  z = NULL;
842  osresult->setGeneralStatusType( "error");
843  osrl = osrlwriter->writeOSrL( osresult);
844  throw ErrorClass( osrl) ;
845  }
846 
847 }// end writeResult()
848 
Cut Generator for linear convexifications.
double * getConstraintLowerBounds()
Get constraint lower bounds.
double * getVariableLowerBounds()
Get variable lower bounds.
double * getConstraintUpperBounds()
Get constraint upper bounds.
~CouenneSolver()
the IpoptSolver class destructor
class inverse:
double coef
coef is an option coefficient on the variable, the default value is 1.0
Definition: OSnLNode.h:1485
std::string OSgetVersionInfo()
double os_strtod(const char *s00, char **se)
Definition: OSdtoa.cpp:2541
int getNumberOfIntegerVariables()
getNumberOfIntegerVariables
void writeResult()
use this to write the solution information to an OSResult object
char * getVariableTypes()
Get variable initial values.
ScalarExpressionTree * getNonlinearExpressionTree(int rowIdx)
Get the expression tree for a given row index.
bool setSolutionStatus(int solIdx, std::string type, std::string description)
Set the [i]th optimization solution status, where i equals the given solution index.
bool setPrimalVariableValuesDense(int solIdx, double *x)
Set the [i]th optimization solution&#39;s primal variable values, where i equals the given solution index...
Definition: OSResult.cpp:5001
class Group, with constant, linear and nonlinear terms:
#define OS_MAX
Definition: OSParameters.h:44
const OSSmartPtr< OSOutput > osoutput
Definition: OSOutput.cpp:39
class cosine,
int getVariableNumber()
Get number of variables.
class for subtraction,
#define OS_COS
Definition: OSParameters.h:42
bool setServiceName(std::string serviceName)
Set service name.
#define OS_NUMBER
Definition: OSParameters.h:45
class opposite,
bool setVariableNumber(int variableNumber)
Set the variable number.
Definition: OSResult.cpp:4712
unsigned int inumberOfChildren
inumberOfChildren is the number of OSnLNode child elements If this number is not fixed, e.g., for a sum node, it is temporarily set to 0
Definition: OSnLNode.h:74
int idx
idx is the index of the variable
Definition: OSnLNode.h:1488
std::string errormsg
errormsg is the error that is causing the exception to be thrown
Definition: OSErrorClass.h:42
virtual void solve()
solve results in an instance being read into the Couenne data structrues and optimized ...
std::vector< SolverOption * > getSolverOptions(std::string solver_name)
Get the options associated with a given solver.
Definition: OSOption.cpp:4508
SparseVector ** getObjectiveCoefficients()
Get objective coefficients.
#define OS_PI
Definition: OSParameters.h:46
Power of an expression (binary operator), with constant.
The Result Class.
Definition: OSResult.h:2548
OSOption * osoption
bool setSolverInvoked(std::string solverInvoked)
Set solver invoked.
Definition: OSResult.cpp:4155
void writeDiffFiles(const std::string prefix=std::string()) const
write files with differences between input model and this one
Take an OSResult object and write a string that validates against OSrL.
Definition: OSrLWriter.h:30
int getObjectiveNumber()
Get number of objectives.
bool setObjectiveNumber(int objectiveNumber)
Set the objective number.
Definition: OSResult.cpp:4721
bool setInstanceName(std::string instanceName)
Set instance name.
Couenne::expression * createCouenneExpression(OSnLNode *node)
#define OS_MINUS
Definition: OSParameters.h:29
int inodeInt
inodeInt is the unique integer assigned to the OSnLNode or OSnLMNode in OSParameters.h.
Definition: OSnLNode.h:62
constant-type operator
static char * j
Definition: OSdtoa.cpp:3622
class for divisions,
int * indexes
indexes holds an integer array of rowIdx (or colIdx) elements in coefMatrix (AMatrix).
Definition: OSGeneral.h:258
virtual bool isProvenPrimalInfeasible() const
Is primal infeasiblity proven?
bool setSolutionNumber(int number)
set the number of solutions.
Definition: OSResult.cpp:4740
The OSnLNodeNumber Class.
Definition: OSnLNode.h:1262
Used to hold part of the instance in memory.
void fint fint fint real fint real real real real real real real real real * e
Error class to throw exceptions from OsiTMINLPInterface.
Used to read an OSiL string.
Definition: OSiLReader.h:37
virtual void setSolverOptions()
The implementation of the virtual functions.
a sparse matrix data structure
Definition: OSGeneral.h:223
#define OS_LN
Definition: OSParameters.h:38
void setSolver(Ipopt::SmartPtr< TNLPSolver > app)
Set the solver to be used by interface.
SparseMatrix * getLinearConstraintCoefficientsInRowMajor()
Get linear constraint coefficients in row major.
The OSnLNodeVariable Class.
Definition: OSnLNode.h:1478
#define OS_MIN
Definition: OSParameters.h:43
Class for MINLP problems with symbolic information.
void printError(std::ostream &os)
Print error message.
OSResult * osresult
#define OS_PLUS
Definition: OSParameters.h:27
#define OS_ABS
Definition: OSParameters.h:35
expression clone (points to another expression)
const double OSDBL_MAX
Definition: OSParameters.h:93
std::string * getObjectiveMaxOrMins()
Get objective maxOrMins.
#define OS_SQUARE
Definition: OSParameters.h:36
a sparse vector data structure
Definition: OSGeneral.h:122
OSnLNode ** m_mChildren
m_mChildren holds all the operands, that is, nodes that the current node operates on...
Definition: OSnLNode.h:84
bool setGeneralMessage(std::string message)
Set the general message.
double * values
values holds a double array of value elements in coefMatrix (AMatrix), which contains nonzero element...
Definition: OSGeneral.h:264
double * getObjectiveConstants()
Get objective constants.
#define OS_SIN
Definition: OSParameters.h:41
bool setGeneralStatusType(std::string type)
Set the general status type, which can be: success, error, warning.
OSnLNode * m_treeRoot
m_treeRoot holds the root node (of OSnLNode type) of the expression tree.
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:452
std::string getInstanceName()
Get instance name.
#define OS_SUM
Definition: OSParameters.h:28
static const int infeasible
Definition: Couenne.cpp:68
int number
number is the number of elements in the indexes and values arrays.
Definition: OSGeneral.h:154
void setModel(Ipopt::SmartPtr< TMINLP > tminlp)
Set the model to be solved by interface.
std::vector< std::pair< exprVar *, CouNumber > > lincoeff
double CouNumber
main number type in Couenne
int getConstraintNumber()
Get number of constraints.
bool setConstraintNumber(int constraintNumber)
Set the constraint number.
Definition: OSResult.cpp:4731
#define OS_POWER
Definition: OSParameters.h:33
int getNumberOfSolverOptions()
Get the number of solver options.
Definition: OSOption.cpp:2207
Used to read an OSoL string.
Definition: OSoLReader.h:37
#define OS_SQRT
Definition: OSParameters.h:37
#define OS_TIMES
Definition: OSParameters.h:31
class logarithm,
bool initForAlgDiff()
This should be called by nonlinear solvers using callback functions.
int * starts
starts holds an integer array of start elements in coefMatrix (AMatrix), which points to the start of...
Definition: OSGeneral.h:252
double * values
values holds a double array of nonzero values.
Definition: OSGeneral.h:164
double * calculateAllObjectiveFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the objective function values.
CouenneSolver()
the CouenneSolver class constructor
We will throw this error when a problem is not solved.
double * getVariableUpperBounds()
Get variable upper bounds.
bool setObjectiveValuesDense(int solIdx, double *objectiveValues)
Set the [i]th optimization solution&#39;s objective values, where i equals the given solution index...
Definition: OSResult.cpp:5824
int * indexes
indexes holds an integer array of indexes whose corresponding values are nonzero. ...
Definition: OSGeneral.h:159
#define OS_PRODUCT
Definition: OSParameters.h:34
Expression base class.
class for the exponential,
OSInstance * osinstance
The OSnLNode Class for nonlinear expressions.
Definition: OSnLNode.h:179
virtual std::string getTokenName()=0
void initialize(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions, Ipopt::SmartPtr< Ipopt::OptionsList > options, Ipopt::SmartPtr< Ipopt::Journalist > journalist, const std::string &prefix, Ipopt::SmartPtr< TMINLP > tminlp)
Facilitator to initialize interface.
#define OS_DIVIDE
Definition: OSParameters.h:32
virtual void buildSolverInstance()
buildSolverInstance is a virtual function – the actual solvers will implement their own buildSolverIn...
used for throwing exceptions.
Definition: OSErrorClass.h:31
#define OS_VARIABLE
Definition: OSParameters.h:48
#define OS_EXP
Definition: OSParameters.h:39
int getNumberOfBinaryVariables()
getNumberOfBinaryVariables
void fint fint fint real fint real * x
class for multiplications,
#define OS_NEGATE
Definition: OSParameters.h:30