BonOsiTMINLPInterface.cpp
Go to the documentation of this file.
1 // (C) Copyright International Business Machines Corporation and
2 // Carnegie Mellon University 2004, 2007
3 //
4 // All Rights Reserved.
5 // This code is published under the Eclipse Public License.
6 //
7 // Authors :
8 // Pierre Bonami, Carnegie Mellon University,
9 // Carl D. Laird, Carnegie Mellon University,
10 // Andreas Waechter, International Business Machines Corporation
11 //
12 // Date : 12/01/2004
13 
14 #include "BonminConfig.h"
15 
17 #include "BonTMINLP.hpp"
18 #include "BonTMINLP2TNLP.hpp"
19 #include "BonTNLP2FPNLP.hpp"
20 #include "BonTMINLP2OsiLP.hpp"
21 #include "BonTNLPSolver.hpp"
22 #include "CoinTime.hpp"
23 #include <climits>
24 #include <string>
25 #include <sstream>
26 #include "BonAuxInfos.hpp"
27 
28 #include "Ipopt/BonIpoptSolver.hpp"
30 #ifdef COIN_HAS_FILTERSQP
33 //#include "Filter/BonBqpdWarmStart.hpp"
34 #endif
35 
36 #include "OsiBranchingObject.hpp"
37 #include "OsiRowCutDebugger.hpp"
39 
40 //Macros to try and make messages definition less heavy
41 #include "BonMsgUtils.hpp"
42 
43 using namespace Ipopt;
44 
45 
46 extern bool BonminAbortAll;
47 namespace Bonmin {
49 static void
52 {
53  roptions->SetRegisteringCategory("NLP interface", RegisteredOptions::BonminCategory);
54  roptions->AddStringOption3("nlp_solver",
55  "Choice of the solver for local optima of continuous NLP's",
56  "Ipopt",
57  "Ipopt", "Interior Point OPTimizer (https://projects.coin-or.org/Ipopt)",
58  "filterSQP", "Sequential quadratic programming trust region "
59  "algorithm (http://www-unix.mcs.anl.gov/~leyffer/solvers.html)",
60  "all", "run all available solvers at each node",
61  "Note that option will work only if the specified solver has been installed. Ipopt will usually be installed with Bonmin by default. For FilterSQP please see http://www-unix.mcs.anl.gov/~leyffer/solvers.html on how to obtain it and https://projects.coin-or.org/Bonmin/wiki/HintTricks on how to configure Bonmin to use it.");
62  roptions->setOptionExtraInfo("nlp_solver",127);
63 
64  roptions->AddStringOption4("warm_start",
65  "Select the warm start method",
66  "none",
67  "none","No warm start, just start NLPs from optimal solution of the root relaxation",
68  "fake_basis", "builds fake basis, useful for cut management in Cbc (warm start is the same as in none)",
69  "optimum","Warm start with direct parent optimum",
70  "interior_point","Warm start with an interior point of direct parent",
71  "This will affect the function getWarmStart(), and as a consequence the warm starting in the various algorithms.");
72  roptions->setOptionExtraInfo("warm_start",8);
73 
74  roptions->SetRegisteringCategory("Output and Loglevel", RegisteredOptions::BonminCategory);
75 
76  roptions->AddBoundedIntegerOption("nlp_log_level",
77  "specify NLP solver interface log level (independent from ipopt print_level).",
78  0,2,1,
79  "Set the level of output of the OsiTMINLPInterface : "
80  "0 - none, 1 - normal, 2 - verbose"
81  );
82  roptions->setOptionExtraInfo("nlp_log_level",127);
83 
84  roptions->AddStringOption2("file_solution",
85  "Write a file bonmin.sol with the solution",
86  "no",
87  "yes","",
88  "no","","");
89  roptions->setOptionExtraInfo("file_solution",127);
90 
91  roptions->SetRegisteringCategory("NLP solution robustness", RegisteredOptions::BonminCategory);
92 
93  roptions->AddLowerBoundedNumberOption("max_random_point_radius",
94  "Set max value r for coordinate of a random point.",
95  0.,1,1e5,
96  "When picking a random point, coordinate i will be in the interval [min(max(l,-r),u-r), max(min(u,r),l+r)] "
97  "(where l is the lower bound for the variable and u is its upper bound)");
98  roptions->setOptionExtraInfo("max_random_point_radius",8);
99 
100  roptions->AddStringOption3("random_point_type","method to choose a random starting point",
101  "Jon",
102  "Jon", "Choose random point uniformly between the bounds",
103  "Andreas", "perturb the starting point of the problem within a prescribed interval",
104  "Claudia", "perturb the starting point using the perturbation radius suffix information",
105  "");
106  roptions->setOptionExtraInfo("random_point_type",8);
107 
108  roptions->AddLowerBoundedNumberOption("random_point_perturbation_interval",
109  "Amount by which starting point is perturbed when choosing to pick random point by perturbing starting point",
110  0.,true, 1.,
111  "");
112  roptions->setOptionExtraInfo("random_point_perturbation_interval",8);
113 
114 
115  roptions->AddLowerBoundedIntegerOption
116  ("num_iterations_suspect",
117  "Number of iterations over which a node is considered \"suspect\" (for debugging purposes only, see detailed documentation).",
118  -1,-1,
119  "When the number of iterations to solve a node is above this number, the subproblem at this"
120  " node is considered to be suspect and it will be written into a file (set to -1 to deactivate this).");
121  roptions->setOptionExtraInfo("num_iterations_suspect",127);
122 
123 
124 
125  roptions->AddLowerBoundedIntegerOption("num_retry_unsolved_random_point",
126  "Number $k$ of times that the algorithm will try to resolve an unsolved NLP with a random starting point "
127  "(we call unsolved an NLP for which Ipopt is not "
128  "able to guarantee optimality within the specified tolerances).",
129  0,0,
130  "When Ipopt fails to solve a continuous NLP sub-problem, if $k > 0$, the algorithm will "
131  "try again to solve the failed NLP with $k$ new randomly chosen starting points "
132  " or until the problem is solved with success.");
133  roptions->setOptionExtraInfo("num_retry_unsolved_random_point",127);
134 
135  roptions->AddLowerBoundedNumberOption("resolve_on_small_infeasibility",
136  "If a locally infeasible problem is infeasible by less than this, resolve it "
137  "with initial starting point.",
138  0.,false, 0.,
139  "It is set to 0 by default with Ipopt. "
140  "When using FilterSQP, Bonmin sets it to a small value.");
141  roptions->setOptionExtraInfo("resolve_on_small_infeasibility",8);
142 
143 
144  roptions->SetRegisteringCategory("Nonconvex problems", RegisteredOptions::BonminCategory);
145 
146 
147  roptions->AddLowerBoundedIntegerOption("num_resolve_at_root",
148  "Number $k$ of tries to resolve the root node with different starting points.",
149  0,0,
150  "The algorithm will solve the root node with $k$ random starting points"
151  " and will keep the best local optimum found.");
152  roptions->setOptionExtraInfo("num_resolve_at_root",8);
153 
154  roptions->AddLowerBoundedIntegerOption("num_resolve_at_node",
155  "Number $k$ of tries to resolve a node (other than the root) of the tree with different starting point.",
156  0,0,
157  "The algorithm will solve all the nodes with $k$ different random starting points "
158  "and will keep the best local optimum found.");
159  roptions->setOptionExtraInfo("num_resolve_at_node",8);
160 
161  roptions->AddLowerBoundedIntegerOption("num_resolve_at_infeasibles",
162  "Number $k$ of tries to resolve an infeasible node (other than the root) of the tree with different starting point.",
163  0,0,
164  "The algorithm will solve all the infeasible nodes with $k$ different random starting points "
165  "and will keep the best local optimum found.");
166  roptions->setOptionExtraInfo("num_resolve_at_infeasibles",8);
167 
168 
169  roptions->AddStringOption2("dynamic_def_cutoff_decr",
170  "Do you want to define the parameter cutoff_decr dynamically?",
171  "no",
172  "no", "",
173  "yes", "");
174  roptions->setOptionExtraInfo("dynamic_def_cutoff_decr",8);
175 
176  roptions->AddLowerBoundedNumberOption("coeff_var_threshold",
177  "Coefficient of variation threshold (for dynamic definition of cutoff_decr).",
178  0.0,
179  false,
180  0.1);
181  roptions->setOptionExtraInfo("coeff_var_threshold",8);
182 
183  roptions->AddNumberOption("first_perc_for_cutoff_decr",
184  "The percentage used when, the coeff of variance is smaller than the threshold, to compute the cutoff_decr dynamically.",
185  -0.02);
186  roptions->setOptionExtraInfo("first_perc_for_cutoff_decr",8);
187 
188  roptions->AddNumberOption("second_perc_for_cutoff_decr",
189  "The percentage used when, the coeff of variance is greater than the threshold, to compute the cutoff_decr dynamically.",
190  -0.05);
191  roptions->setOptionExtraInfo("second_perc_for_cutoff_decr",8);
192 
193  }
194 
195 static void register_OA_options
197 {
198  //
199 
200  roptions->SetRegisteringCategory("Outer Approximation strengthening", RegisteredOptions::UndocumentedCategory);
201  roptions->AddStringOption2("disjunctive_cut_type",
202  "Determine if and what kind of disjunctive cuts should be computed.",
203  "none",
204  "none", "No disjunctive cuts.",
205  "most-fractional", "If discrete variables present, compute disjunction for most-fractional variable");
206  roptions->setOptionExtraInfo("disjunctive_cut_type",119);
207 
208 
209 
210 
211  roptions->AddStringOption4("cut_strengthening_type",
212  "Determines if and what kind of cut strengthening should be performed.",
213  "none",
214  "none", "No strengthening of cuts.",
215  "sglobal", "Strengthen global cuts.",
216  "uglobal-slocal", "Unstrengthened global and strengthened local cuts",
217  "sglobal-slocal", "Strengthened global and strengthened local cuts",
218  "");
219  roptions->setOptionExtraInfo("cut_strengthening_type",119);
220 
221  roptions->SetRegisteringCategory("Outer Approximation cuts generation", RegisteredOptions::BonminCategory);
222 
223  roptions->AddStringOption2("oa_cuts_scope","Specify if OA cuts added are to be set globally or locally valid",
224  "global",
225  "local","Cuts are treated as locally valid",
226  "global", "Cuts are treated as globally valid",
227  "");
228  roptions->setOptionExtraInfo("oa_cuts_scope",119);
229 
230  roptions->AddStringOption2("add_only_violated_oa","Do we add all OA cuts or only the ones violated by current point?",
231  "no",
232  "no","Add all cuts",
233  "yes","Add only violated cuts","");
234  roptions->setOptionExtraInfo("add_only_violated_oa",119);
235 
236 
237  roptions->AddLowerBoundedNumberOption("tiny_element","Value for tiny element in OA cut",
238  -0.,0,1e-08,
239  "We will remove \"cleanly\" (by relaxing cut) an element lower"
240  " than this.");
241  roptions->setOptionExtraInfo("tiny_element",119);
242 
243  roptions->AddLowerBoundedNumberOption("very_tiny_element","Value for very tiny element in OA cut",
244  -0.,0,1e-17,
245  "Algorithm will take the risk of neglecting an element lower"
246  " than this.");
247  roptions->setOptionExtraInfo("very_tiny_element",119);
248 
249  roptions->AddLowerBoundedNumberOption("oa_rhs_relax","Value by which to relax OA cut",
250  -0.,0,1e-8,
251  "RHS of OA constraints will be relaxed by this amount times the absolute value of the initial rhs if it is >= 1 (otherwise by this amount)."
252  );
253  roptions->setOptionExtraInfo("oa_rhs_relax",119);
254 
255  roptions->SetRegisteringCategory("Output and Loglevel", RegisteredOptions::BonminCategory);
256 
257  roptions->AddLowerBoundedIntegerOption("oa_cuts_log_level",
258  "level of log when generating OA cuts.",
259  0, 0,
260  "0: outputs nothing,\n"
261  "1: when a cut is generated, its violation and index of row from which it originates,\n"
262  "2: always output violation of the cut.\n"
263  "3: output generated cuts incidence vectors.");
264  roptions->setOptionExtraInfo("oa_cuts_log_level",119);
265 
266 }
267 
268 
270 void
271 OsiTMINLPInterface::registerOptions
273 {
274  // We try to register the options - if those have been registered
275  // already, we catch the exception and don't need to do it again
276  try {
277  register_general_options(roptions);
278  register_OA_options(roptions);
279 #ifdef COIN_HAS_FILTERSQP
280  FilterSolver::RegisterOptions(roptions);
281 #endif
282  IpoptSolver::RegisterOptions(roptions);
283  }
284  catch(RegisteredOptions::OPTION_ALREADY_REGISTERED) {
285  // skipping
286  }
287 
288 
289 }
290 
292 void
293 OsiTMINLPInterface::setAppDefaultOptions(SmartPtr<OptionsList> Options)
294 {}
295 
296 OsiTMINLPInterface::Messages::Messages
297 ():CoinMessages((int)OSITMINLPINTERFACE_DUMMY_END)
298 {
299  strcpy(source_ ,"NLP");
300  ADD_MSG(SOLUTION_FOUND, std_m, 2,
301  "After %d tries found a solution of %g (previous best %g).");
302 
303  ADD_MSG(INFEASIBLE_SOLUTION_FOUND, std_m, 2,
304  "After %d tries found an solution of %g infeasible problem.");
305 
306  ADD_MSG(UNSOLVED_PROBLEM_FOUND, std_m, 2,
307  "After %d tries found an solution of %g unsolved problem.");
308  ADD_MSG(WARN_SUCCESS_WS, warn_m, 2,
309  "Problem not solved with warm start but solved without");
310 
311  ADD_MSG(WARNING_RESOLVING, warn_m,2,
312  "Trying to resolve NLP with different starting point (%d attempts).");
313  ADD_MSG(WARN_SUCCESS_RANDOM, warn_m, 1,
314  "Problem initially not solved but solved with a random starting point (success on %d attempt)");
315  ADD_MSG(WARN_CONTINUING_ON_FAILURE, warn_m, 1,
316  "Warning : continuing branching, while there are unrecovered failures at nodes");
317 
318  ADD_MSG(SUSPECT_PROBLEM, std_m, 2, "NLP number %d is suspect (see bounds and start file)");
319  ADD_MSG(IPOPT_SUMMARY, std_m, 2, "Ipopt return (for %s): status %2d, iter count %4d, time %g");
320  ADD_MSG(BETTER_SOL, std_m, 2, "Solution of value %g found on %d'th attempt");
321 
322  ADD_MSG(LOG_HEAD, std_m, 1,
323  "\n "
324  " Num Status Obj It time Location");
325  ADD_MSG(LOG_LINE, std_m, 1,
326  "%c %8d %11s %g %8d %g %20s");
327 
328  ADD_MSG(ALTERNATE_OBJECTIVE, std_m, 1, "Objective value recomputed with alternate objective: %g.");
329 
330  ADD_MSG(WARN_RESOLVE_BEFORE_INITIAL_SOLVE, warn_m, 1,
331  "resolve called before any call to initialSol can not use warm starts.");
332  ADD_MSG(ERROR_NO_TNLPSOLVER, warn_m, 1,"Can not parse options when no IpApplication has been created");
333  ADD_MSG(WARNING_NON_CONVEX_OA, warn_m, 1,
334  "OA on non-convex constraint is very experimental.");
335  ADD_MSG(SOLVER_DISAGREE_STATUS, warn_m, 1, "%s says problem %s, %s says %s.");
336  ADD_MSG(SOLVER_DISAGREE_VALUE, warn_m, 1, "%s gives objective %.16g, %s gives %.16g.");
337 
338 }
339 
340 
341 void
342 OsiTMINLPInterface::OaMessageHandler::print(OsiRowCut &row){
343  FILE * fp = filePointer();
344  const int &n = row.row().getNumElements();
345  fprintf(fp,"Row cut has %d elements. Lower bound: %g, upper bound %g.\n", n, row.lb(), row.ub());
346  const int * idx = row.row().getIndices();
347  const double * val = row.row().getElements();
348  for(int i = 0 ; i < n ; i++){
349  fprintf(fp,"%g, x%d",val[i], idx[i]);
350  if(i && i % 7 == 0)
351  fprintf(fp,"\n");
352  }
353 }
354 
355 OsiTMINLPInterface::OaMessages::OaMessages(): CoinMessages((int) OA_MESSAGES_DUMMY_END){
356  strcpy(source_,"OaCg");
357  ADD_MSG(VIOLATED_OA_CUT_GENERATED, std_m, 1,"Row %d, cut violation is %g: Outer approximation cut generated.");
358 
359  ADD_MSG(CUT_NOT_VIOLATED_ENOUGH, std_m, 2,"Row %d, cut violation is %g: Outer approximation cut not generated.");
360 
361  ADD_MSG(OA_CUT_GENERATED, std_m, 1,"Row %d: Outer approximation cut not generated.");
362 }
363 bool OsiTMINLPInterface::hasPrintedOptions=0;
364 
366 // Constructors and desctructors //
370  OsiSolverInterface(),
371  tminlp_(NULL),
372  problem_(NULL),
373  problem_to_optimize_(NULL),
374  feasibility_mode_(false),
375  app_(NULL),
376  debug_apps_(),
377  testOthers_(false),
378  warmstart_(NULL),
379  rowsense_(NULL),
380  rhs_(NULL),
381  rowrange_(NULL),
382  reducedCosts_(NULL),
383  OsiDualObjectiveLimit_(1e200),
384  hasVarNamesFile_(true),
385  nCallOptimizeTNLP_(0),
386  totalNlpSolveTime_(0),
387  totalIterations_(0),
388  maxRandomRadius_(1e08),
389  randomGenerationType_(0),
390  max_perturbation_(COIN_DBL_MAX),
391  pushValue_(1e-02),
392  numRetryInitial_(-1),
393  numRetryResolve_(-1),
394  numRetryInfeasibles_(-1),
395  numRetryUnsolved_(1),
396  infeasibility_epsilon_(0),
397  dynamicCutOff_(0),
398  coeff_var_threshold_(0.1),
399  first_perc_for_cutoff_decr_(-0.02),
400  second_perc_for_cutoff_decr_(-0.05),
401  messages_(),
402  pretendFailIsInfeasible_(0),
403  pretendSucceededNext_(0),
404  hasContinuedAfterNlpFailure_(false),
405  numIterationSuspect_(-1),
406  hasBeenOptimized_(false),
407  obj_(NULL),
408  feasibilityProblem_(NULL),
409  jRow_(NULL),
410  jCol_(NULL),
411  jValues_(NULL),
412  nnz_jac(0),
413  constTypes_(NULL),
414  nNonLinear_(0),
415  tiny_(1e-8),
416  veryTiny_(1e-20),
417  rhsRelax_(tiny_),
418  infty_(1e100),
419  warmStartMode_(None),
420  firstSolve_(true),
421  cutStrengthener_(NULL),
422  oaMessages_(),
423  oaHandler_(NULL),
424  newCutoffDecr(COIN_DBL_MAX)
425 
426 {
427  oaHandler_ = new OaMessageHandler;
428  oaHandler_->setLogLevel(0);
429 }
430 
431 void
435  const std::string & prefix,
436  Ipopt::SmartPtr<TMINLP> tminlp){
437  if(!IsValid(app_))
438  createApplication(roptions, options, journalist, prefix);
439  setModel(tminlp);
440 }
441 
443  app_ = app;
444  }
445 
446 
447 void
448 OsiTMINLPInterface::createApplication(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions,
451  const std::string & prefix
452  )
453 {
454  assert(!IsValid(app_));
455  int ival;
456  options->GetEnumValue("nlp_solver", ival, prefix.c_str());
457  Solver s = (Solver) ival;
458  if(s == EFilterSQP){
459  testOthers_ = false;;
460 #ifdef COIN_HAS_FILTERSQP
461  app_ = new Bonmin::FilterSolver(roptions, options, journalist, prefix);
462 #else
463  throw SimpleError("createApplication",
464  "Bonmin not configured to run with FilterSQP.");
465 #endif
466 
467  debug_apps_.push_back(new IpoptSolver(roptions, options, journalist, prefix));
468  }
469  else if(s == EIpopt){
470  testOthers_ = false;
471  app_ = new IpoptSolver(roptions, options, journalist, prefix);
472 
473 #ifdef COIN_HAS_FILTERSQP
474  debug_apps_.push_back(new Bonmin::FilterSolver(roptions, options, journalist, prefix));
475 #endif
476  }
477  else if(s == EAll){
478 #ifdef COIN_HAS_FILTERSQP
479  app_ = new Bonmin::FilterSolver(roptions, options, journalist, prefix);
480 #else
481  throw SimpleError("createApplication",
482  "Bonmin not configured to run with Ipopt.");
483 #endif
484  debug_apps_.push_back(new IpoptSolver(roptions, options, journalist, prefix));
485  testOthers_ = true;
486  }
487  if (!app_->Initialize("")) {
488  throw CoinError("Error during initialization of app_","createApplication", "OsiTMINLPInterface");
489  }
490  for(std::list<Ipopt::SmartPtr<TNLPSolver> >::iterator i = debug_apps_.begin() ;
491  i != debug_apps_.end() ; i++){
492  (*i)->Initialize("");
493  }
494  extractInterfaceParams();
495 
496 }
497 
499 void
501 {
502  assert(IsValid(tminlp));
503  tminlp_ = tminlp;
504  problem_ = new TMINLP2TNLP(tminlp_);
505  feasibilityProblem_ = new TNLP2FPNLP
506  (SmartPtr<TNLP>(GetRawPtr(problem_)));
507  if(feasibility_mode_){
508  problem_to_optimize_ = GetRawPtr(feasibilityProblem_);
509  }
510  else {
511  problem_to_optimize_ = GetRawPtr(problem_);
512  }
513 }
514 
515 
516 
517 void
518 OsiTMINLPInterface::readOptionFile(const std::string & fileName)
519 {
520  if(IsValid(app_)){
521  std::ifstream is;
522  if (fileName != "") {
523  try {
524  is.open(fileName.c_str());
525  }
526  catch(std::bad_alloc) {
527  throw CoinError("Not enough memory to open option file.\n", "readOptionFile", "OsiTMINLPInterface");
528  }
529  }
530  options()->ReadFromStream(*app_->journalist(), is);
531  extractInterfaceParams();
532  }
533 }
534 
537  OsiSolverInterface(source),
538  tminlp_(source.tminlp_),
539  problem_(NULL),
540  problem_to_optimize_(NULL),
541  feasibility_mode_(source.feasibility_mode_),
542  rowsense_(NULL),
543  rhs_(NULL),
544  rowrange_(NULL),
545  reducedCosts_(NULL),
546  OsiDualObjectiveLimit_(source.OsiDualObjectiveLimit_),
547  hasVarNamesFile_(source.hasVarNamesFile_),
548  nCallOptimizeTNLP_(0),
549  totalNlpSolveTime_(0),
550  totalIterations_(0),
551  maxRandomRadius_(source.maxRandomRadius_),
552  randomGenerationType_(source.randomGenerationType_),
553  max_perturbation_(source.max_perturbation_),
554  pushValue_(source.pushValue_),
555  numRetryInitial_(source.numRetryInitial_),
556  numRetryResolve_(source.numRetryResolve_),
557  numRetryInfeasibles_(source.numRetryInfeasibles_),
558  numRetryUnsolved_(source.numRetryUnsolved_),
559  infeasibility_epsilon_(source.infeasibility_epsilon_),
560  dynamicCutOff_(source.dynamicCutOff_),
561  coeff_var_threshold_(source.coeff_var_threshold_),
562  first_perc_for_cutoff_decr_(source.first_perc_for_cutoff_decr_),
563  second_perc_for_cutoff_decr_(source.second_perc_for_cutoff_decr_),
564  messages_(),
565  pretendFailIsInfeasible_(source.pretendFailIsInfeasible_),
566  pretendSucceededNext_(source.pretendSucceededNext_),
567  hasContinuedAfterNlpFailure_(source.hasContinuedAfterNlpFailure_),
568  numIterationSuspect_(source.numIterationSuspect_),
569  hasBeenOptimized_(source.hasBeenOptimized_),
570  obj_(NULL),
571  feasibilityProblem_(NULL),
572  jRow_(NULL),
573  jCol_(NULL),
574  jValues_(NULL),
575  nnz_jac(source.nnz_jac),
576  constTypes_(NULL),
577 // constTypesNum_(NULL),
578  nNonLinear_(0),
579  tiny_(source.tiny_),
580  veryTiny_(source.veryTiny_),
581  rhsRelax_(source.rhsRelax_),
582  infty_(source.infty_),
583  warmStartMode_(source.warmStartMode_),
584  firstSolve_(true),
585  cutStrengthener_(source.cutStrengthener_),
586  oaMessages_(),
587  oaHandler_(NULL),
588  newCutoffDecr(source.newCutoffDecr),
589  strong_branching_solver_(source.strong_branching_solver_)
590 {
591  if(IsValid(source.tminlp_)) {
592  problem_ = source.problem_->clone();
593  feasibilityProblem_ = new TNLP2FPNLP
594  (SmartPtr<TNLP>(GetRawPtr(problem_)), source.feasibilityProblem_);
595  if(feasibility_mode_)
596  problem_to_optimize_ = GetRawPtr(feasibilityProblem_);
597  else
598  problem_to_optimize_ = GetRawPtr(problem_);
599  pretendFailIsInfeasible_ = source.pretendFailIsInfeasible_;
600  pretendSucceededNext_ = source.pretendSucceededNext_;
601 
602  setAuxiliaryInfo(source.getAuxiliaryInfo());
603  // Copy options from old application
604  app_ = source.app_->clone();
605  for(std::list<Ipopt::SmartPtr<TNLPSolver> >::const_iterator i = source.debug_apps_.begin();
606  i != source.debug_apps_.end() ; i++){
607  debug_apps_.push_back((*i)->clone());
608  }
609  testOthers_ = source.testOthers_;
610  }
611  else {
612  throw SimpleError("Don't know how to copy an empty IpoptInterface.",
613  "copy constructor");
614  }
615 
616  warmstart_ = source.warmstart_ ? source.warmstart_->clone() : NULL;
617 
618  if(source.obj_) {
619  obj_ = new double[source.getNumCols()];
620  CoinCopyN(source.obj_, source.getNumCols(), obj_);
621  }
622 
623 
624  oaHandler_ = new OaMessageHandler(*source.oaHandler_);;
625 
626 }
627 
628 OsiSolverInterface *
629 OsiTMINLPInterface::clone(bool copyData ) const
630 {
631  if(copyData)
632  return new OsiTMINLPInterface(*this);
633  else return new OsiTMINLPInterface;
634 }
635 
638 {
639  if(this!= &rhs) {
640  OsiSolverInterface::operator=(rhs);
641  OsiDualObjectiveLimit_ = rhs.OsiDualObjectiveLimit_;
642  nCallOptimizeTNLP_ = rhs.nCallOptimizeTNLP_;
643  totalNlpSolveTime_ = rhs.nCallOptimizeTNLP_;
644  totalIterations_ = rhs.totalIterations_;
645  maxRandomRadius_ = rhs.maxRandomRadius_;
646  hasVarNamesFile_ = rhs.hasVarNamesFile_;
647  pushValue_ = rhs.pushValue_;
648 
649  delete warmstart_;
650  warmstart_ = NULL;
651 
652  if(IsValid(rhs.tminlp_)) {
653 
654  tminlp_ = rhs.tminlp_;
655  problem_ = new TMINLP2TNLP(tminlp_);
656  problem_to_optimize_ = GetRawPtr(problem_);
657  app_ = rhs.app_->clone();
658 
659  warmstart_ = rhs.warmstart_ ? rhs.warmstart_->clone() : NULL;
660 
661  feasibilityProblem_ = new TNLP2FPNLP
662  (SmartPtr<TNLP>(GetRawPtr(problem_)));
663  nnz_jac = rhs.nnz_jac;
664 
665  if(constTypes_ != NULL) {
666  delete [] constTypes_;
667  constTypes_ = NULL;
668  }
669  if(rhs.constTypes_ != NULL) {
670  constTypes_ = new TNLP::LinearityType[getNumRows()];
671  CoinCopyN(rhs.constTypes_, getNumRows(), constTypes_);
672  }
673 /*
674  if(constTypesNum_ != NULL) {
675  delete [] constTypesNum_;
676  constTypesNum_ = NULL;
677  }
678  if(rhs.constTypesNum_ != NULL) {
679  constTypesNum_ = new int[getNumRows()];
680  CoinCopyN(rhs.constTypesNum_, getNumRows(), constTypesNum_);
681  }
682 */
683  if(rhs.jValues_!=NULL && rhs.jRow_ != NULL && rhs.jCol_ != NULL && nnz_jac>0) {
684  jValues_ = new double [nnz_jac];
685  jCol_ = new Index [nnz_jac];
686  jRow_ = new Index [nnz_jac];
687  CoinCopyN(rhs.jValues_ , nnz_jac,jValues_ );
688  CoinCopyN(rhs.jCol_ , nnz_jac,jCol_ );
689  CoinCopyN(rhs.jRow_ , nnz_jac,jRow_ );
690  }
691  else if(nnz_jac > 0) {
692  throw CoinError("Arrays for storing jacobian are inconsistant.",
693  "copy constructor",
694  "IpoptOAInterface");
695  }
696  tiny_ = rhs.tiny_;
697  veryTiny_ = rhs.veryTiny_;
698  rhsRelax_ = rhs.rhsRelax_;
699  infty_ = rhs.infty_;
700  warmStartMode_ = rhs.warmStartMode_;
701  newCutoffDecr = rhs.newCutoffDecr;
702 
703  }
704  else {
705  tminlp_ =NULL;
706  problem_ = NULL;
707  app_ = NULL;
708  feasibilityProblem_ = NULL;
709  }
710 
711 
712  if(obj_) {
713  delete [] obj_;
714  obj_ = NULL;
715  }
716  if(rhs.obj_) {
717  obj_ = new double[rhs.getNumCols()];
718  CoinCopyN(rhs.obj_, rhs.getNumCols(), obj_);
719  }
720 
721  hasVarNamesFile_ = rhs.hasVarNamesFile_;
722 
723  nCallOptimizeTNLP_ = rhs.nCallOptimizeTNLP_;
724  totalNlpSolveTime_ = rhs.totalNlpSolveTime_;
725  totalIterations_ = rhs.totalIterations_;
726  maxRandomRadius_ = rhs.maxRandomRadius_;
727  pushValue_ = rhs.pushValue_;
728  numRetryInitial_ = rhs.numRetryInitial_;
729  numRetryResolve_ = rhs.numRetryResolve_;
730  numRetryInfeasibles_ = rhs.numRetryInfeasibles_;
731  numRetryUnsolved_ = rhs.numRetryUnsolved_;
732  infeasibility_epsilon_ = rhs.infeasibility_epsilon_;
733  pretendFailIsInfeasible_ = rhs.pretendFailIsInfeasible_;
734  pretendSucceededNext_ = rhs.pretendSucceededNext_;
735  numIterationSuspect_ = rhs.numIterationSuspect_;
736 
737  hasBeenOptimized_ = rhs.hasBeenOptimized_;
738  cutStrengthener_ = rhs.cutStrengthener_;
739 
740  delete oaHandler_;
741  oaHandler_ = new OaMessageHandler(*rhs.oaHandler_);
742  strong_branching_solver_ = rhs.strong_branching_solver_;
743 
744  dynamicCutOff_ = rhs.dynamicCutOff_;
745  coeff_var_threshold_ = rhs.coeff_var_threshold_;
746  first_perc_for_cutoff_decr_ = rhs.first_perc_for_cutoff_decr_;
747  second_perc_for_cutoff_decr_ = rhs.second_perc_for_cutoff_decr_;
748 
749  freeCachedData();
750  }
751  return *this;
752 }
753 
755 {
756  if(!IsValid(app_)) {
757  messageHandler()->message(ERROR_NO_TNLPSOLVER, messages_)<<CoinMessageEol;
758  return NULL;
759  }
760  else
761  return app_->options();
762 }
763 
765 {
766  if(!IsValid(app_)) {
767  messageHandler()->message(ERROR_NO_TNLPSOLVER, messages_)<<CoinMessageEol;
768  return NULL;
769  }
770  else
771  return app_->options();
772 }
773 
776 {
777  freeCachedData();
778  delete [] jRow_;
779  delete [] jCol_;
780  delete [] jValues_;
781  delete [] constTypes_;
782  delete [] obj_;
783  delete oaHandler_;
784  delete warmstart_;
785 }
786 
787 void
788 OsiTMINLPInterface::freeCachedColRim()
789 {
790  if(reducedCosts_!=NULL) {
791  delete [] reducedCosts_;
792  reducedCosts_ = NULL;
793  }
794 
795 }
796 
797 void
798 OsiTMINLPInterface::freeCachedRowRim()
799 {
800  if(rowsense_!=NULL) {
801  delete [] rowsense_;
802  rowsense_ = NULL;
803  }
804  if(rhs_!=NULL) {
805  delete [] rhs_;
806  rhs_ = NULL;
807  }
808  if(rowrange_!=NULL) {
809  delete [] rowrange_;
810  rowrange_ = NULL;
811  }
812  // if(dualsol_!=NULL)
813  // {
814  // delete [] dualsol_; dualsol_ = NULL;
815  // }
816 }
817 
818 void
819 OsiTMINLPInterface::freeCachedData()
820 {
821  freeCachedColRim();
822  freeCachedRowRim();
823 }
824 
825 const char * OsiTMINLPInterface::OPT_SYMB="OPT";
826 const char * OsiTMINLPInterface::FAILED_SYMB="FAILED";
827 const char * OsiTMINLPInterface::UNBOUND_SYMB="UNBOUNDED";
828 const char * OsiTMINLPInterface::INFEAS_SYMB="INFEAS";
829 const char * OsiTMINLPInterface::TIME_SYMB="TIME";
831 // WarmStart Information //
833 
834 
835 void
836 OsiTMINLPInterface::resolveForCost(int numsolve, bool keepWarmStart)
837 {
838  // This method assumes that a problem has just been solved and we try for a
839  // different solution. So disregard (in fact, clear out) any warmstart info
840  // we might have, and acquire a new one before returning.
841  delete warmstart_;
842  warmstart_ = NULL;
843 
844  double * of_current = (numsolve > 0) ? new double[numsolve]: NULL;
845  int num_failed, num_infeas;
846  double mean, std_dev, var_coeff;
847  double min = DBL_MAX;
848  double max = -DBL_MAX;
849 
850  Coin::SmartPtr<SimpleReferencedPtr<CoinWarmStart> > ws_backup = NULL;
851  if(warmStartMode_ <= Optimum && keepWarmStart){
852  //if warm start is not exposed, we need to store the current starting point to
853  //restore it at the end of the method
854  ws_backup = make_referenced(app_->getUsedWarmStart(problem_));
855  }
857  vector<double> point(getNumCols()*3+ getNumRows());
858  double bestBound = (isProvenOptimal()) ? getObjValue() : DBL_MAX;
859  CoinCopyN(getColSolution(),
860  getNumCols(), point());
861  CoinCopyN(getRowPrice(),
862  2*getNumCols()+ getNumRows(),
863  point() + getNumCols());
864  TNLPSolver::ReturnStatus savedStatus = optimizationStatus_;
865  if(isProvenOptimal())
866  messageHandler()->message(SOLUTION_FOUND,
867  messages_)
868  <<1<<getObjValue()<<bestBound
869  <<CoinMessageEol;
870  else
871  messageHandler()->message(INFEASIBLE_SOLUTION_FOUND,
872  messages_)
873  <<1
874  <<CoinMessageEol;
875 
876  num_failed = 0;
877  num_infeas = 0;
878  mean = 0;
879 
880  for(int f = 0; f < numsolve ; f++) {
881  messageHandler()->message(WARNING_RESOLVING,
882  messages_)
883  <<f+1<< CoinMessageEol ;
885  solveAndCheckErrors(0,0,"resolve cost");
886 
887 
888  char c=' ';
889  //Is solution better than previous
890  if(isProvenOptimal() &&
891  getObjValue()<bestBound) {
892  c='*';
893  messageHandler()->message(BETTER_SOL, messages_)<<getObjValue()<<f+1<< CoinMessageEol;
894  CoinCopyN(getColSolution(),
895  getNumCols(), point());
896  CoinCopyN(getRowPrice(),
897  2*getNumCols()+ getNumRows(),
898  point() + getNumCols());
899  bestBound = getObjValue();
900  savedStatus = optimizationStatus_;
901  }
902 
903  messageHandler()->message(LOG_LINE, messages_)
904  <<c<<f+1<<statusAsString()<<getObjValue()<<app_->IterationCount()<<app_->CPUTime()<<"resolve cost"<<CoinMessageEol;
905 
906  if(isAbandoned()) {
907  num_failed++;
908  }
909  else if(isProvenPrimalInfeasible()) {
910  num_infeas++;
911  }
912 
913  else if(isProvenOptimal())
914  messageHandler()->message(SOLUTION_FOUND,
915  messages_)
916  <<f+2<<getObjValue()<<bestBound
917  <<CoinMessageEol;
918  else if(!isAbandoned())
919  messageHandler()->message(UNSOLVED_PROBLEM_FOUND,
920  messages_)
921  <<f+2
922  <<CoinMessageEol;
923  else
924  messageHandler()->message(INFEASIBLE_SOLUTION_FOUND,
925  messages_)
926  <<f+2
927  <<CoinMessageEol;
928 
929  if(of_current != NULL){
930  if(isProvenOptimal())
931  {
932  of_current[f] = getObjValue();
933  mean=mean+of_current[f];
934  if (of_current[f] < min)
935  min = of_current[f];
936  else if (of_current[f] > max)
937  max = of_current[f];
938  }
939  else
940  {
941  of_current[f] = 0;
942  }
943  }
944 }
945 
946 
947  if(of_current != NULL){
948  //calculate the mean
949  mean=mean/(numsolve-num_failed-num_infeas);
950 
951  std_dev = 0;
952 
953  //calculate the std deviation
954  for(int i=0; i<numsolve; i++)
955  {
956  if(of_current[i]!=0)
957  std_dev=std_dev+pow(of_current[i]-mean,2);
958  }
959  std_dev=pow((std_dev/(numsolve-num_failed-num_infeas)),0.5);
960 
961  //calculate coeff of variation
962  var_coeff=std_dev/mean;
963 
964  if(dynamicCutOff_)
965  {
966  if(var_coeff<0.1)
967  {
968  setNewCutoffDecr(mean*first_perc_for_cutoff_decr_);
969  }
970  else
971  {
972  setNewCutoffDecr(mean*second_perc_for_cutoff_decr_);
973  }
974  }
975  }
976 
977  problem_->Set_x_sol(getNumCols(),point());
978  problem_->Set_dual_sol((int) point.size()-getNumCols(), point() + getNumCols());
979  problem_->set_obj_value(bestBound);
980  optimizationStatus_ = savedStatus;
981  hasBeenOptimized_ = true;
982 
983  if(warmStartMode_ < Optimum && keepWarmStart) {
984  app_->setWarmStart(ws_backup->ptr(), problem_);
985  }
986 }
987 
988 void
990 {
991  // This method assumes that a problem has just been solved and we try for a
992  // different solution. So disregard (in fact, clear out) any warmstart info
993  // we might have, and acquire a new one before returning.
994  delete warmstart_;
995  warmstart_ = NULL;
996 
997 
998  CoinWarmStart * ws_backup = NULL;
999  if(warmStartMode_ < Optimum){
1000  //if warm start is not exposed, we need to store the current starting point to
1001  //restore it at the end of the method
1002  ws_backup = app_->getUsedWarmStart(problem_);
1003  }
1004  //std::cerr<<"Resolving the problem for robustness"<<std::endl;
1005  //First remove warm start point and resolve
1006  app_->disableWarmStart();
1008  messageHandler()->message(WARNING_RESOLVING,
1009  messages_)
1010  <<1<< CoinMessageEol ;
1011  solveAndCheckErrors(0,0,"resolve robustness");
1012 
1013 
1014  char c='*';
1015  if(isAbandoned()) {
1016  c=' ';
1017  }
1018  messageHandler()->message(LOG_LINE, messages_)
1019  <<c<<1<<statusAsString()<<getObjValue()<<app_->IterationCount()<<
1020  app_->CPUTime()<<"resolve robustness"<<CoinMessageEol;
1021 
1022 
1023  if(!isAbandoned()) {
1024  messageHandler()->message(WARN_SUCCESS_WS, messages_) << CoinMessageEol ;
1025  // re-enable warmstart and get it
1026  app_->enableWarmStart();
1027  if (warmStartMode_ < Optimum) {
1028  app_->setWarmStart(ws_backup, problem_);
1029  delete ws_backup;
1030  }
1031  return; //we won go on
1032  }
1033 
1034  //still unsolved try again with different random starting points
1035  for(int f = 0; f < numsolve ; f++) {
1036  messageHandler()->message(WARNING_RESOLVING,
1037  messages_)
1038  <<f+2<< CoinMessageEol ;
1039 
1041  solveAndCheckErrors(0,0,"resolve robustness");
1042 
1043 
1044  messageHandler()->message(IPOPT_SUMMARY, messages_)
1045  <<"resolveForRobustness"<<optimizationStatus_<<app_->IterationCount()<<app_->CPUTime()<<CoinMessageEol;
1046 
1047 
1048  char c='*';
1049  if(isAbandoned()) {
1050  c=' ';
1051  }
1052  messageHandler()->message(LOG_LINE, messages_)
1053  <<c<<f+2<<statusAsString()<<getObjValue()
1054  <<app_->IterationCount()<<app_->CPUTime()<<"resolve robustness"<<CoinMessageEol;
1055 
1056 
1057  if(!isAbandoned()) {
1058  messageHandler()->message(WARN_SUCCESS_RANDOM, messages_)
1059  << f+2 << CoinMessageEol ;
1060  // re-enable warmstart and get it
1061  app_->enableWarmStart();
1062  if (warmStartMode_ < Optimum) {
1063  app_->setWarmStart(ws_backup, problem_);
1064  delete ws_backup;
1065  }
1066 
1067  return; //we have found a solution and continue
1068  }
1069  }
1070 
1071 
1072  if(warmStartMode_ < Optimum){
1073  app_->setWarmStart(ws_backup, problem_);
1074  delete ws_backup;
1075  }
1076  if(pretendFailIsInfeasible_) {
1077  pretendSucceededNext_ = true;
1078  if(pretendFailIsInfeasible_ == 1) {
1079  messageHandler()->message(WARN_CONTINUING_ON_FAILURE,
1080  messages_)
1081  <<CoinMessageEol;
1082  hasContinuedAfterNlpFailure_ = 1;
1083  }
1084  return;
1085  }
1086  else {
1087  std::string probName;
1088  getStrParam(OsiProbName,probName);
1089  throw newUnsolvedError(app_->errorCode(), problem_,
1090  probName);
1091  }
1092  // Do NOT get warmstart in other cases
1093 }
1094 
1096 // Problem information methods //
1100 {
1101 
1102  return problem_->num_variables();
1103 }
1104 
1105 
1107 int
1109 {
1110  return problem_->num_constraints();
1111 }
1112 
1113 const double *
1115 {
1116  return problem_->x_l();
1117 }
1118 
1119 const double *
1121 {
1122  return problem_->x_u();
1123 }
1124 
1125 #if 1
1126 
1127 
1129 const OsiSolverInterface::OsiNameVec&
1131  return getColNames();
1132 }
1133 #endif
1134 
1135 
1136 void OsiTMINLPInterface::extractSenseRhsAndRange() const
1137 {
1138  assert(rowsense_==NULL&&rhs_==NULL&&rowrange_==NULL);
1139  int numrows = problem_->num_constraints();
1140  if(numrows == 0) return;
1141  const double * rowLower = getRowLower();
1142  const double * rowUpper = getRowUpper();
1143  rowsense_ = new char [numrows];
1144  rhs_ = new double [numrows];
1145  rowrange_ = new double [numrows];
1146  for(int i = 0 ; i < numrows ; i++) {
1147  rowrange_[i]=0.;
1148  convertBoundToSense(rowLower[i], rowUpper[i], rowsense_[i], rhs_[i], rowrange_[i]);
1149  }
1150 }
1151 
1161 const char *
1163 {
1164  if(rowsense_==NULL) {
1165  extractSenseRhsAndRange();
1166  }
1167  return rowsense_;
1168 }
1169 
1178 const double *
1180 {
1181  if(rhs_==NULL) {
1182  extractSenseRhsAndRange();
1183  }
1184  return rhs_;
1185 }
1186 
1195 const double *
1197 {
1198  if(rowrange_==NULL) {
1199  extractSenseRhsAndRange();
1200  }
1201  return rowrange_;
1202 }
1203 
1204 const double *
1206 {
1207  return problem_->g_l();
1208 }
1209 
1210 const double *
1212 {
1213  return problem_->g_u();
1214 }
1215 
1217 bool
1219 {
1220  return (problem_->var_types()[colNumber]==TMINLP::CONTINUOUS);
1221 }
1222 
1224 bool
1225 OsiTMINLPInterface::isBinary(int colNumber) const
1226 {
1227  return (problem_->var_types()[colNumber]==TMINLP::BINARY);
1228 }
1229 
1234 bool
1235 OsiTMINLPInterface::isInteger(int colNumber) const
1236 {
1237  return ((problem_->var_types()[colNumber]==TMINLP::BINARY)||
1238  (problem_->var_types()[colNumber]==TMINLP::INTEGER));
1239 }
1240 
1242 bool
1244 {
1245  return (problem_->var_types()[colNumber]==TMINLP::INTEGER);
1246 }
1248 bool
1250 {
1251  return ((problem_->var_types()[colNumber]==TMINLP::BINARY)
1252  &&((getColUpper()[colNumber]-getColLower()[colNumber]) > 1 - 1e-09));
1253 }
1254 
1256 double
1258 {
1259  return COIN_DBL_MAX;
1260 }
1261 
1263 const double *
1265 {
1266  if(hasBeenOptimized_)
1267  return problem_->x_sol();
1268  else
1269  return problem_->x_init();
1270 }
1271 
1273 const double *
1275 {
1276  if(hasBeenOptimized_)
1277  return problem_->duals_sol();
1278  else
1279  return problem_->duals_init();
1280 }
1281 
1283 const double *
1285 {
1286  (*handler_)<<"WARNING : trying to access reduced cost in Ipopt always retrun 0"<<CoinMessageEol;
1287  if(reducedCosts_==NULL) {
1288  reducedCosts_ = new double [getNumCols()];
1289  CoinFillN(reducedCosts_,getNumCols(),0.);
1290  }
1291  return reducedCosts_;
1292 }
1293 
1296 const double *
1298 {
1299  return problem_->g_sol();
1300 }
1301 
1305 int
1307 {
1308  return app_->IterationCount();
1309 }
1310 
1311 
1314 void
1315 OsiTMINLPInterface::setColLower( int elementIndex, double elementValue )
1316 {
1317  // if(fabs(problem_->x_l()[elementIndex]-elementValue)>1e-06)
1318  problem_->SetVariableLowerBound(elementIndex,elementValue);
1319  hasBeenOptimized_ = false;
1320 }
1321 
1324 void
1325 OsiTMINLPInterface::setColUpper( int elementIndex, double elementValue )
1326 {
1327  // if(fabs(problem_->x_u()[elementIndex]-elementValue)>1e-06)
1328  problem_->SetVariableUpperBound(elementIndex,elementValue);
1329  hasBeenOptimized_ = false;
1330 }
1331 
1334 void
1335 OsiTMINLPInterface::setColLower( const double* array )
1336 {
1337  problem_->SetVariablesLowerBounds(problem_->num_variables(),
1338  array);
1339  hasBeenOptimized_ = false;
1340 }
1341 
1344 void
1345 OsiTMINLPInterface::setColUpper( const double* array )
1346 {
1347  problem_->SetVariablesUpperBounds(problem_->num_variables(),
1348  array);
1349  hasBeenOptimized_ = false;
1350 }
1351 
1354 void
1355 OsiTMINLPInterface::setRowLower( int elementIndex, double elementValue )
1356 {
1357  throw SimpleError("Not implemented yet but should be if necessary.",
1358  "setRowLower");
1359  hasBeenOptimized_ = false;
1360 }
1361 
1364 void
1365 OsiTMINLPInterface::setRowUpper( int elementIndex, double elementValue )
1366 {
1367  throw SimpleError("Not implemented yet but should be if necessary.",
1368  "setRowUpper");
1369  hasBeenOptimized_ = false;
1370 }
1371 
1373 void
1374 OsiTMINLPInterface::setRowType(int index, char sense, double rightHandSide,
1375  double range)
1376 {
1377  throw SimpleError("Not implemented yet but should be if necessary.",
1378  "setRowType");
1379  hasBeenOptimized_ = false;
1380 }
1381 
1382 
1385 void
1387 {
1388  throw SimpleError("Can not change objective sense of an Ipopt problem.",
1389  "setObjSense");
1390  hasBeenOptimized_ = false;
1391 }
1392 
1402 void
1404 {
1405  if(colsol != NULL)
1406  problem_->setxInit(getNumCols(), colsol);
1407  else
1408  problem_->resetStartingPoint();
1409  hasBeenOptimized_ = false;
1410 }
1411 
1422 void
1423 OsiTMINLPInterface::setRowPrice(const double * rowprice)
1424 {
1425  problem_->setDualsInit(getNumCols()*2 + getNumRows(), rowprice);
1426  hasBeenOptimized_ = false;
1427 }
1428 
1435 CoinWarmStart *
1437 {return app_->getEmptyWarmStart();}
1438 
1440 CoinWarmStart*
1442 {
1443  if (warmStartMode_ >= Optimum) {
1444  return internal_getWarmStart();;
1445  }
1446  else if(warmStartMode_ == FakeBasis){
1447  return build_fake_basis();
1448  }
1449  else {
1450  return getEmptyWarmStart();
1451  }
1452 }
1455 bool
1457 {
1458  if (warmStartMode_ >= Optimum) {
1459  return internal_setWarmStart(ws);
1460  }
1461  else {
1462  return true;
1463  }
1464 }
1465 
1466 
1467 #define EPSILON 1e-4
1468 
1469 CoinWarmStart*
1470 OsiTMINLPInterface::build_fake_basis() const{
1471  CoinWarmStartBasis * r_val = new CoinWarmStartBasis();
1472  int n_con = problem_->num_constraints();
1473  r_val->setSize(problem_->num_variables(), n_con);
1474  const double * act = problem_->g_sol();
1475  const double * lb = problem_->g_l();
1476  const double * ub = problem_->g_u();
1477  for(int i = 0 ; i < n_con ; i++){
1478  if(lb[i] > ub[i] - EPSILON){
1479  r_val->setArtifStatus(i, CoinWarmStartBasis::isFree);
1480  }
1481  if(act[i] > ub[i] - EPSILON){
1482  r_val->setArtifStatus(i, CoinWarmStartBasis::atLowerBound);
1483  }
1484  else if(act[i] < lb[i] + EPSILON){
1485  r_val->setArtifStatus(i, CoinWarmStartBasis::atLowerBound);
1486  }
1487  else {
1488  r_val->setArtifStatus(i, CoinWarmStartBasis::basic);
1489  }
1490  }
1491  return r_val;
1492 }
1493 
1495 CoinWarmStart*
1496 OsiTMINLPInterface::internal_getWarmStart() const
1497 {
1498  if (warmStartMode_ >= Optimum && warmstart_) {
1499  return warmstart_->clone();
1500  }
1501  else {
1502  return getEmptyWarmStart();
1503  }
1504 }
1507 bool
1508 OsiTMINLPInterface::internal_setWarmStart(const CoinWarmStart* ws)
1509 {
1510  delete warmstart_;
1511  warmstart_ = NULL;
1512  hasBeenOptimized_ = false;
1513  if (warmStartMode_ >= Optimum) {
1514  if (ws == NULL) {
1515  return true;
1516  }
1517  if(app_->warmStartIsValid(ws)) {
1518  warmstart_ = ws->clone();
1519  return true;
1520  }
1521  // See if it is anything else than the CoinWarmStartBasis that all others
1522  // derive from
1523  const CoinWarmStartPrimalDual* pdws =
1524  dynamic_cast<const CoinWarmStartPrimalDual*>(ws);
1525  if (pdws) {
1526  // Must be an IpoptWarmStart, since the others do not derive from this.
1527  // Accept it.
1528  warmstart_ = new IpoptWarmStart(*pdws);
1529  return true;
1530  }
1531  return false;
1532  }
1533  else {
1534  return true;
1535  }
1536 }
1537 
1539 void
1541 {
1542  problem_->SetVariableType(index, TMINLP::CONTINUOUS);
1543  hasBeenOptimized_ = false;
1544 }
1546 void
1548 {
1549  problem_->SetVariableType(index, TMINLP::INTEGER);
1550  hasBeenOptimized_ = false;
1551 }
1552 
1554 double
1556 {
1557  return problem_->obj_value();
1558 }
1559 
1560 //#############################################################################
1561 // Parameter related methods
1562 //#############################################################################
1563 
1564 bool
1565 OsiTMINLPInterface::setIntParam(OsiIntParam key, int value)
1566 {
1567  // debugMessage("OsiCpxSolverInterface::setIntParam(%d, %d)\n", key, value);
1568 
1569  bool retval = false;
1570  switch (key) {
1571  case OsiMaxNumIteration:
1572  retval = false;
1573  break;
1574  case OsiMaxNumIterationHotStart:
1575  if( value >= 0 ) {
1576  retval = false;
1577  }
1578  else
1579  retval = false;
1580  break;
1581  case OsiLastIntParam:
1582  retval = false;
1583  break;
1584  default:
1585  retval = false;
1586  (*handler_)<< "Unhandled case in setIntParam\n"<<CoinMessageEol;
1587  break;
1588  }
1589  return retval;
1590 }
1591 
1592 //-----------------------------------------------------------------------------
1593 
1594 bool
1595 OsiTMINLPInterface::setDblParam(OsiDblParam key, double value)
1596 {
1597  // debugMessage("OsiTMINLPInterface::setDblParam(%d, %g)\n", key, value);
1598 
1599  bool retval = false;
1600  switch (key) {
1601  case OsiDualObjectiveLimit:
1602  OsiDualObjectiveLimit_ = value;
1603  retval = true;
1604  break;
1605  case OsiPrimalObjectiveLimit:
1606  (*handler_)<<"Can not set primal objective limit parameter"<<CoinMessageEol;
1607  retval = false;
1608  break;
1609  case OsiDualTolerance:
1610  (*handler_)<<"Can not set dual tolerance parameter"<<CoinMessageEol;
1611  retval = false;
1612  break;
1613  case OsiPrimalTolerance:
1614  (*handler_)<<"Can not set primal tolerance parameter"<<CoinMessageEol;
1615  retval = false;
1616  case OsiObjOffset:
1617  retval = OsiSolverInterface::setDblParam(key,value);
1618  break;
1619  case OsiLastDblParam:
1620  retval = false;
1621  break;
1622  default:
1623  retval = false;
1624  (*handler_) << "Unhandled case in setDblParam"<<CoinMessageEol;
1625  break;
1626  }
1627  return retval;
1628 }
1629 
1630 
1631 //-----------------------------------------------------------------------------
1632 
1633 bool
1634 OsiTMINLPInterface::setStrParam(OsiStrParam key, const std::string & value)
1635 {
1636  // debugMessage("OsiTMINLPInterface::setStrParam(%d, %s)\n", key, value.c_str());
1637 
1638  bool retval=false;
1639  switch (key) {
1640  case OsiProbName:
1641  OsiSolverInterface::setStrParam(key,value);
1642  return retval = true;
1643  case OsiSolverName:
1644  return false;
1645  case OsiLastStrParam:
1646  return false;
1647  }
1648  return false;
1649 }
1650 
1651 //-----------------------------------------------------------------------------
1652 
1653 bool
1654 OsiTMINLPInterface::getIntParam(OsiIntParam key, int& value) const
1655 {
1656  // debugMessage("OsiTMINLPInterface::getIntParam(%d)\n", key);
1657 
1658  value = -COIN_INT_MAX; // Give a dummy value
1659  bool retval = false;
1660  switch (key) {
1661  case OsiMaxNumIteration:
1662  retval = false;
1663  break;
1664  case OsiMaxNumIterationHotStart:
1665  retval = false;
1666  break;
1667  case OsiLastIntParam:
1668  retval = false;
1669  break;
1670  default:
1671  retval = false;
1672  (*handler_) << "Unhandled case in setIntParam"<<CoinMessageEol;
1673  }
1674  return retval;
1675 }
1676 
1677 //-----------------------------------------------------------------------------
1678 
1679 bool
1680 OsiTMINLPInterface::getDblParam(OsiDblParam key, double& value) const
1681 {
1682  // debugMessage("OsiTMINLPInterface::getDblParam(%d)\n", key);
1683 
1684  bool retval = false;
1685  switch (key) {
1686  case OsiDualObjectiveLimit:
1687  value = OsiDualObjectiveLimit_;
1688  retval = true;
1689  break;
1690  case OsiPrimalObjectiveLimit:
1691  value = getInfinity();
1692  retval = true;
1693  break;
1694  case OsiDualTolerance:
1695  retval = false;
1696  break;
1697  case OsiPrimalTolerance:
1698  options()->GetNumericValue("tol", value,"");
1699  value = 1e-07;
1700  retval = true;
1701  break;
1702  case OsiObjOffset:
1703  retval = OsiSolverInterface::getDblParam(key, value);
1704  break;
1705  case OsiLastDblParam:
1706  retval = false;
1707  break;
1708  }
1709  return retval;
1710 }
1711 
1712 
1713 //-----------------------------------------------------------------------------
1714 
1715 bool
1716 OsiTMINLPInterface::getStrParam(OsiStrParam key, std::string & value) const
1717 {
1718  // debugMessage("OsiTMINLPInterface::getStrParam(%d)\n", key);
1719 
1720  switch (key) {
1721  case OsiProbName:
1722  OsiSolverInterface::getStrParam(key, value);
1723  break;
1724  case OsiSolverName:
1725  value = "Ipopt";
1726  break;
1727  case OsiLastStrParam:
1728  return false;
1729  }
1730 
1731  return true;
1732 }
1733 
1734 void
1735 OsiTMINLPInterface::set_linearizer(Ipopt::SmartPtr<TMINLP2OsiLP> linearizer)
1736 {
1737  linearizer_ = linearizer->clone();
1738  linearizer_->set_tols(tiny_, veryTiny_, rhsRelax_, infty_);
1739  linearizer_->set_model(GetRawPtr(problem_));
1740 }
1741 
1743 OsiTMINLPInterface::linearizer(){
1744  return linearizer_;
1745 }
1746 
1747 
1748 void
1750 {
1751  int numcols = getNumCols();
1752  const double * colLower = getColLower();
1753  const double * colUpper = getColUpper();
1754  double * sol = new double[numcols];
1755  const Number * x_init = problem_->x_init_user();
1756  const double* perturb_radius = NULL;
1757  if (randomGenerationType_ == perturb_suffix) {
1758  const TMINLP::PerturbInfo* pertubinfo = tminlp_->perturbInfo();
1759  if (pertubinfo) {
1760  perturb_radius = pertubinfo->GetPerturbationArray();
1761  }
1762  if (!perturb_radius) {
1763  throw SimpleError("Can't use perturb_radius if no radii are given.",
1764  "randomStartingPoint");
1765  }
1766  }
1767  for(int i = 0 ; i < numcols ; i++) {
1768  if(randomGenerationType_ == uniform || x_init[i] < colLower[i] || x_init[i] > colUpper[i]) {
1769  double lower = std::min(-maxRandomRadius_,colUpper[i] - maxRandomRadius_);
1770  lower = std::max(colLower[i], lower);
1771  double upper = std::max(maxRandomRadius_,colLower[i] + maxRandomRadius_);
1772  upper = std::min(colUpper[i],upper);
1773  lower = std::min(upper,lower);
1774  upper = std::max(upper, lower);
1775  double interval = upper - lower;
1776  sol[i] = CoinDrand48()*(interval) + lower;
1777  }
1778  else if (randomGenerationType_ == perturb) {
1779  const double lower = std::max(x_init[i] - max_perturbation_, colLower[i]);
1780  const double upper = std::min(x_init[i] + max_perturbation_, colUpper[i]);
1781  const double interval = upper - lower;
1782  sol[i] = lower + CoinDrand48()*(interval);
1783  }
1784  else if (randomGenerationType_ == perturb_suffix) {
1785  const double radius = perturb_radius[i];
1786  const double lower = std::max(x_init[i] - radius*max_perturbation_, colLower[i]);
1787  const double upper = std::min(x_init[i] + radius*max_perturbation_, colUpper[i]);
1788  const double interval = upper - lower;
1789  sol[i] = lower + CoinDrand48()*(interval);
1790  }
1791  }
1792  app_->disableWarmStart();
1793  setColSolution(sol);
1794  delete [] sol;
1795 }
1796 
1797 
1798 
1800 int OsiTMINLPInterface::initializeJacobianArrays()
1801 {
1802  Index n, m, nnz_h_lag;
1803  TNLP::IndexStyleEnum index_style;
1804  problem_to_optimize_->get_nlp_info( n, m, nnz_jac, nnz_h_lag, index_style);
1805 
1806  if(jRow_ != NULL) delete [] jRow_;
1807  if(jCol_ != NULL) delete [] jCol_;
1808  if(jValues_ != NULL) delete [] jValues_;
1809 
1810  jRow_ = new Index[nnz_jac];
1811  jCol_ = new Index[nnz_jac];
1812  jValues_ = new Number[nnz_jac];
1813  problem_to_optimize_->eval_jac_g(n, NULL, 0, m, nnz_jac, jRow_, jCol_, NULL);
1814  if(index_style == Ipopt::TNLP::FORTRAN_STYLE)//put C-style
1815  {
1816  for(int i = 0 ; i < nnz_jac ; i++){
1817  jRow_[i]--;
1818  jCol_[i]--;
1819  }
1820  }
1821 
1822  if(constTypes_ != NULL) delete [] constTypes_;
1823 // if(constTypesNum_ != NULL) delete [] constTypesNum_;
1824 
1825  constTypes_ = new TNLP::LinearityType[getNumRows()];
1826  problem_to_optimize_->get_constraints_linearity(getNumRows(), constTypes_);
1827 // constTypesNum_ = new int[getNumRows()];
1828  for(int i = 0; i < getNumRows() ; i++) {
1829  if(constTypes_[i]==TNLP::NON_LINEAR) {
1830  //constTypesNum_[i] =
1831  nNonLinear_++;
1832  }
1833  }
1834  return nnz_jac;
1835 }
1836 
1837 
1838 double
1839 OsiTMINLPInterface::getConstraintsViolation(const double *x, double &obj)
1840 {
1841  int numcols = getNumCols();
1842  int numrows = getNumRows();
1843  double * g = new double[numrows];
1844  tminlp_->eval_g(numcols, x, 1, numrows, g);
1845  const double * rowLower = getRowLower();
1846  const double * rowUpper = getRowUpper();
1847 
1848 
1849  double norm = 0;
1850  for(int i = 0; i< numrows ; i++) {
1851  if(!constTypes_ || constTypes_[i] == TNLP::NON_LINEAR) {
1852  double rowViolation = 0;
1853  if(rowLower[i] > -1e10)
1854  rowViolation = std::max(0.,rowLower[i] - g[i]);
1855 
1856  if(rowUpper[i] < 1e10);
1857  rowViolation = std::max(rowViolation, g[i] - rowUpper[i]);
1858 
1859  norm = rowViolation > norm ? rowViolation : norm;
1860  }
1861  }
1862  tminlp_->eval_f(numcols, x, 1, obj);
1863  delete [] g;
1864  return norm;
1865 }
1866 
1868 double
1869 OsiTMINLPInterface::getNonLinearitiesViolation(const double *x, const double obj)
1870 {
1871  double f;
1872  double norm = getConstraintsViolation(x, f);
1873  assert((f - obj) > -1e-08);
1874  norm = (f - obj) > norm ? f - obj : norm;
1875  return norm;
1876 }
1877 
1878 
1879 
1880 //A procedure to try to remove small coefficients in OA cuts (or make it non small
1881 static inline
1882 bool cleanNnz(double &value, double colLower, double colUpper,
1883  double rowLower, double rowUpper, double colsol,
1884  double & lb, double &ub, double tiny, double veryTiny,
1885  double infty)
1886 {
1887  //return 1;
1888  if(fabs(value)>= tiny) return 1;
1889 
1890  if(fabs(value)<veryTiny) return 0;//Take the risk?
1891 
1892  //try and remove
1893  bool colUpBounded = colUpper < infty;
1894  bool colLoBounded = colLower > -infty;
1895  bool rowNotLoBounded = rowLower <= - infty;
1896  bool rowNotUpBounded = rowUpper >= infty;
1897  bool pos = value > 0;
1898  if(colUpBounded && pos && rowNotUpBounded) {
1899  lb += value * (colsol - colUpper);
1900  return 0;
1901  }
1902  else
1903  if(colUpBounded && !pos && rowNotLoBounded) {
1904  ub += value * (colsol - colUpper);
1905  return 0;
1906  }
1907  else
1908  if(colLoBounded && !pos && rowNotUpBounded) {
1909  lb += value * (colsol - colLower);
1910  return 0;
1911  }
1912  else
1913  if(colLoBounded && pos && rowNotLoBounded) {
1914  ub += value * (colsol - colLower);
1915  return 0;
1916  }
1917  //can not remove coefficient
1918  return 1;
1919 }
1920 
1923 void
1924 OsiTMINLPInterface::getOuterApproximation(OsiCuts &cs, const double * x,
1925  int getObj, const double * x2,
1926  double theta, bool global)
1927 {
1928  if(IsValid(linearizer_) && x2 == NULL){
1929  linearizer_->get_oas(cs, x, getObj, global);
1930  return;
1931  }
1932  int n,m, nnz_jac_g, nnz_h_lag;
1933  TNLP::IndexStyleEnum index_style;
1934  problem_to_optimize_->get_nlp_info( n, m, nnz_jac_g, nnz_h_lag, index_style);
1935  if(jRow_ == NULL || jCol_ == NULL || jValues_ == NULL)
1936  initializeJacobianArrays();
1937  assert(jRow_ != NULL);
1938  assert(jCol_ != NULL);
1939  vector<double> g(m);
1940  problem_to_optimize_->eval_jac_g(n, x, 1, m, nnz_jac_g, NULL, NULL, jValues_);
1941  problem_to_optimize_->eval_g(n,x,1,m,g());
1942  //As jacobian is stored by cols fill OsiCuts with cuts
1943  vector<CoinPackedVector> cuts(nNonLinear_ + 1);
1944  vector<double> lb(nNonLinear_ + 1);
1945  vector<double> ub(nNonLinear_ + 1);
1946 
1947  vector<int> row2cutIdx(m,-1);//store correspondance between index of row and index of cut (some cuts are not generated for rows because linear, or not binding). -1 if constraint does not generate a cut, otherwise index in cuts.
1948  int numCuts = 0;
1949 
1950  const double * rowLower = getRowLower();
1951  const double * rowUpper = getRowUpper();
1952  const double * colLower = getColLower();
1953  const double * colUpper = getColUpper();
1954  const double * duals = getRowPrice() + 2 * n;
1955  double infty = getInfinity();
1956 
1957  for(int rowIdx = 0; rowIdx < m ; rowIdx++) {
1958  if(constTypes_[rowIdx] == TNLP::NON_LINEAR) {
1959  row2cutIdx[rowIdx] = numCuts;
1960  if(rowLower[rowIdx] > - infty_)
1961  lb[numCuts] = rowLower[rowIdx] - g[rowIdx];
1962  else
1963  lb[numCuts] = - infty;
1964  if(rowUpper[rowIdx] < infty_)
1965  ub[numCuts] = rowUpper[rowIdx] - g[rowIdx];
1966  else
1967  ub[numCuts] = infty;
1968  if(rowLower[rowIdx] > -infty && rowUpper[rowIdx] < infty)
1969  {
1970  if(duals[rowIdx] >= 0)// <= inequality
1971  lb[numCuts] = - infty;
1972  if(duals[rowIdx] <= 0)// >= inequality
1973  ub[numCuts] = infty;
1974  }
1975 
1976  numCuts++;
1977  }
1978  }
1979 
1980 
1981  for(int i = 0 ; i < nnz_jac_g ; i++) {
1982  const int &rowIdx = jRow_[i];
1983  const int & cutIdx = row2cutIdx[ rowIdx ];
1984  if(cutIdx != -1) {
1985  const int &colIdx = jCol_[i];
1986  //"clean" coefficient
1987  if(cleanNnz(jValues_[i],colLower[colIdx], colUpper[colIdx],
1988  rowLower[rowIdx], rowUpper[rowIdx],
1989  x[colIdx],
1990  lb[cutIdx],
1991  ub[cutIdx], tiny_, veryTiny_, infty_)) {
1992  cuts[cutIdx].insert(colIdx,jValues_[i]);
1993  if(lb[cutIdx] > - infty)
1994  lb[cutIdx] += jValues_[i] * x[colIdx];
1995  if(ub[cutIdx] < infty)
1996  ub[cutIdx] += jValues_[i] * x[colIdx];
1997  }
1998  }
1999  }
2000 
2001  vector<int> cut2rowIdx(0);
2002  if (IsValid(cutStrengthener_) || oaHandler_->logLevel() > 0) {
2003  cut2rowIdx.resize(numCuts);// Store correspondance between indices of cut and indices of rows. For each cut
2004  for(int rowIdx = 0 ; rowIdx < m ; rowIdx++){
2005  if(row2cutIdx[rowIdx] >= 0){
2006  cut2rowIdx[row2cutIdx[rowIdx]] = rowIdx;
2007  }
2008  }
2009  }
2010 
2011  for(int cutIdx = 0; cutIdx < numCuts; cutIdx++) {
2012  //Compute cut violation
2013  if(x2 != NULL) {
2014  double rhs = cuts[cutIdx].dotProduct(x2);
2015  double violation = 0.;
2016  violation = std::max(violation, rhs - ub[cutIdx]);
2017  violation = std::max(violation, lb[cutIdx] - rhs);
2018  if(violation < theta && oaHandler_->logLevel() > 0) {
2019  oaHandler_->message(CUT_NOT_VIOLATED_ENOUGH, oaMessages_)<<cut2rowIdx[cutIdx]<<violation<<CoinMessageEol;
2020  continue;}
2021  if(oaHandler_->logLevel() > 0)
2022  oaHandler_->message(VIOLATED_OA_CUT_GENERATED, oaMessages_)<<cut2rowIdx[cutIdx]<<violation<<CoinMessageEol;
2023  }
2024  OsiRowCut newCut;
2025  // if(lb[i]>-1e20) assert (ub[i]>1e20);
2026 
2027  if (IsValid(cutStrengthener_)) {
2028  const int& rowIdx = cut2rowIdx[cutIdx];
2029  bool retval =
2030  cutStrengthener_->ComputeCuts(cs, GetRawPtr(tminlp_),
2031  GetRawPtr(problem_), rowIdx,
2032  cuts[cutIdx], lb[cutIdx], ub[cutIdx], g[rowIdx],
2033  rowLower[rowIdx], rowUpper[rowIdx],
2034  n, x, infty);
2035  if (!retval) {
2036  (*messageHandler()) << "error in cutStrengthener_->ComputeCuts\n";
2037  //exit(-2);
2038  }
2039  }
2040  if(global) {
2041  newCut.setGloballyValidAsInteger(1);
2042  }
2043  if(lb[cutIdx] > infty) lb[cutIdx] -= rhsRelax_*std::max(fabs(lb[cutIdx]), 1.);
2044  if(ub[cutIdx] < infty) ub[cutIdx] += rhsRelax_*std::max(fabs(ub[cutIdx]), 1.);
2045  newCut.setLb(lb[cutIdx]);
2046  newCut.setUb(ub[cutIdx]);
2047  newCut.setRow(cuts[cutIdx]);
2048  if(oaHandler_->logLevel()>2){
2049  oaHandler_->print(newCut);}
2050  cs.insert(newCut);
2051  }
2052 
2053  if(getObj == 2 || (getObj && !problem_->hasLinearObjective())) { // Get the objective cuts
2054  vector<double> obj(n);
2055  problem_to_optimize_->eval_grad_f(n, x, 1,obj());
2056  double f;
2057  problem_to_optimize_->eval_f(n, x, 1, f);
2058 
2059  CoinPackedVector v;
2060  v.reserve(n);
2061  lb[nNonLinear_] = -f;
2062  ub[nNonLinear_] = -f;
2063  //double minCoeff = 1e50;
2064  for(int i = 0; i<n ; i++) {
2065  if(cleanNnz(obj[i],colLower[i], colUpper[i],
2066  -getInfinity(), 0,
2067  x[i],
2068  lb[nNonLinear_],
2069  ub[nNonLinear_],tiny_, 1e-15, infty_)) {
2070  v.insert(i,obj[i]);
2071  lb[nNonLinear_] += obj[i] * x[i];
2072  ub[nNonLinear_] += obj[i] * x[i];
2073  }
2074  }
2075  v.insert(n,-1);
2076  //Compute cut violation
2077  bool genCut = true;
2078  if(x2 != NULL) {
2079  double rhs = v.dotProduct(x2);
2080  double violation = std::max(0., rhs - ub[nNonLinear_]);
2081  if(violation < theta) genCut = false;
2082  }
2083  if(genCut) {
2084  if (IsValid(cutStrengthener_)) {
2085  lb[nNonLinear_] = -infty;
2086  bool retval =
2087  cutStrengthener_->ComputeCuts(cs, GetRawPtr(tminlp_),
2088  GetRawPtr(problem_), -1,
2089  v, lb[nNonLinear_], ub[nNonLinear_],
2090  ub[nNonLinear_], -infty, 0.,
2091  n, x, infty);
2092  if (!retval) {
2093  (*handler_)<< "error in cutStrengthener_->ComputeCuts"<<CoinMessageEol;
2094  //exit(-2);
2095  }
2096  }
2097  OsiRowCut newCut;
2098  if(global)
2099  newCut.setGloballyValidAsInteger(1);
2100  //newCut.setEffectiveness(99.99e99);
2101  newCut.setRow(v);
2102  newCut.setLb(-COIN_DBL_MAX/*Infinity*/);
2103  newCut.setUb(ub[nNonLinear_]);
2104  cs.insert(newCut);
2105  }
2106  }
2107 }
2108 
2110 void
2112  bool global){
2113  int n,m, nnz_jac_g, nnz_h_lag;
2114  TNLP::IndexStyleEnum index_style;
2115  problem_to_optimize_->get_nlp_info( n, m, nnz_jac_g, nnz_h_lag, index_style);
2116  if(jRow_ == NULL || jCol_ == NULL || jValues_ == NULL)
2117  initializeJacobianArrays();
2118  assert(jRow_ != NULL);
2119  assert(jCol_ != NULL);
2120  vector<double> g(m);
2121  const double * x = getColSolution();
2122  problem_to_optimize_->eval_jac_g(n, x, 1, m, nnz_jac_g, NULL, NULL, jValues_);
2123  problem_to_optimize_->eval_g(n,x,1,m,g());
2124  //As jacobian is stored by cols fill OsiCuts with cuts
2125  vector<double> cut(n+1,0.);
2126  vector<bool> keep(m+1,false);
2127  double lb = 0;
2128  double ub = 0;
2129 
2130  const double * rowLower = getRowLower();
2131  const double * rowUpper = getRowUpper();
2132  const double * colLower = getColLower();
2133  const double * colUpper = getColUpper();
2134  const double * duals = getRowPrice() + 2 * n;
2135  //double infty = getInfinity();
2136 
2137  for(int rowIdx = 0; rowIdx < m ; rowIdx++) {
2138  if(constTypes_[rowIdx] == TNLP::NON_LINEAR && fabs(duals[rowIdx]) > 1e-06)
2139  {
2140  const double & lam = duals[rowIdx];
2141  keep[rowIdx] = true;
2142  assert(lam < 0 || rowUpper[rowIdx] < 1e10);
2143  assert(lam > 0 || rowLower[rowIdx] > -1e10);
2144  if(lam < 0){
2145  assert(rowLower[rowIdx] > -1e10);
2146  ub += lam*(rowLower[rowIdx] -g[rowIdx]);
2147  }
2148  else {
2149  assert(rowUpper[rowIdx] < 1e10);
2150  ub += lam*(rowUpper[rowIdx] -g[rowIdx]);
2151  }
2152  }
2153  }
2154 
2155 
2156  for(int i = 0 ; i < nnz_jac_g ; i++) {
2157  const int &rowIdx = jRow_[i];
2158  if (!keep[rowIdx]) continue;
2159  const int &colIdx = jCol_[i];
2160  //"clean" coefficient
2161  const double & lam = duals[rowIdx];
2162  double coeff = lam*jValues_[i];
2163  if(cleanNnz(coeff,colLower[colIdx], colUpper[colIdx],
2164  rowLower[rowIdx], rowUpper[rowIdx], x[colIdx], lb,
2165  ub, tiny_, veryTiny_, infty_)) {
2166  cut[colIdx] += coeff;
2167  ub += coeff * x[colIdx];
2168  }
2169  }
2170 
2171  CoinPackedVector v;
2172  if(!problem_->hasLinearObjective() &&
2173  isProvenOptimal()) { // Get the objective cuts
2174  vector<double> obj(n);
2175  problem_to_optimize_->eval_grad_f(n, x, 1,obj());
2176  double f;
2177  problem_to_optimize_->eval_f(n, x, 1, f);
2178 
2179  ub = -f;
2180  //double minCoeff = 1e50;
2181  for(int i = 0; i<n ; i++) {
2182  if(cleanNnz(obj[i],colLower[i], colUpper[i], -getInfinity(), 0,
2183  x[i], lb, ub,tiny_, 1e-15, infty_)) {
2184  cut[i] += obj[i];
2185  ub += obj[i] * x[i];
2186  }
2187  }
2188  v.insert(n,-1);
2189  }
2190  for(int i = 0 ; i < n ; i++){
2191  if(fabs(cut[i])>1e-020){
2192  v.insert(i, cut[i]);
2193  }
2194  }
2195  OsiRowCut newCut;
2196  if(global)
2197  newCut.setGloballyValidAsInteger(1);
2198  newCut.setLb(-COIN_DBL_MAX/*Infinity*/);
2199  newCut.setUb(ub);
2200  newCut.setRow(v);
2201  cs.insert(newCut);
2202 }
2203 
2206 void
2208  const double * x,
2209  const double * x2, bool global)
2210 {
2211  double g;
2212  int * indices = new int[getNumCols()];
2213  double * values = new double[getNumCols()];
2214  int nnz;
2215  problem_->eval_grad_gi(getNumCols(), x, 1, rowIdx, nnz, indices, values);
2216  problem_->eval_gi(getNumCols(),x,1, rowIdx, g);
2217 
2218  CoinPackedVector cut;
2219  double lb;
2220  double ub;
2221 
2222 
2223  const double rowLower = getRowLower()[rowIdx];
2224  const double rowUpper = getRowUpper()[rowIdx];
2225  const double * colLower = getColLower();
2226  const double * colUpper = getColUpper();
2227  const double dual = (getRowPrice() + 2 * getNumCols())[rowIdx];
2228  double infty = getInfinity();
2229 
2230  if(rowLower > - infty_)
2231  lb = rowLower - g;
2232  else
2233  lb = - infty;
2234  if(rowUpper < infty_)
2235  ub = rowUpper - g;
2236  else
2237  ub = infty;
2238  if(rowLower > -infty && rowUpper < infty)
2239  {
2240  if(dual >= 0)// <= inequality
2241  lb = - infty;
2242  if(dual <= 0)// >= inequality
2243  ub = infty;
2244  }
2245 
2246  for(int i = 0 ; i < nnz; i++) {
2247  const int &colIdx = indices[i];
2248  //"clean" coefficient
2249  if(cleanNnz(values[i],colLower[colIdx], colUpper[colIdx],
2250  rowLower, rowUpper,
2251  x[colIdx],
2252  lb,
2253  ub, tiny_, veryTiny_, infty_)) {
2254  cut.insert(colIdx,values[i]);
2255  if(lb > - infty)
2256  lb += values[i] * x[colIdx];
2257  if(ub < infty)
2258  ub += values[i] * x[colIdx];
2259  }
2260  }
2261 
2262  OsiRowCut newCut;
2263 
2264  if(global) {
2265  newCut.setGloballyValidAsInteger(1);
2266  }
2267  //newCut.setEffectiveness(99.99e99);
2268  newCut.setLb(lb);
2269  newCut.setUb(ub);
2270  newCut.setRow(cut);
2271  cs.insert(newCut);
2272 
2273  delete [] indices;
2274  delete [] values;
2275 }
2276 
2277 void
2278 OsiTMINLPInterface::switchToFeasibilityProblem(size_t n,const double * x_bar,const int *inds,
2279  double a, double s, int L){
2280  if(! IsValid(feasibilityProblem_)) {
2281  throw SimpleError("No feasibility problem","getFeasibilityOuterApproximation");
2282  }
2283  feasibilityProblem_->set_use_feasibility_pump_objective(true);
2284  feasibilityProblem_->set_dist_to_point_obj(n,(const Number *) x_bar,(const Index *) inds);
2285  feasibilityProblem_->setLambda(a);
2286  feasibilityProblem_->setSigma(s);
2287  feasibilityProblem_->setNorm(L);
2288  feasibilityProblem_->set_use_cutoff_constraint(false);
2289  feasibilityProblem_->set_use_local_branching_constraint(false);
2290  problem_to_optimize_ = GetRawPtr(feasibilityProblem_);
2291  feasibility_mode_ = true;
2292 }
2293 
2294 void
2295 OsiTMINLPInterface::switchToFeasibilityProblem(size_t n,const double * x_bar,const int *inds,
2296  double rhs_local_branching_constraint){
2297  if(! IsValid(feasibilityProblem_)) {
2298  throw SimpleError("No feasibility problem","getFeasibilityOuterApproximation");
2299  }
2300  feasibilityProblem_->set_use_feasibility_pump_objective(false);
2301  feasibilityProblem_->set_dist_to_point_obj(n,(const Number *) x_bar,(const Index *) inds);
2302  feasibilityProblem_->set_use_cutoff_constraint(false);
2303  feasibilityProblem_->set_use_local_branching_constraint(true);
2304  feasibilityProblem_->set_rhs_local_branching_constraint(rhs_local_branching_constraint);
2305  problem_to_optimize_ = GetRawPtr(feasibilityProblem_);
2306  feasibility_mode_ = true;
2307 }
2308 
2309 void
2310 OsiTMINLPInterface::switchToOriginalProblem(){
2311  problem_to_optimize_ = GetRawPtr(problem_);
2312  feasibility_mode_ = false;
2313 }
2314 
2315 double
2316 OsiTMINLPInterface::solveFeasibilityProblem(size_t n,const double * x_bar,const int *inds,
2317  double a, double s, int L)
2318 {
2319  if(! IsValid(feasibilityProblem_)) {
2320  throw SimpleError("No feasibility problem","getFeasibilityOuterApproximation");
2321  }
2322  feasibilityProblem_->set_use_feasibility_pump_objective(true);
2323  feasibilityProblem_->set_dist_to_point_obj(n,(const Number *) x_bar,(const Index *) inds);
2324  feasibilityProblem_->setLambda(a);
2325  feasibilityProblem_->setSigma(s);
2326  feasibilityProblem_->setNorm(L);
2327  feasibilityProblem_->set_use_cutoff_constraint(false);
2328  feasibilityProblem_->set_use_local_branching_constraint(false);
2329  nCallOptimizeTNLP_++;
2330  totalNlpSolveTime_-=CoinCpuTime();
2331  SmartPtr<TNLPSolver> app2 = app_->clone();
2332  app2->options()->SetIntegerValue("print_level", (Index) 0);
2333  optimizationStatus_ = app2->OptimizeTNLP(GetRawPtr(feasibilityProblem_));
2334  totalNlpSolveTime_+=CoinCpuTime();
2335  hasBeenOptimized_=true;
2336  return getObjValue();
2337 }
2338 
2339 double
2340 OsiTMINLPInterface::solveFeasibilityProblem(size_t n,const double * x_bar,const int *inds,
2341  int L, double cutoff)
2342 {
2343  if(! IsValid(feasibilityProblem_)) {
2344  throw SimpleError("No feasibility problem","getFeasibilityOuterApproximation");
2345  }
2346  feasibilityProblem_->set_use_feasibility_pump_objective(true);
2347  feasibilityProblem_->set_dist_to_point_obj(n,(const Number *) x_bar,(const Index *) inds);
2348  feasibilityProblem_->setLambda(1.0);
2349  feasibilityProblem_->setSigma(0.0);
2350  feasibilityProblem_->setNorm(L);
2351  feasibilityProblem_->set_use_cutoff_constraint(true);
2352  feasibilityProblem_->set_cutoff(cutoff);
2353  feasibilityProblem_->set_use_local_branching_constraint(false);
2354  nCallOptimizeTNLP_++;
2355  totalNlpSolveTime_-=CoinCpuTime();
2356  SmartPtr<TNLPSolver> app2 = app_->clone();
2357  app2->options()->SetIntegerValue("print_level", (Index) 0);
2358  optimizationStatus_ = app2->OptimizeTNLP(GetRawPtr(feasibilityProblem_));
2359  totalNlpSolveTime_+=CoinCpuTime();
2360  hasBeenOptimized_=true;
2361  return getObjValue();
2362 }
2363 
2364 #if 0
2365 double
2366 OsiTMINLPInterface::getFeasibilityOuterApproximation(int n,const double * x_bar,const int *inds, OsiCuts &cs, bool addOnlyViolated, bool global)
2367 {
2368  double ret_val = solveFeasibilityProblem(n, x_bar, inds, 1, 0, 2);
2369  getOuterApproximation(cs, getColSolution(), 0, (addOnlyViolated? x_bar:NULL)
2370  , global);
2371  return ret_val;
2372 }
2373 #endif
2374 
2375 static bool WarnedForNonConvexOa=false;
2376 
2377 void
2379  const double * x, bool getObj
2380  )
2381 {
2382  if(IsValid(linearizer_)){
2383  linearizer_->extract(&si, x, getObj);
2384  return;
2385  }
2386  int n;
2387  int m;
2388  int nnz_jac_g;
2389  int nnz_h_lag;
2390  TNLP::IndexStyleEnum index_style;
2391  //Get problem information
2392  problem_to_optimize_->get_nlp_info( n, m, nnz_jac_g, nnz_h_lag, index_style);
2393 
2394  //if not allocated allocate spaced for stroring jacobian
2395  //if(jRow_ == NULL || jCol_ == NULL || jValues_ == NULL)
2396  initializeJacobianArrays();
2397 
2398  //get Jacobian
2399  problem_to_optimize_->eval_jac_g(n, x, 1, m, nnz_jac_g, NULL, NULL, jValues_);
2400 
2401 
2402  vector<double> g(m);
2403  problem_to_optimize_->eval_g(n, x, 1, m, g());
2404 
2405  vector<double> rowLow(m);
2406  vector<double> rowUp(m);
2407  vector<int> nonBindings(m);;//store non binding constraints (which are to be removed from OA)
2408  int numNonBindings = 0;
2409  const double * rowLower = getRowLower();
2410  const double * rowUpper = getRowUpper();
2411  vector<double> colLower(n);
2412  vector<double> colUpper(n);
2413  std::copy(getColLower(), getColLower() + n, colLower.begin());
2414  std::copy(getColUpper(), getColUpper() + n, colUpper.begin());
2415  const double * duals = getRowPrice() + 2*n;
2416  assert(m==getNumRows());
2417  double infty = si.getInfinity();
2418  for(int i = 0 ; i < m ; i++) {
2419  if(constTypes_[i] == TNLP::NON_LINEAR) {
2420  //If constraint is range not binding prepare to remove it
2421  if(rowLower[i] > -infty_ && rowUpper[i] < infty_ && fabs(duals[i]) == 0.)
2422  {
2423  nonBindings[numNonBindings++] = i;
2424  continue;
2425  }
2426  else
2427  if(rowLower[i] > - infty_){
2428  rowLow[i] = (rowLower[i] - g[i]) - 1e-07;
2429  if(! WarnedForNonConvexOa && rowUpper[i] < infty_){
2430  messageHandler()->message(WARNING_NON_CONVEX_OA, messages_)<<CoinMessageEol;
2431  WarnedForNonConvexOa = true;
2432  }
2433  }
2434  else
2435  rowLow[i] = - infty;
2436  if(rowUpper[i] < infty_)
2437  rowUp[i] = (rowUpper[i] - g[i]) + 1e-07;
2438  else
2439  rowUp[i] = infty;
2440 
2441  //If equality or ranged constraint only add one side by looking at sign of dual multiplier
2442  if(rowLower[i] > -infty_ && rowUpper[i] < infty_)
2443  {
2444  if(duals[i] >= 0.)// <= inequality
2445  rowLow[i] = - infty;
2446  if(duals[i] <= 0.)// >= inequality
2447  rowUp[i] = infty;
2448  }
2449  }
2450  else {
2451  if(rowLower[i] > -infty_){
2452  rowLow[i] = (rowLower[i]);
2453  }
2454  else
2455  rowLow[i] = - infty;
2456  if(rowUpper[i] < infty_){
2457  rowUp[i] = (rowUpper[i]);
2458  }
2459  else
2460  rowUp[i] = infty;
2461  }
2462  }
2463 
2464 
2465 
2466  //Then convert everything to a CoinPackedMatrix
2467  //Go through values, clean coefficients and fix bounds
2468  for(int i = 0 ; i < nnz_jac_g ; i++) {
2469  if(constTypes_[jRow_[i]] != TNLP::LINEAR){//For linear just copy is fine.
2470  if(//For other clean tinys
2471  cleanNnz(jValues_[i],colLower[jCol_[i]], colUpper[jCol_[i]],
2472  rowLower[jRow_[i]], rowUpper[jRow_[i]],
2473  x[jCol_[i]],
2474  rowLow[jRow_[i]],
2475  rowUp[jRow_[i]], tiny_, veryTiny_, infty_)) {
2476  if(rowLow[jRow_[i]] > - infty)
2477  rowLow[jRow_[i]] += jValues_[i] * x[jCol_ [i]];
2478  if(rowUp[jRow_[i]] < infty)
2479  rowUp[jRow_[i]] += jValues_[i] *x[jCol_[i]];
2480  }
2481  }
2482  else {
2483  //double value = jValues_[i] * x[jCol_[i]];
2484  //rowLow[jRow_[i]] += value;
2485  //rowUp[jRow_[i]] += value;
2486  }
2487  }
2488 
2489 
2490  CoinPackedMatrix mat(true, jRow_, jCol_, jValues_, nnz_jac_g);
2491  mat.setDimensions(m,n); // In case matrix was empty, this should be enough
2492 
2493  //remove non-bindings equality constraints
2494  mat.deleteRows(numNonBindings, nonBindings());
2495 
2496  int numcols=getNumCols();
2497  vector<double> obj(numcols);
2498  for(int i = 0 ; i < numcols ; i++){
2499  obj[i] = 0.;
2500  if(colLower[i] <= - infty_) colLower[i] = - infty;
2501  if(colUpper[i] >= infty_) colUpper[i] = infty;
2502  }
2503 
2504 
2505  //Relax rhs's by tiny_
2506  for(size_t i = 0 ; i < rowLow.size() ; i++){
2507  if(rowLow[i] > infty) rowLow[i] -= rhsRelax_*std::max(fabs(rowLow[i]), 1.);
2508  if(rowUp[i] < infty) rowUp[i] += rhsRelax_*std::max(fabs(rowUp[i]), 1.);
2509  }
2510 
2511  si.loadProblem(mat, colLower(), colUpper(), obj(), rowLow(), rowUp());
2512  for(int i = 0 ; i < numcols ; i++) {
2513  if(isInteger(i))
2514  si.setInteger(i);
2515  }
2516  if(getObj) {
2517  bool addObjVar = false;
2518  if(problem_->hasLinearObjective()){
2519  double zero;
2520  vector<double> x0(n,0.);
2521  problem_to_optimize_->eval_f(n, x0(), 1, zero);
2522  si.setDblParam(OsiObjOffset, -zero);
2523  //Copy the linear objective and don't create a dummy variable.
2524  problem_to_optimize_->eval_grad_f(n, x, 1,obj());
2525  si.setObjective(obj());
2526  }
2527  else {
2528  addObjVar = true;
2529  }
2530 
2531  if(addObjVar){
2532  addObjectiveFunction(si, x);
2533  }
2534  }
2535 
2536  //si.writeMpsNative("Toto.mps", NULL, NULL, 1);
2537 }
2538 
2539 void
2541  const double *x){
2542  const double * colLower = getColLower();
2543  const double * colUpper = getColUpper();
2544  int numcols = getNumCols();
2545  assert(numcols == si.getNumCols() );
2546  vector<double> obj(numcols);
2547  problem_to_optimize_->eval_grad_f(numcols, x, 1,obj());
2548  //add variable alpha
2549  //(alpha should be empty in the matrix with a coefficient of -1 and unbounded)
2550  CoinPackedVector a;
2551  si.addCol(a,-si.getInfinity(), si.getInfinity(), 1.);
2552 
2553  // Now get the objective cuts
2554  // get the gradient, pack it and add the cut
2555  double ub;
2556  problem_to_optimize_->eval_f(numcols, x, 1, ub);
2557  ub*=-1;
2558  double lb = -1e300;
2559  CoinPackedVector objCut;
2560  CoinPackedVector * v = &objCut;
2561  v->reserve(numcols+1);
2562  for(int i = 0; i<numcols ; i++) {
2563  if(si.getNumRows())
2564  {
2565  if(cleanNnz(obj[i],colLower[i], colUpper[i],
2566  -getInfinity(), 0,
2567  x[i],
2568  lb,
2569  ub, tiny_, veryTiny_, infty_)) {
2570  v->insert(i,obj[i]);
2571  lb += obj[i] * x[i];
2572  ub += obj[i] * x[i];
2573  }
2574  }
2575  else //Unconstrained problem can not put clean coefficient
2576  {
2577  if(cleanNnz(obj[i],colLower[i], colUpper[i],
2578  -getInfinity(), 0,
2579  x[i],
2580  lb,
2581  ub, 1e-03, 1e-08, infty_)) {
2582  v->insert(i,obj[i]);
2583  lb += obj[i] * x[i];
2584  ub += obj[i] * x[i];
2585  }
2586  }
2587  }
2588  v->insert(numcols,-1);
2589  si.addRow(objCut, lb, ub);
2590 }
2591 
2593 void
2594 OsiTMINLPInterface::applyRowCuts(int numberCuts, const OsiRowCut * cuts)
2595 {
2596  if(numberCuts)
2597  freeCachedRowRim();
2598  const OsiRowCut ** cutsPtrs = new const OsiRowCut*[numberCuts];
2599  for(int i = 0 ; i < numberCuts ; i++)
2600  {
2601  cutsPtrs[i] = &cuts[i];
2602  }
2603  problem_->addCuts(numberCuts, cutsPtrs);
2604  delete [] cutsPtrs;
2605 }
2606 
2607 void
2608 OsiTMINLPInterface::solveAndCheckErrors(bool warmStarted, bool throwOnFailure,
2609  const char * whereFrom)
2610 {
2611  if (BonminAbortAll == true) return;
2612  totalNlpSolveTime_-=CoinCpuTime();
2613  if(warmStarted)
2614  optimizationStatus_ = app_->ReOptimizeTNLP(GetRawPtr(problem_to_optimize_));
2615  else
2616  optimizationStatus_ = app_->OptimizeTNLP(GetRawPtr(problem_to_optimize_));
2617  totalNlpSolveTime_+=CoinCpuTime();
2618  nCallOptimizeTNLP_++;
2619  hasBeenOptimized_ = true;
2620 
2621  if(getRowCutDebugger()){
2622  //printf("On the optimal path %g < %g?\n", getObjValue(), getRowCutDebugger()->optimalValue());
2623  if(! (isProvenOptimal() && getObjValue() <= getRowCutDebugger()->optimalValue())){
2624  std::string probName;
2625  getStrParam(OsiProbName, probName);
2626  fprintf(stderr, "Problem on optimal path is infeasible!\n");
2627  throw newUnsolvedError(app_->errorCode(), problem_, probName);
2628  }
2629  }
2630 
2631  //Options should have been printed if not done already turn off Ipopt output
2632  if(!hasPrintedOptions) {
2633  hasPrintedOptions = 1;
2634  //app_->Options()->SetIntegerValue("print_level",0, true, true);
2635  app_->options()->SetStringValue("print_user_options","no", false, true);
2636  }
2637 
2638  bool otherDisagree = false ;
2639  if(!app_->isRecoverable(optimizationStatus_))//Solver failed and the error can not be recovered, throw it
2640  {
2641  std::string probName;
2642  getStrParam(OsiProbName, probName);
2643  throw newUnsolvedError(app_->errorCode(), problem_, probName);
2644  }
2645  else if(testOthers_ && !app_->isError(optimizationStatus_)){
2646  Ipopt::SmartPtr<TMINLP2TNLP> problem_copy = problem_->clone();
2647  //Try other solvers and see if they agree
2648  int f =1;
2649  for(std::list<Ipopt::SmartPtr<TNLPSolver> >::iterator i = debug_apps_.begin();
2650  i != debug_apps_.end() ; i++){
2651  TNLPSolver::ReturnStatus otherStatus = (*i)->OptimizeTNLP(GetRawPtr(problem_copy));
2652  messageHandler()->message(LOG_LINE, messages_)
2653  <<'d'<<f++<<statusAsString(otherStatus)<<problem_copy->obj_value()
2654  <<(*i)->IterationCount()<<(*i)->CPUTime()<<"retry with "+(*i)->solverName()<<CoinMessageEol;
2655  if(!(*i)->isError(otherStatus)){
2656  CoinRelFltEq eq(1e-05);
2657  if(otherStatus != optimizationStatus_){
2658  otherDisagree = true;
2659  messageHandler()->message(SOLVER_DISAGREE_STATUS, messages_)
2660  <<app_->solverName()<<statusAsString()
2661  <<(*i)->solverName()<<statusAsString(otherStatus)<<CoinMessageEol;
2662  }
2663  else if(isProvenOptimal() && !eq(problem_->obj_value(),problem_copy->obj_value()))
2664  {
2665  otherDisagree = true;
2666  messageHandler()->message(SOLVER_DISAGREE_VALUE, messages_)
2667  <<app_->solverName()<<problem_->obj_value()
2668  <<(*i)->solverName()<<problem_copy->obj_value()<<CoinMessageEol;
2669  }
2670  }
2671  }
2672  }
2673  else if(app_->isError(optimizationStatus_) && ! debug_apps_.empty()){
2674  int f =1;
2675  for(std::list<Ipopt::SmartPtr<TNLPSolver> >::iterator i = debug_apps_.begin();
2676  i != debug_apps_.end() && app_->isError(optimizationStatus_) ; i++){
2677  optimizationStatus_ = (*i)->OptimizeTNLP(GetRawPtr(problem_));
2678  messageHandler()->message(LOG_LINE, messages_)
2679  <<'d'<<f++<<statusAsString(optimizationStatus_)<<problem_->obj_value()
2680  <<(*i)->IterationCount()<<(*i)->CPUTime()<<"retry with "+(*i)->solverName()<<CoinMessageEol;
2681  }
2682  }
2683  try{
2684  totalIterations_ += app_->IterationCount();
2685  }
2686  catch(SimpleError &E)
2687  {
2688  if (throwOnFailure)//something failed throw
2689  {
2690  throw SimpleError("No statistics available from Ipopt",whereFrom);
2691  }
2692  else {
2693  return;
2694  }
2695  }
2696  if(problem_->hasUpperBoundingObjective()){//Check if solution is integer and recompute objective value using alternative objective function
2697  const double * sol = getColSolution();
2698  bool integerSol = true;
2699  double intTol = 1e-08;
2700  if(objects()){
2701  int nObjects = numberObjects();
2702  OsiObject ** object = objects();
2703  for(int i = 0 ; i< nObjects ; i++){
2704  int dummy;
2705  if(object[i]->infeasibility(this,dummy) > intTol)
2706  {
2707  integerSol=false;
2708  break;
2709  }
2710  }
2711  }
2712  else{//Only works for integer constraints
2713  int numcols = getNumCols();
2714  for(int i = 0 ; i < numcols ; i++){
2715  if(isInteger(i) || isBinary(i)){
2716  if(fabs(sol[i] - floor(sol[i]+0.5)) > intTol){
2717  integerSol = false;
2718  break;
2719  }
2720  }
2721  }
2722  }
2723  if(integerSol&&isProvenOptimal()){
2724  double help= problem_->evaluateUpperBoundingFunction(sol);
2725 
2726 
2727  OsiAuxInfo * auxInfo = getAuxiliaryInfo();
2728  Bonmin::AuxInfo * bonInfo = dynamic_cast<Bonmin::AuxInfo *>(auxInfo);
2729  if(bonInfo!=0)
2730  {
2731 
2732  if(help<bonInfo->bestObj2())
2733  {
2734  bonInfo->setBestObj2(help);
2735  bonInfo->setBestSolution2(getNumCols(), const_cast<double *>(getColSolution()));
2736 
2737  messageHandler()->message(ALTERNATE_OBJECTIVE, messages_)
2738  <<help<<CoinMessageEol;
2739  }
2740  }
2741  else {
2742  printf("\nWARNING: the algorithm selected does not consider the second objective function\n");
2743  }
2744  }
2745  }
2746 
2747  messageHandler()->message(IPOPT_SUMMARY, messages_)
2748  <<whereFrom<<optimizationStatus_<<app_->IterationCount()<<app_->CPUTime()<<CoinMessageEol;
2749 
2750  if((nCallOptimizeTNLP_ % 20) == 1)
2751  messageHandler()->message(LOG_HEAD, messages_)<<CoinMessageEol;
2752 
2753 
2754  if ( (numIterationSuspect_ >= 0 && (getIterationCount()>numIterationSuspect_ || isAbandoned())) ||
2755  ( otherDisagree )){
2756  messageHandler()->message(SUSPECT_PROBLEM,
2757  messages_)<<nCallOptimizeTNLP_<<CoinMessageEol;
2758  std::string subProbName;
2759  getStrParam(OsiProbName, subProbName);
2760  std::ostringstream os;
2761  os<<"_"<<nCallOptimizeTNLP_;
2762  subProbName+=os.str();
2763  problem_->outputDiffs(subProbName, NULL/*getVarNames()*/);
2764  }
2765 
2766 }
2767 
2769 // Solve Methods //
2772 {
2773  initialSolve("");
2774 }
2775 
2777 // Solve Methods //
2779 void OsiTMINLPInterface::initialSolve(const char * whereFrom)
2780 {
2781  assert(IsValid(app_));
2782  assert(IsValid(problem_));
2783 
2784  if (BonminAbortAll == true) return;
2785  // Discard warmstart_ if we had one
2786  delete warmstart_;
2787  warmstart_ = NULL;
2788 
2789  if(!hasPrintedOptions) {
2790  int printOptions;
2791  app_->options()->GetEnumValue("print_user_options",printOptions,app_->prefix());
2792  if(printOptions)
2793  app_->options()->SetStringValue("print_user_options","yes",true,true);
2794  }
2795  if(warmStartMode_ >= Optimum)
2796  app_->disableWarmStart();
2797  solveAndCheckErrors(0,1,"initialSolve");
2798 
2799  //Options should have been printed if not done already turn off Ipopt output
2800  if(!hasPrintedOptions) {
2801  hasPrintedOptions = 1;
2802  app_->options()->SetStringValue("print_user_options","no");
2803  app_->options()->SetIntegerValue("print_level",0);
2804  }
2805 
2806  messageHandler()->message(LOG_LINE, messages_)<<' '<<nCallOptimizeTNLP_
2807  <<statusAsString()
2808  <<getObjValue()
2809  <<app_->IterationCount()
2810  <<app_->CPUTime()
2811  <<whereFrom<<CoinMessageEol;
2812 
2813  if(BonminAbortAll){
2814  return;
2815  }
2816  int numRetry = firstSolve_ ? numRetryInitial_ : numRetryResolve_;
2817  if(isAbandoned() ||
2818  ( isProvenPrimalInfeasible() && getObjValue() < infeasibility_epsilon_)) {
2819  resolveForRobustness(numRetryUnsolved_);
2820  }
2821  else if(numRetry)
2822  {
2823  resolveForCost(numRetry, numRetryInitial_ > 0);
2825  numRetryInitial_ = 0;
2826  }
2827  firstSolve_ = false;
2828 
2829  // if warmstart_ is not empty then had to use resolveFor... and that created
2830  // the warmstart at the end, and we have nothing to do here. Otherwise...
2831  if (! warmstart_ && ! isAbandoned()) {
2832  if (warmStartMode_ >= Optimum) {
2833  warmstart_ = app_->getWarmStart(problem_);
2834  }
2835  }
2836 }
2837 
2839 void
2841  resolve("");
2842 }
2845 void
2846 OsiTMINLPInterface::resolve(const char * whereFrom)
2847 {
2848  assert(IsValid(app_));
2849  assert(IsValid(problem_));
2850  if (BonminAbortAll == true) return;
2851  int has_warmstart = warmstart_ == NULL ? 0 : 1;
2852  if(warmstart_ == NULL) has_warmstart = 0;
2853  else if(!app_->warmStartIsValid(warmstart_)) has_warmstart = 1;
2854  else has_warmstart = 2;
2855  if (has_warmstart < 2) {
2856  // empty (or unrecognized) warmstart
2857  initialSolve(whereFrom);
2858  return;
2859  }
2860  app_->setWarmStart(warmstart_, problem_);
2861  delete warmstart_;
2862  warmstart_ = NULL;
2863 
2864  if (INT_BIAS > 0.) {
2865  app_->options()->SetStringValue("warm_start_same_structure", "yes");
2866  }
2867  else {
2868  app_->options()->SetStringValue("warm_start_same_structure", "no");
2869  }
2870 
2871  if(problem_->duals_init() != NULL)
2872  app_->enableWarmStart();
2873  else app_->disableWarmStart();
2874  solveAndCheckErrors(1,1,"resolve");
2875 
2876  messageHandler()->message(LOG_LINE, messages_)<<' '<<nCallOptimizeTNLP_
2877  <<statusAsString()
2878  <<getObjValue()
2879  <<app_->IterationCount()
2880  <<app_->CPUTime()
2881  <<whereFrom
2882  <<"totot"
2883  <<CoinMessageEol;
2884 
2885  if(isAbandoned() ||
2886  ( (getObjValue() < 1e-06) && isProvenPrimalInfeasible())) {
2887  resolveForRobustness(numRetryUnsolved_);
2888  }
2889  else if(numRetryResolve_ ||
2890  (numRetryInfeasibles_ && isProvenPrimalInfeasible() ))
2891  resolveForCost(std::max(numRetryResolve_, numRetryInfeasibles_), 0);
2892 
2893  // if warmstart_ is not empty then had to use resolveFor... and that created
2894  // the warmstart at the end, and we have nothing to do here. Otherwise...
2895  if (! warmstart_ && ! isAbandoned()) {
2896  if (warmStartMode_ >= Optimum) {
2897  warmstart_ = app_->getWarmStart(problem_);
2898  }
2899  }
2900 }
2901 
2902 
2904 // Methods returning info on how the solution process terminated //
2908 {
2909  if (pretendSucceededNext_)
2910  return false;
2911  pretendSucceededNext_ = false;
2912  return (
2913  (optimizationStatus_==TNLPSolver::iterationLimit)||
2914  (optimizationStatus_==TNLPSolver::computationError)||
2915  (optimizationStatus_==TNLPSolver::illDefinedProblem)||
2916  (optimizationStatus_==TNLPSolver::illegalOption)||
2917  (optimizationStatus_==TNLPSolver::externalException)|
2918  (optimizationStatus_==TNLPSolver::exception)
2919  );
2920 }
2921 
2924 {
2925  return (optimizationStatus_==TNLPSolver::solvedOptimal) ||
2926  (optimizationStatus_==TNLPSolver::solvedOptimalTol);
2927 }
2930 {
2931  return (optimizationStatus_ == TNLPSolver::provenInfeasible);
2932 }
2935 {
2936  return (optimizationStatus_ == TNLPSolver::unbounded);
2937 }
2940 {
2941  (*handler_)<<"Warning : isPrimalObjectiveLimitReached not implemented yet"<<CoinMessageEol;
2942  return 0;
2943 }
2946 {
2947  // (*messageHandler_)<<"Warning : isDualObjectiveLimitReached not implemented yet"<<CoinMessageEol;
2948  return (optimizationStatus_==TNLPSolver::unbounded);
2949 
2950 }
2953 {
2954  return (optimizationStatus_==TNLPSolver::iterationLimit);
2955 }
2956 
2957 void
2958 OsiTMINLPInterface::extractInterfaceParams()
2959 {
2960  if (IsValid(app_)) {
2961  int logLevel;
2962  app_->options()->GetIntegerValue("nlp_log_level", logLevel,app_->prefix());
2963  messageHandler()->setLogLevel(logLevel);
2964 
2965 #ifdef COIN_HAS_FILTERSQP
2966  FilterSolver * filter = dynamic_cast<FilterSolver *>(GetRawPtr(app_));
2967 
2968  bool is_given =
2969 #endif
2970  app_->options()->GetNumericValue("max_random_point_radius",maxRandomRadius_,app_->prefix());
2971 
2972 #ifdef COIN_HAS_FILTERSQP
2973  if(filter && !is_given){
2974  // overwriting default for filter
2975  maxRandomRadius_ = 10.;
2976  }
2977 #endif
2978 
2979  int oaCgLogLevel = 0;
2980  app_->options()->GetIntegerValue("oa_cuts_log_level", oaCgLogLevel,app_->prefix());
2981  oaHandler_->setLogLevel(oaCgLogLevel);
2982 
2983  int buffy;
2984  app_->options()->GetEnumValue("warm_start", buffy, app_->prefix());
2985  warmStartMode_ = (WarmStartModes) buffy;
2986 
2987  app_->options()->GetIntegerValue("num_retry_unsolved_random_point", numRetryUnsolved_,app_->prefix());
2988  app_->options()->GetIntegerValue("num_resolve_at_root", numRetryInitial_,app_->prefix());
2989  app_->options()->GetIntegerValue("num_resolve_at_node", numRetryResolve_,app_->prefix());
2990  app_->options()->GetIntegerValue("num_resolve_at_infeasibles", numRetryInfeasibles_,app_->prefix());
2991  app_->options()->GetIntegerValue("num_iterations_suspect", numIterationSuspect_,app_->prefix());
2992  app_->options()->GetEnumValue("nlp_failure_behavior",pretendFailIsInfeasible_,app_->prefix());
2993  app_->options()->GetNumericValue
2994  ("warm_start_bound_frac" ,pushValue_,app_->prefix());
2995  app_->options()->GetNumericValue("tiny_element",tiny_,app_->prefix());
2996  app_->options()->GetNumericValue("very_tiny_element",veryTiny_,app_->prefix());
2997  app_->options()->GetNumericValue("oa_rhs_relax",rhsRelax_,app_->prefix());
2998  app_->options()->GetNumericValue("random_point_perturbation_interval",max_perturbation_,app_->prefix());
2999  app_->options()->GetEnumValue("random_point_type",randomGenerationType_,app_->prefix());
3000  int cut_strengthening_type;
3001  app_->options()->GetEnumValue("cut_strengthening_type", cut_strengthening_type,app_->prefix());
3002  double lo_inf, up_inf;
3003  app_->options()->GetNumericValue("nlp_lower_bound_inf",lo_inf, app_->prefix());
3004  app_->options()->GetNumericValue("nlp_upper_bound_inf",up_inf, app_->prefix());
3005  infty_ = std::min(fabs(lo_inf), fabs(up_inf));
3006 
3007 #ifdef COIN_HAS_FILTERSQP
3008  is_given =
3009 #endif
3010  app_->options()->GetNumericValue("resolve_on_small_infeasibility", infeasibility_epsilon_, app_->prefix());
3011 
3012 #ifdef COIN_HAS_FILTERSQP
3013  if(filter && !is_given){
3014  // overwriting default for filter
3015  infeasibility_epsilon_ = 1e-06;
3016  std::string o_name = app_->prefix();
3017  o_name += "resolve_on_small_infeasibility";
3018  app_->options()->SetNumericValue(o_name.c_str(), infeasibility_epsilon_, true, true);
3019  }
3020 #endif
3021  if (cut_strengthening_type != CS_None) {
3022  // TNLP solver to be used in the cut strengthener
3023  cutStrengthener_ = new CutStrengthener(app_->clone(), app_->options());
3024  }
3025  }
3026 }
3027 
3028 void
3029 OsiTMINLPInterface::SetStrongBrachingSolver(SmartPtr<StrongBranchingSolver> strong_branching_solver)
3030 {
3031  strong_branching_solver_ = strong_branching_solver;
3032 }
3033 
3034  //#define STRONG_COMPARE
3035 #ifdef STRONG_COMPARE
3036  static double objorig;
3037 #endif
3038 
3039 void
3040 OsiTMINLPInterface::markHotStart()
3041 {
3042  if (IsValid(strong_branching_solver_)) {
3043 #ifdef STRONG_COMPARE
3044  // AWDEBUG
3045  OsiSolverInterface::markHotStart();
3046  objorig = getObjValue();
3047 #endif
3048  optimizationStatusBeforeHotStart_ = optimizationStatus_;
3049  strong_branching_solver_->markHotStart(this);
3050  }
3051  else {
3052  // Default Implementation
3053  OsiSolverInterface::markHotStart();
3054  }
3055 }
3056 
3057 void
3058 OsiTMINLPInterface::solveFromHotStart()
3059 {
3060  if (IsValid(strong_branching_solver_)) {
3061 #ifdef STRONG_COMPARE
3062  // AWDEBUG
3063  OsiSolverInterface::solveFromHotStart();
3064  double obj_nlp = getObjValue() - objorig;
3065 #endif
3066  optimizationStatus_ = strong_branching_solver_->solveFromHotStart(this);
3067  hasBeenOptimized_ = true;
3068 #ifdef STRONG_COMPARE
3069  double obj_other = getObjValue() - objorig;
3070  printf("AWDEBUG: Strong Branching results: NLP = %15.8e Other = %15.8e\n",
3071  obj_nlp, obj_other);
3072 #endif
3073  }
3074  else {
3075  // Default Implementation
3076  OsiSolverInterface::solveFromHotStart();
3077  }
3078 }
3079 
3080 void
3081 OsiTMINLPInterface::unmarkHotStart()
3082 {
3083  if (IsValid(strong_branching_solver_)) {
3084 #ifdef STRONG_COMPARE
3085  // AWDEBUG
3086  OsiSolverInterface::unmarkHotStart();
3087 #endif
3088  strong_branching_solver_->unmarkHotStart(this);
3089  optimizationStatus_ = optimizationStatusBeforeHotStart_;
3090  }
3091  else {
3092  // Default Implementation
3093  OsiSolverInterface::unmarkHotStart();
3094  }
3095 }
3096 
3098 {
3099  const int n = getNumCols();
3100  delete [] obj_;
3101  obj_ = NULL;
3102  obj_ = new double[n];
3103 
3104  bool new_x = true;
3105  const double* x_sol = problem_->x_sol();
3106  bool retval = problem_->eval_grad_f(n, x_sol, new_x, obj_);
3107 
3108  if (!retval) {
3109  // Let's see if that happens - it will cause a crash
3110  fprintf(stderr, "ERROR WHILE EVALUATING GRAD_F in OsiTMINLPInterface::getObjCoefficients()\n");
3111  delete [] obj_;
3112  obj_ = NULL;
3113  }
3114 
3115  return obj_;
3116 }
3117 
3119  void
3121  problem_ = tminlp2tnlp;
3122  problem_to_optimize_ = GetRawPtr(problem_);
3123  feasibilityProblem_->use(GetRawPtr(tminlp2tnlp));}
3124 
3125 }
double * values
bool getIntParam(OsiIntParam key, int &value) const
TNLPSolver::UnsolvedError * newUnsolvedError(int num, Ipopt::SmartPtr< TMINLP2TNLP > problem, std::string name)
virtual double getInfinity() const
Get solver&#39;s value for infinity.
virtual bool isAbandoned() const
Are there a numerical difficulties?
virtual void setRowLower(int elementIndex, double elementValue)
Set a single row lower bound.
void getOuterApproximation(OsiCuts &cs, int getObj, const double *x2, bool global)
Get the outer approximation constraints at the current optimal point.
void resetStartingPoint()
reset the starting point to original one.
void setBestSolution2(int n, double *d)
Definition: BonAuxInfos.hpp:86
Solver
Solvers for solving nonlinear programs.
virtual const double * getColLower() const
Get pointer to array[getNumCols()] of column lower bounds.
filterSQP Sequential Quadratic Programming algorithm.
ULong L
Definition: OSdtoa.cpp:1816
pos
position where the operator should be printed when printing the expression
ULong x2
Definition: OSdtoa.cpp:1776
virtual bool isPrimalObjectiveLimitReached() const
Is the given primal objective limit reached?
Use all solvers.
const TMINLP2TNLP * problem() const
get pointer to the TMINLP2TNLP adapter
const Ipopt::SmartPtr< Ipopt::OptionsList > options() const
Retrieve OsiTMINLPApplication option list.
This is class provides an Osi interface for a Mixed Integer Linear Program expressed as a TMINLP (so ...
virtual bool isInteger(int columnNumber) const
Return true if column is integer.
void fint fint fint real * a
OsiSolverInterface * clone(bool copyData=true) const
Virtual copy constructor.
bool IsValid(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:465
int std_m(int n)
Definition: BonMsgUtils.hpp:10
virtual int getNumRows() const
Get number of rows.
Head of &quot;civilized&quot; log.
void use(Ipopt::SmartPtr< TMINLP2TNLP > tminlp2tnlp)
Sets the TMINLP2TNLP to be used by the interface.
virtual CoinWarmStart * getEmptyWarmStart() const
Get an empty warm start object.
void setBestObj2(double o)
Set an alternate objective value.
Definition: BonAuxInfos.hpp:82
virtual void setContinuous(int index)
Set the index-th variable to be a continuous variable.
virtual void resolveForCost(int numretry, bool keepWs)
Resolve the problem with different random starting points to try to find a better solution (only make...
Different solver gives different status for problem.
The IpoptSolver class solves problems using Ipopt.
virtual int getNumCols() const
Get number of columns.
virtual bool isProvenOptimal() const
Is optimality proven?
virtual void initialSolve()
Solve initial continuous relaxation.
virtual double getObjValue() const
Get objective function value (can&#39;t use default)
void fint fint fint real fint real real real real * f
virtual const double * getObjCoefficients() const
This returns the objective function gradient at the current point.
SimpleReferenced< X > * make_referenced(X other)
Definition: BonTypes.hpp:87
double solveFeasibilityProblem(size_t n, const double *x_bar, const int *ind, double a, double s, int L)
Given a point x_bar this solves the problem of finding the point which minimize a convex combination ...
virtual bool isProvenPrimalInfeasible() const
Is primal infeasiblity proven?
virtual const double * getColSolution() const
Get pointer to array[getNumCols()] of primal solution vector.
void fint fint fint real fint real real real real real real real real real * e
const double * GetPerturbationArray() const
Method for getting the array for the perturbation radii in order to use the values.
Definition: BonTMINLP.hpp:176
Error class to throw exceptions from OsiTMINLPInterface.
ULong * x0
Definition: OSdtoa.cpp:1776
#define INT_BIAS
virtual void setColUpper(int elementIndex, double elementValue)
Set a single column upper bound.
bool getStrParam(OsiStrParam key, std::string &value) const
void getBendersCut(OsiCuts &cs, bool global)
Get a benders cut from solution.
virtual void getConstraintOuterApproximation(OsiCuts &cs, int constraintNumber, const double *x, const double *x2, bool global)
Get the outer approximation at provided point for given constraint.
virtual void resolve()
Resolve the continuous relaxation after problem modification.
void readOptionFile(const std::string &fileName)
Read parameter file.
void setSolver(Ipopt::SmartPtr< TNLPSolver > app)
Set the solver to be used by interface.
#define EPSILON
virtual void setRowUpper(int elementIndex, double elementValue)
Set a single row upper bound.
virtual void setColSolution(const double *colsol)
Set the primal solution variable values Set the values for the starting point.
virtual void setRowType(int index, char sense, double rightHandSide, double range)
Set the type of a single row.
virtual bool isFreeBinary(int columnNumber) const
Return true if column is binary and not fixed at either bound.
bool setStrParam(OsiStrParam key, const std::string &value)
Found a better solution with random values.
virtual const double * getRowUpper() const
Get pointer to array[getNumRows()] of row upper bounds.
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real * s
virtual bool isIterationLimitReached() const
Iteration limit reached?
virtual const double * getReducedCost() const
Get a pointer to array[getNumCols()] of reduced costs.
virtual const double * getRightHandSide() const
Get pointer to array[getNumRows()] of rows right-hand sides.
virtual bool isProvenDualInfeasible() const
Is dual infeasiblity proven?
static int
Definition: OSdtoa.cpp:2173
virtual bool isDualObjectiveLimitReached() const
Is the given dual objective limit reached?
static bool WarnedForNonConvexOa
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:452
void fint fint fint real fint real real real real real real real real real fint real fint fint fint real * ws
virtual bool isContinuous(int colNumber) const
Return true if column is continuous.
virtual const char * getRowSense() const
Get pointer to array[getNumRows()] of row constraint senses.
virtual int getIterationCount() const
Get how many iterations it took to solve the problem (whatever &quot;iteration&quot; mean to the solver...
virtual bool isIntegerNonBinary(int columnNumber) const
Return true if column is general integer.
Recomputed integer feasible with alternate objective function.
void setModel(Ipopt::SmartPtr< TMINLP > tminlp)
Set the model to be solved by interface.
ReturnStatus
Standard return statuses for a solver.
standard line (retry solving) of log.
virtual void setObjSense(double s)
Set the objective function sense (disabled).
virtual const double * getRowRange() const
Get pointer to array[getNumRows()] of row ranges.
void setNewCutoffDecr(double d)
Are there a numerical difficulties?
virtual CoinWarmStart * getWarmStart() const
Get warmstarting information.
static bool cleanNnz(double &value, double colLower, double colUpper, double rowLower, double rowUpper, double colsol, double &lb, double &ub, double tiny, double veryTiny)
Ipopt::SmartPtr< const Ipopt::OptionsList > options() const
Get the options (for getting their values).
#define ADD_MSG(Id, Type, Level, MSG)
Definition: BonMsgUtils.hpp:7
Warn that there are equality or ranged constraints and OA may works bad.
virtual const double * getRowPrice() const
Get pointer to array[getNumRows()] of dual prices.
virtual ~OsiTMINLPInterface()
Destructor.
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real real fint real fint real * lam
virtual void setRowPrice(const double *rowprice)
Set dual solution variable values.
static void register_OA_options(SmartPtr< RegisteredOptions > roptions)
bool BonminAbortAll
Definition: BonCbc.cpp:37
virtual const double * getRowActivity() const
Get pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vecto...
virtual const double * getColUpper() const
Get pointer to array[getNumCols()] of column upper bounds.
int warn_m(int n)
Definition: BonMsgUtils.hpp:11
virtual void addObjectiveFunction(OsiSolverInterface &si, const double *x)
Add constraint corresponding to objective function.
virtual void setInteger(int index)
Set the index-th variable to be an integer variable.
void fint fint fint real fint real real real real real real * g
virtual const double * getRowLower() const
Get pointer to array[getNumRows()] of row lower bounds.
bool setIntParam(OsiIntParam key, int value)
virtual void resolveForRobustness(int numretry)
Method to be called when a problem has failed to be solved.
void randomStartingPoint()
Get an empty warm start object.
Trying to access non-existent TNLPSolver.
virtual bool isBinary(int columnNumber) const
Return true if column is binary.
static char prefix[100]
Definition: BM_lp.cpp:26
OsiTMINLPInterface & operator=(const OsiTMINLPInterface &rhs)
Assignment operator.
bool setDblParam(OsiDblParam key, double value)
void fint * m
virtual bool setWarmStart(const CoinWarmStart *warmstart)
Set warmstarting information.
int nnz
ATTENTION: Filter expect the jacobian to be ordered by row.
This is an adapter class that converts a TMINLP to a TNLP to be solved by Ipopt.
static void register_general_options(SmartPtr< RegisteredOptions > roptions)
Register options.
Class to store perturbation radii for variables in the model.
Definition: BonTMINLP.hpp:157
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.
virtual void setColLower(int elementIndex, double elementValue)
Set a single column lower bound.
OsiTMINLPInterface()
Default Constructor.
const OsiSolverInterface::OsiNameVec & getVarNames()
get name of variables
This is an adapter class to convert an NLP to a Feasibility Pump NLP by changing the objective functi...
Subproblem not solve with warm start but solved with random point.
void fint * n
virtual void extractLinearRelaxation(OsiSolverInterface &si, const double *x, bool getObj=1)
Extract a linear relaxation of the MINLP.
Bonmin class for passing info between components of branch-and-cuts.
Definition: BonAuxInfos.hpp:23
Output summary statistics on Ipopt solution.
real c
Problem not solved with warm start but solved without.
Different solver gives different optimal value for problem.
bool getDblParam(OsiDblParam key, double &value) const
real infty
void fint fint fint real fint real * x