OSBonminSolver.cpp
Go to the documentation of this file.
1 
18 #include <iostream>
19 
20 
21 #include "OSBonminSolver.h"
22 #include "OSDataStructures.h"
23 #include "OSParameters.h"
24 #include "OSCommonUtil.h"
25 #include "OSMathUtil.h"
26 
28 #include "BonCbc.hpp"
29 
30 #include "CoinTime.hpp"
31 
32 using std::cout;
33 using std::endl;
34 using std::ostringstream;
35 
36 
38  osrlwriter = new OSrLWriter();
39  osresult = new OSResult();
40  m_osilreader = NULL;
41  m_osolreader = NULL;
42  bonminErrorMsg = "";
43 
44 }
45 
47  #ifdef DEBUG
48  cout << "inside BonminSolver destructor" << endl;
49  #endif
50  if(m_osilreader != NULL) delete m_osilreader;
51  m_osilreader = NULL;
52  if(m_osolreader != NULL) delete m_osolreader;
53  m_osolreader = NULL;
54  delete osresult;
55  osresult = NULL;
56  delete osrlwriter;
57  osrlwriter = NULL;
58  //delete osinstance;
59  //osinstance = NULL;
60  #ifdef DEBUG
61  cout << "leaving BonminSolver destructor" << endl;
62  #endif
63 }
64 
65 
66 
67 
68 
69 
70 bool BonminProblem::get_variables_types(Index n, VariableType* var_types){
71  int i = 0;
72  char *varType;
73  varType = osinstance->getVariableTypes();
75  for(i = 0; i < n; i++){
76  if( varType[i] == 'B') {
77  var_types[i] = BINARY;
78  }
79  else{
80  if( varType[i] == 'I') {
81  var_types[i] = INTEGER;
82  }
83  else{
84  var_types[i] = CONTINUOUS;
85  }
86  }
87  }
88  return true;
89 }
90 
91 bool BonminProblem::get_variables_linearity(Index n, Ipopt::TNLP::LinearityType* var_types){
92 
93 
94 
95  std::cout << "Initialize Nonlinear Structures" << std::endl;
96  try{
98  }
99  catch(const ErrorClass& eclass){
100  bonminErrorMsg = eclass.errormsg;
101  throw;
102  }
108  std::map<int, int> varIndexMap;
109  std::map<int, int>::iterator posVarIndexMap;
111  /* first make all continuous */
112 
113  int i;
114 
115  for(i = 0; i < n; i++){
116  var_types[ i] = Ipopt::TNLP::LINEAR;
117  }
122  for(posVarIndexMap = varIndexMap.begin(); posVarIndexMap != varIndexMap.end(); ++posVarIndexMap){
123  std::cout << "Variable Index = " << posVarIndexMap->first << std::endl ;
124  var_types[ posVarIndexMap->first] = Ipopt::TNLP::NON_LINEAR;
125  }
126  std::cout << "Number of nonlinear variables = " << varIndexMap.size() << std::endl;
127 
128  return true;
129 }
130 
131 bool BonminProblem::get_constraints_linearity(Index m, Ipopt::TNLP::LinearityType* const_types){
132 
133  int i;
134 
135  for(i = 0; i < m; i++){
136  const_types[ i] = Ipopt::TNLP::LINEAR;
137  }
138 
139 
141 
142 
143 
144  for(i = 0; i < mm; i++){
146  std::cout << osinstance->getNonlinearExpressionTreeModIndexes()[ i] << std::endl;
147  const_types[ osinstance->getNonlinearExpressionTreeModIndexes()[ i] ] = Ipopt::TNLP::NON_LINEAR;
148 
149  }
150 
151  }
152 
153  return true;
154 }
155 
156 // returns the size of the problem
157 bool BonminProblem::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
158  Index& nnz_h_lag, TNLP::IndexStyleEnum& index_style)
159 {
160  if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Bonmin NEEDS AN OBJECTIVE FUNCTION");
161  // number of variables
163  // number of constraints
165  cout << "Bonmin number variables !!!!!!!!!!!!!!!!!!!!!!!!!!!" << n << endl;
166  cout << "Bonmin number constraints !!!!!!!!!!!!!!!!!!!!!!!!!!!" << m << endl;
167  try{
169  }
170  catch(const ErrorClass& eclass){
171  bonminErrorMsg = eclass.errormsg;
172  throw;
173  }
174  // use the OS Expression tree for function evaluations instead of CppAD
176  //std::cout << "Call sparse jacobian" << std::endl;
177  SparseJacobianMatrix *sparseJacobian = NULL;
178  try{
179  sparseJacobian = osinstance->getJacobianSparsityPattern();
180  }
181  catch(const ErrorClass& eclass){
182  bonminErrorMsg = eclass.errormsg;
183  throw;
184  }
185  //std::cout << "Done calling sparse jacobian" << std::endl;
186  nnz_jac_g = sparseJacobian->valueSize;
187  cout << "nnz_jac_g !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_jac_g << endl;
188  // nonzeros in upper hessian
189 
191  cout << "This is a linear program" << endl;
192  nnz_h_lag = 0;
193  }
194  else{
195  //std::cout << "Get Lagrangian Hessian Sparsity Pattern " << std::endl;
197  //std::cout << "Done Getting Lagrangian Hessian Sparsity Pattern " << std::endl;
198  nnz_h_lag = sparseHessian->hessDimension;
199  }
200  cout << "print nnz_h_lag (OSBonminSolver.cpp)" << endl;
201  cout << "nnz_h_lag !!!!!!!!!!!!!!!!!!!!!!!!!!!" << nnz_h_lag << endl;
202  cout << "set index_style (OSBonminSolver.cpp)" << endl;
203  // use the C style indexing (0-based)
204  index_style = TNLP::C_STYLE;
205  cout << "return from get_nlp_info (OSBonminSolver.cpp)" << endl;
206 
208 
209  return true;
210 }//get_nlp_info
211 
212 
213 bool BonminProblem::get_bounds_info(Index n, Number* x_l, Number* x_u,
214  Index m, Number* g_l, Number* g_u){
215  int i;
216 
217  double * mdVarLB = osinstance->getVariableLowerBounds();
218  //std::cout << "GET BOUNDS INFORMATION FOR BONMIN !!!!!!!!!!!!!!!!!" << std::endl;
219  // variables upper bounds
220  double * mdVarUB = osinstance->getVariableUpperBounds();
221 
222  for(i = 0; i < n; i++){
223  x_l[ i] = mdVarLB[ i];
224  x_u[ i] = mdVarUB[ i];
225  cout << "x_l !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_l[i] << endl;
226  cout << "x_u !!!!!!!!!!!!!!!!!!!!!!!!!!!" << x_u[i] << endl;
227  }
228  // Bonmin interprets any number greater than nlp_upper_bound_inf as
229  // infinity. The default value of nlp_upper_bound_inf and nlp_lower_bound_inf
230  // is 1e19 and can be changed through bonmin options.
231  // e.g. g_u[0] = 2e19;
232 
233  //constraint lower bounds
234  double * mdConLB = osinstance->getConstraintLowerBounds();
235  //constraint upper bounds
236  double * mdConUB = osinstance->getConstraintUpperBounds();
237 
238  for(int i = 0; i < m; i++){
239  g_l[ i] = mdConLB[ i];
240  g_u[ i] = mdConUB[ i];
241  cout << "lower !!!!!!!!!!!!!!!!!!!!!!!!!!!" << g_l[i] << endl;
242  cout << "upper !!!!!!!!!!!!!!!!!!!!!!!!!!!" << g_u[i] << endl;
243  }
244  return true;
245 }//get_bounds_info
246 
247 
248 // returns the initial point for the problem
249 bool BonminProblem::get_starting_point(Index n, bool init_x, Number* x,
250  bool init_z, Number* z_L, Number* z_U, Index m, bool init_lambda,
251  Number* lambda) {
252  // Here, we assume we only have starting values for x, if you code
253  // your own NLP, you can provide starting values for the dual variables
254  // if you wish
255  assert(init_x == true);
256  assert(init_z == false);
257  assert(init_lambda == false);
258  int i, m1, n1;
259 
260 #ifdef DEBUG
261  cout << "get initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
262 #endif
263 
264  //now set initial values
265 #ifdef DEBUG
266  cout << "get number of initial values !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
267  cout << "Is osoption = NULL? " << (osoption == NULL) << endl;
268 #endif
269  int k;
270  if (osoption != NULL)
271  m1 = osoption->getNumberOfInitVarValues();
272  else
273  m1 = 0;
274 #ifdef DEBUG
275  cout << "number of variables initialed: " << m1 << endl;
276 #endif
277 
279  bool* initialed;
280  initialed = new bool[n1];
281 #ifdef DEBUG
282  cout << "number of variables in total: " << n1 << endl;
283 #endif
284 
285 
286  for(k = 0; k < n1; k++)
287  initialed[k] = false;
288 
289  if (m1 > 0)
290  {
291 #ifdef DEBUG
292  cout << "get initial values " << endl;
293 #endif
294 
295  InitVarValue** initVarVector = osoption->getInitVarValuesSparse();
296 #ifdef DEBUG
297  cout << "done " << endl;
298 #endif
299 
300  double initval;
301  try
302  {
303  for(k = 0; k < m1; k++)
304  {
305  i = initVarVector[k]->idx;
306  if (initVarVector[k]->idx > n1)
307  throw ErrorClass ("Illegal index value in variable initialization");
308 
309  initval = initVarVector[k]->value;
311  { if (osinstance->instanceData->variables->var[i]->lb > initval)
312  throw ErrorClass ("Initial value outside of bounds");
313  }
314  else
316  { if (osinstance->instanceData->variables->var[i]->ub < initval)
317  throw ErrorClass ("Initial value outside of bounds");
318  }
319  else
320  { if ((osinstance->instanceData->variables->var[i]->lb > initval) ||
321  (osinstance->instanceData->variables->var[i]->ub < initval))
322  throw ErrorClass ("Initial value outside of bounds");
323  }
324 
325  x[initVarVector[k]->idx] = initval;
326  initialed[initVarVector[k]->idx] = true;
327  }
328  }
329  catch(const ErrorClass& eclass)
330  { cout << "Error in BonminProblem::get_starting_point (OSBonminSolver.cpp)";
331  cout << endl << endl << endl;
332  }
333  } // end if (m1 > 0)
334 
335  double default_initval;
336  default_initval = 1.7171;
337 
338  for(k = 0; k < n1; k++)
339  {
340  if (!initialed[k])
342  if (osinstance->instanceData->variables->var[k]->lb <= default_initval)
343  x[k] = default_initval;
344  else
346  else
348  if (osinstance->instanceData->variables->var[k]->ub >= default_initval)
349  x[k] = default_initval;
350  else
352  else
353  if ((osinstance->instanceData->variables->var[k]->lb <= default_initval) &&
354  (osinstance->instanceData->variables->var[k]->ub >= default_initval))
355  x[k] = default_initval;
356  else
357  if (osinstance->instanceData->variables->var[k]->lb > default_initval)
359  else
361  }
362  for(i = 0; i < n1; i++){
363  std::cout << "INITIAL VALUE !!!!!!!!!!!!!!!!!!!! " << x[ i] << std::endl;
364  }
365 
366 
367  delete[] initialed;
368 
369  return true;
370 }//get_starting_point
371 
372 
373 // returns the value of the objective function
374 bool BonminProblem::eval_f(Index n, const Number* x, bool new_x, Number& obj_value){
375  try{
376  obj_value = osinstance->calculateAllObjectiveFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 )[ 0];
377  }
378  catch(const ErrorClass& eclass){
379  bonminErrorMsg = eclass.errormsg;
380  throw;
381  }
382  if( CommonUtil::ISOSNAN( (double)obj_value) ) return false;
383  return true;
384 }
385 
386 bool BonminProblem::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f){
387  int i;
388  double *objGrad;
389  try{
390  //objGrad = osinstance->calculateAllObjectiveFunctionGradients( const_cast<double*>(x), NULL, NULL, new_x, 1)[ 0];
391  //std::cout << "Calculate Objective function gradient " << std::endl;
392  // we assume we are doing the objective function indexed by -1
393  objGrad = osinstance->calculateObjectiveFunctionGradient( const_cast<double*>(x), NULL, NULL, -1, new_x, 1);
394  }
395  catch(const ErrorClass& eclass){
396  bonminErrorMsg = eclass.errormsg;
397  throw;
398  }
399  for(i = 0; i < n; i++){
400  grad_f[ i] = objGrad[ i];
401  //std::cout << grad_f[ i] << std::endl;
402  }
403  std::cout << "DONE WITH Calculate Objective function gradient " << std::endl;
404  return true;
405 }//eval_grad_f
406 
407 // return the value of the constraints: g(x)
408 bool BonminProblem::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g) {
409  try{
410  double *conVals = osinstance->calculateAllConstraintFunctionValues( const_cast<double*>(x), NULL, NULL, new_x, 0 );
411  int i;
412  for(i = 0; i < m; i++){
413  if( CommonUtil::ISOSNAN( (double)conVals[ i] ) ) return false;
414  g[i] = conVals[ i] ;
415  }
416  return true;
417  }
418  catch(const ErrorClass& eclass){
419  bonminErrorMsg = eclass.errormsg;
420  throw;
421  }
422 }//eval_g
423 
424 
425 // return the structure or values of the jacobian
426 bool BonminProblem::eval_jac_g(Index n, const Number* x, bool new_x,
427  Index m, Index nele_jac, Index* iRow, Index *jCol,
428  Number* values){
429  SparseJacobianMatrix *sparseJacobian;
430  if (values == NULL) {
431  // return the values of the jacobian of the constraints
432  //cout << "n: " << n << endl;
433  //cout << "m: " << m << endl;
434  //cout << "nele_jac: " << nele_jac << endl;
435  // return the structure of the jacobian
436  try{
437  sparseJacobian = osinstance->getJacobianSparsityPattern();
438  }
439  catch(const ErrorClass& eclass){
440  bonminErrorMsg = eclass.errormsg;
441  throw;
442  }
443  int i = 0;
444  int k, idx;
445  for(idx = 0; idx < m; idx++){
446  for(k = *(sparseJacobian->starts + idx); k < *(sparseJacobian->starts + idx + 1); k++){
447  iRow[i] = idx;
448  jCol[i] = *(sparseJacobian->indexes + k);
449  //cout << "ROW IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << iRow[i] << endl;
450  //cout << "COL IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << jCol[i] << endl;
451  i++;
452  }
453  }
454  }
455  else {
456  //std::cout << "EVALUATING JACOBIAN" << std::endl;
457  try{
458  sparseJacobian = osinstance->calculateAllConstraintFunctionGradients( const_cast<double*>(x), NULL, NULL, new_x, 1);
459  }
460  catch(const ErrorClass& eclass){
461  bonminErrorMsg = eclass.errormsg;
462  throw;
463  }
464  //osinstance->getIterateResults( (double*)x, 0.0, NULL, -1, new_x, 1);
465  for(int i = 0; i < nele_jac; i++){
466  values[ i] = sparseJacobian->values[i];
467  //values[ i] = osinstance->m_mdJacValue[ i];
468  //cout << "values[i]:!!!!!!!!!!!! " << values[ i] << endl;
469  //cout << "m_mdJacValue[ i]:!!!!!!!!!!!! " << osinstance->m_mdJacValue[ i] << endl;
470  }
471  }
472  return true;
473 }//eval_jac_g
474 
475 //return the structure or values of the hessian
476 bool BonminProblem::eval_h(Index n, const Number* x, bool new_x,
477  Number obj_factor, Index m, const Number* lambda,
478  bool new_lambda, Index nele_hess, Index* iRow,
479  Index* jCol, Number* values){
480 
482  SparseHessianMatrix *sparseHessian;
483 
484  int i;
485  if (values == NULL) {
486  // return the structure. This is a symmetric matrix, fill the lower left triangle only.
487  //cout << "get structure of HESSIAN !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
488  try{
490  }
491  catch(const ErrorClass& eclass){
492  bonminErrorMsg = eclass.errormsg;
493  throw;
494  }
495  //cout << "got structure of HESSIAN !!!!!!!!!!!!!!!!!!!!!!!!!! " << endl;
496  for(i = 0; i < nele_hess; i++){
497  iRow[i] = *(sparseHessian->hessColIdx + i);
498  jCol[i] = *(sparseHessian->hessRowIdx + i);
499  //cout << "ROW HESS IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << iRow[i] << endl;
500  //cout << "COL HESS IDX !!!!!!!!!!!!!!!!!!!!!!!!!!!" << jCol[i] << endl;
501  }
502  }
503  else {
504  //std::cout << "EVALUATING HESSIAN" << std::endl;
505  // return the values. This is a symmetric matrix, fill the lower left triangle only
506  double* objMultipliers = new double[1];
507  objMultipliers[0] = obj_factor;
508  try{
509  sparseHessian = osinstance->calculateLagrangianHessian( const_cast<double*>(x), objMultipliers, const_cast<double*>(lambda) , new_x, 2);
510  delete[] objMultipliers;
511  }
512  catch(const ErrorClass& eclass){
513  bonminErrorMsg = eclass.errormsg;
514  delete[] objMultipliers;
515  throw;
516  }
517  for(i = 0; i < nele_hess; i++){
518  values[ i] = *(sparseHessian->hessValues + i);
519  }
520  }
522  return true;
523 }//eval_h
524 
525 bool BonminProblem::get_scaling_parameters(Number& obj_scaling,
526  bool& use_x_scaling, Index n,
527  Number* x_scaling,
528  bool& use_g_scaling, Index m,
529  Number* g_scaling){
530  /*
531  * Bonmin assumes problems cast as a min
532  * if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") != 0){
533  obj_scaling = -1;
534  }
535  else obj_scaling = 1;
536  use_x_scaling = false;
537  use_g_scaling = false;
538  */
539  return true;
540 }//get_scaling_parameters
541 
542 
543 
544 
545 void
546 BonminProblem::finalize_solution(TMINLP::SolverReturn status,
547  Index n, const Number* x, Number obj_value)
548 {
549  OSrLWriter *osrlwriter ;
550  osrlwriter = new OSrLWriter();
551  std::cout<<"Problem status: "<<status<<std::endl;
552  std::cout<<"Objective value: "<<obj_value<<std::endl;
553  if(printSol_ && x != NULL){
554  std::cout<<"Solution:"<<std::endl;
555  for(int i = 0 ; i < n ; i++){
556  std::cout<<"x["<<i<<"] = "<<x[i];
557  if(i < n-1) std::cout<<", ";
558  }
559  std::cout<<std::endl;
560  }
561 
562  printf("\n\nObjective value\n");
563  printf("f(x*) = %e\n", obj_value);
564  int solIdx = 0;
565  ostringstream outStr;
566  double* mdObjValues = new double[1];
567  std::string message = "Bonmin solver finishes to the end.";
568  std::string solutionDescription = "";
569 
570  try{
571 
572  // resultHeader information
573  if(osresult->setServiceName( "Bonmin solver service") != true)
574  throw ErrorClass("OSResult error: setServiceName");
576  throw ErrorClass("OSResult error: setInstanceName");
577 
578  //if(osresult->setJobID( osoption->jobID) != true)
579  // throw ErrorClass("OSResult error: setJobID");
580 
581  // set basic problem parameters
583  throw ErrorClass("OSResult error: setVariableNumer");
584  if(osresult->setObjectiveNumber( 1) != true)
585  throw ErrorClass("OSResult error: setObjectiveNumber");
587  throw ErrorClass("OSResult error: setConstraintNumber");
588  if(osresult->setSolutionNumber( 1) != true)
589  throw ErrorClass("OSResult error: setSolutionNumer");
590 
591 
592  if(osresult->setGeneralMessage( message) != true)
593  throw ErrorClass("OSResult error: setGeneralMessage");
594 
595  switch( status){
596  case SUCCESS:
597  solutionDescription = "SUCCESS[BONMIN]: Algorithm terminated successfully at a locally optimal point, satisfying the convergence tolerances.";
598  osresult->setSolutionStatus(solIdx, "locallyOptimal", solutionDescription);
599  osresult->setPrimalVariableValues(solIdx, const_cast<double*>(x), osinstance->getVariableNumber());
600  //osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda));
601  mdObjValues[0] = obj_value;
602  osresult->setObjectiveValues(solIdx, mdObjValues, 1);
603  break;
604  case MAXITER_EXCEEDED:
605  solutionDescription = "MAXITER_EXCEEDED[BONMIN]: Maximum number of iterations exceeded.";
606  osresult->setSolutionStatus(solIdx, "stoppedByLimit", solutionDescription);
607  osresult->setPrimalVariableValues(solIdx, const_cast<double*>(x), osinstance->getVariableNumber());
608  //osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda));
609  mdObjValues[0] = obj_value;
610  osresult->setObjectiveValues(solIdx, mdObjValues, 1);
611  break;
612  case STOP_AT_TINY_STEP:
613  solutionDescription = "STOP_AT_TINY_STEP[BONMIN]: Algorithm proceeds with very little progress.";
614  osresult->setSolutionStatus(solIdx, "stoppedByLimit", solutionDescription);
615  osresult->setPrimalVariableValues(solIdx, const_cast<double*>( x), osinstance->getVariableNumber());
616  //osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda));
617  mdObjValues[0] = obj_value;
618  osresult->setObjectiveValues(solIdx, mdObjValues, 1);
619  break;
620  case STOP_AT_ACCEPTABLE_POINT:
621  solutionDescription = "STOP_AT_ACCEPTABLE_POINT[BONMIN]: Algorithm stopped at a point that was converged, not to _desired_ tolerances, but to _acceptable_ tolerances";
622  osresult->setSolutionStatus(solIdx, "BonminAccetable", solutionDescription);
623  osresult->setPrimalVariableValues(solIdx, const_cast<double*>(x), osinstance->getVariableNumber());
624  //osresult->setDualVariableValues(solIdx, const_cast<double*>( lambda));
625  mdObjValues[0] = obj_value;
626  osresult->setObjectiveValues(solIdx, mdObjValues, 1);
627  break;
628  case LOCAL_INFEASIBILITY:
629  solutionDescription = "LOCAL_INFEASIBILITY[BONMIN]: Algorithm converged to a point of local infeasibility. Problem may be infeasible.";
630  osresult->setSolutionStatus(solIdx, "infeasible", solutionDescription);
631  break;
632  case USER_REQUESTED_STOP:
633  solutionDescription = "USER_REQUESTED_STOP[BONMIN]: The user call-back function intermediate_callback returned false, i.e., the user code requested a premature termination of the optimization.";
634  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
635  break;
636  case DIVERGING_ITERATES:
637  solutionDescription = "DIVERGING_ITERATES[BONMIN]: It seems that the iterates diverge.";
638  osresult->setSolutionStatus(solIdx, "unbounded", solutionDescription);
639  break;
640  case RESTORATION_FAILURE:
641  solutionDescription = "RESTORATION_FAILURE[BONMIN]: Restoration phase failed, algorithm doesn't know how to proceed.";
642  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
643  break;
644  case ERROR_IN_STEP_COMPUTATION:
645  solutionDescription = "ERROR_IN_STEP_COMPUTATION[BONMIN]: An unrecoverable error occurred while IPOPT tried to compute the search direction.";
646  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
647  break;
648  case INVALID_NUMBER_DETECTED:
649  solutionDescription = "INVALID_NUMcatBER_DETECTED[BONMIN]: Algorithm received an invalid number (such as NaN or Inf) from the NLP; see also option check_derivatives_for_naninf.";
650  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
651  break;
652  case INTERNAL_ERROR:
653  solutionDescription = "INTERNAL_ERROR[BONMIN]: An unknown internal error occurred. Please contact the IPOPT authors through the mailing list.";
654  osresult->setSolutionStatus(solIdx, "error", solutionDescription);
655  break;
656  default:
657  solutionDescription = "OTHER[BONMIN]: other unknown solution status from Bonmin solver";
658  osresult->setSolutionStatus(solIdx, "other", solutionDescription);
659  }
660  osresult->setGeneralStatusType("normal");
661  delete osrlwriter;
662  delete[] mdObjValues;
663  osrlwriter = NULL;
664 
665  }
666 
667  catch(const ErrorClass& eclass){
669  osresult->setGeneralStatusType( "error");
670  std::string osrl = osrlwriter->writeOSrL( osresult);
671  delete osrlwriter;
672  osrlwriter = NULL;
673  throw ErrorClass( osrl) ;
674  delete[] mdObjValues;
675  mdObjValues = NULL;
676  }
677 }
678 
679 
680 
681 
683  try{
684  if(osil.length() == 0 && osinstance == NULL) throw ErrorClass("there is no instance");
685  if(osinstance == NULL){
686  m_osilreader = new OSiLReader();
688  }
689  // Create a new instance of your nlp
690  tminlp = new BonminProblem( osinstance, osoption, osresult);
691  this->bCallbuildSolverInstance = true;
692  //Now initialize from tminlp
693  bonmin.initialize( GetRawPtr(tminlp) );
694  }
695  catch(const ErrorClass& eclass){
696  std::cout << "THERE IS AN ERROR" << std::endl;
698  osresult->setGeneralStatusType( "error");
699  osrl = osrlwriter->writeOSrL( osresult);
700  throw ErrorClass( osrl) ;
701  }
702 }//end buildSolverInstance()
703 
704 
705 
706 void BonminSolver::setSolverOptions() throw (ErrorClass) {
707  try{
708 
709  this->bSetSolverOptions = true;
710  bonmin.initializeOptionsAndJournalist();
711  //Register an additional option
712  bonmin.roptions()->AddStringOption2("print_solution","Do we print the solution or not?",
713  "yes",
714  "no", "No, we don't.",
715  "yes", "Yes, we do.",
716  "A longer comment can be put here");
717 
718  // Here we can change the default value of some Bonmin or Ipopt option
719  bonmin.options()->SetNumericValue("bonmin.time_limit", 1000); //changes bonmin's time limit
720  bonmin.options()->SetStringValue("mu_oracle","loqo");
721 
722  //Here we read several option files
723  bonmin.readOptionsFile("Mybonmin.opt");
724  bonmin.readOptionsFile();// This reads the default file "bonmin.opt"
725 
726  // Options can also be set by using a string with a format similar to the bonmin.opt file
727  bonmin.readOptionsString("bonmin.algorithm B-BB\n");
728 
729  // Now we can obtain the value of the new option
730  int printSolution;
731  bonmin.options()->GetEnumValue("print_solution", printSolution,"");
732  if(printSolution == 1){
733  tminlp->printSolutionAtEndOfAlgorithm();
734  }
735 
736  if(osoption == NULL && osol.length() > 0)
737  {
738  m_osolreader = new OSoLReader();
739  osoption = m_osolreader->readOSoL( osol);
740  }
741 
742  if(osoption != NULL){
743  std::cout << "number of solver options " << osoption->getNumberOfSolverOptions() << std::endl;
744  std::vector<SolverOption*> optionsVector;
745  optionsVector = osoption->getSolverOptions( "bonmin");
746  char *pEnd;
747  int i;
748  int num_bonmin_options = optionsVector.size();
749  for(i = 0; i < num_bonmin_options; i++){
750  std::cout << "bonmin solver option " << optionsVector[ i]->name << std::endl;
751  if(optionsVector[ i]->type == "numeric" ){
752  std::cout << "FOUND A NUMERIC OPTION " << os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) << std::endl;
753  bonmin.options()->SetNumericValue(optionsVector[ i]->name, os_strtod( optionsVector[ i]->value.c_str(), &pEnd ) );
754  }
755  else if(optionsVector[ i]->type == "integer" ){
756  std::cout << "FOUND AN INTEGER OPTION " << atoi( optionsVector[ i]->value.c_str() ) << std::endl;
757  bonmin.options()->SetIntegerValue(optionsVector[ i]->name, atoi( optionsVector[ i]->value.c_str() ) );
758  }
759  else if(optionsVector[ i]->type == "string" ){
760  bonmin.options()->SetStringValue(optionsVector[ i]->name, optionsVector[ i]->value);
761  }
762  }
763  }
764 
765  }
766 
767  catch(const ErrorClass& eclass){
768  std::cout << "THERE IS AN ERROR" << std::endl;
770  osresult->setGeneralStatusType( "error");
771  osrl = osrlwriter->writeOSrL( osresult);
772  throw ErrorClass( osrl) ;
773  }
774 }//end setSolverOptions()
775 
776 
777 //void BonminSolver::solve() throw (ErrorClass) {
778 void BonminSolver::solve() throw (ErrorClass) {
779  if( this->bCallbuildSolverInstance == false) buildSolverInstance();
780  std::cout << "set Solver Options for Gus" << std::endl;
781  if( this->bSetSolverOptions == false) setSolverOptions();
782  std::cout << "done setting set Solver Options for Gus" << std::endl;
783 
784  try{
785  double start = CoinCpuTime();
786  //OSiLWriter osilwriter;
787  //cout << osilwriter.writeOSiL( osinstance) << endl;
788  if(osinstance->getVariableNumber() <= 0)throw ErrorClass("Bonmin requires decision variables");
789 
790 // The next line should come out eventually...
791  if(osinstance->getConstraintNumber() <= 0)throw ErrorClass("Bonmin cannot handle unconstrained problems");
792 
793  double duration = CoinCpuTime() - start;
794  cout << "Parsing took (seconds): "<< duration << endl;
795 
796  try {
797  Bab bb;
798  bb( bonmin); //process parameter file using Ipopt and do branch and bound using Cbc
799 
800 
801  }
802  catch(TNLPSolver::UnsolvedError *E) {
803  //There has been a failure to solve a problem with Ipopt.
804  std::cerr<<"Ipopt has failed to solve a problem"<<std::endl;
805  }
806  catch(OsiTMINLPInterface::SimpleError &E) {
807  std::cerr<<E.className()<<"::"<<E.methodName()
808  <<std::endl
809  <<E.message()<<std::endl;
810  }
811  catch(CoinError &E) {
812  std::cerr<<E.className()<<"::"<<E.methodName()
813  <<std::endl
814  <<E.message()<<std::endl;
815  }
816 
817 
818  // see if we have a linear program
819  if(osinstance->getObjectiveNumber() <= 0) throw ErrorClass("Bonmin NEEDS AN OBJECTIVE FUNCTION");
821  //app->Options()->SetStringValue("hessian_approximation", "limited-memory");
822  // if it is a max problem call scaling and set to -1
823  if( osinstance->instanceData->objectives->obj[ 0]->maxOrMin.compare("min") != 0){
824  //app->Options()->SetStringValue("nlp_scaling_method", "user-scaling");
825  }
826 
827  std::cout << "Finish Bonmin Optimize" << std::endl;
828  osrl = osrlwriter->writeOSrL( osresult);
829  std::cout << "Finish writing the osrl" << std::endl;
830 
831 
832  }
833  catch(const ErrorClass& eclass){
835  osresult->setGeneralStatusType( "error");
836  osrl = osrlwriter->writeOSrL( osresult);
837  throw ErrorClass( osrl) ;
838  }
839 }//solve
840 
841 
843 
844  int i;
845 
846  // print out problem parameters
847  cout << "This is problem: " << osinstance->getInstanceName() << endl;
848  cout << "The problem source is: " << osinstance->getInstanceSource() << endl;
849  cout << "The problem description is: " << osinstance->getInstanceDescription() << endl;
850  cout << "number of variables = " << osinstance->getVariableNumber() << endl;
851  cout << "number of Rows = " << osinstance->getConstraintNumber() << endl;
852 
853  // print out the variable information
854  if(osinstance->getVariableNumber() > 0){
855  for(i = 0; i < osinstance->getVariableNumber(); i++){
856  if(osinstance->getVariableNames() != NULL) cout << "variable Names " << osinstance->getVariableNames()[ i] << endl;
857  if(osinstance->getVariableTypes() != NULL) cout << "variable Types " << osinstance->getVariableTypes()[ i] << endl;
858  if(osinstance->getVariableLowerBounds() != NULL) cout << "variable Lower Bounds " << osinstance->getVariableLowerBounds()[ i] << endl;
859  if(osinstance->getVariableUpperBounds() != NULL) cout << "variable Upper Bounds " << osinstance->getVariableUpperBounds()[i] << endl;
860  }
861  }
862 
863  // print out objective function information
865  if( osinstance->getObjectiveMaxOrMins()[0] == "min") cout << "problem is a minimization" << endl;
866  else cout << "problem is a maximization" << endl;
867  for(i = 0; i < osinstance->getVariableNumber(); i++){
868  cout << "OBJ COEFFICIENT = " << osinstance->getDenseObjectiveCoefficients()[0][i] << endl;
869  }
870  }
871  // print out constraint information
872  if(osinstance->getConstraintNumber() > 0){
873  for(i = 0; i < osinstance->getConstraintNumber(); i++){
874  if(osinstance->getConstraintNames() != NULL) cout << "row name = " << osinstance->getConstraintNames()[i] << endl;
875  if(osinstance->getConstraintLowerBounds() != NULL) cout << "row lower bound = " << osinstance->getConstraintLowerBounds()[i] << endl;
876  if(osinstance->getConstraintUpperBounds() != NULL) cout << "row upper bound = " << osinstance->getConstraintUpperBounds()[i] << endl;
877  }
878  }
879 
880  // print out linear constraint data
881  cout << endl;
882  cout << "number of nonzeros = " << osinstance->getLinearConstraintCoefficientNumber() << endl;
883  for(i = 0; i <= osinstance->getVariableNumber(); i++){
884  cout << "Start Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->starts[ i] << endl;
885  }
886  cout << endl;
887  for(i = 0; i < osinstance->getLinearConstraintCoefficientNumber(); i++){
888  cout << "Index Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->indexes[i] << endl;
889  cout << "Nonzero Value = " << osinstance->getLinearConstraintCoefficientsInColumnMajor()->values[i] << endl;
890  }
891 
892  // print out quadratic data
893  cout << "number of qterms = " << osinstance->getNumberOfQuadraticTerms() << endl;
894  for(int i = 0; i < osinstance->getNumberOfQuadraticTerms(); i++){
895  cout << "Row Index = " << osinstance->getQuadraticTerms()->rowIndexes[i] << endl;
896  cout << "Var Index 1 = " << osinstance->getQuadraticTerms()->varOneIndexes[ i] << endl;
897  cout << "Var Index 2 = " << osinstance->getQuadraticTerms()->varTwoIndexes[ i] << endl;
898  cout << "Coefficient = " << osinstance->getQuadraticTerms()->coefficients[ i] << endl;
899  }
900 } // end dataEchoCheck
901 
902 
903 BonminProblem::BonminProblem(OSInstance *osinstance_, OSOption *osoption_, OSResult *osresult_) {
904  osinstance = osinstance_;
905  osoption = osoption_;
906  osresult = osresult_;
907  printSol_ = false;
908 }
909 
911 
912 }
913 
914 
915 
double * getConstraintLowerBounds()
Get constraint lower bounds.
double * getVariableLowerBounds()
Get variable lower bounds.
double * getConstraintUpperBounds()
Get constraint upper bounds.
double * values
OSoLReader * m_osolreader
m_osolreader is an OSoLReader object used to create an osoption from an osol string if needed ...
double os_strtod(const char *s00, char **se)
Definition: OSdtoa.cpp:2541
char * getVariableTypes()
Get variable initial values.
std::string value
value holds the text of the value attribute of the OtherVariableResult element
bool setSolutionStatus(int solIdx, std::string type, std::string description)
Set the [i]th optimization solution status, where i equals the given solution index.
SparseHessianMatrix * calculateLagrangianHessian(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate the Hessian of the Lagrangian Expression Tree This method will build the CppAD expression t...
virtual void setSolverOptions()
The implementation of the virtual functions.
double * values
values holds a double array of nonzero partial derivatives
Definition: OSGeneral.h:340
bool bUseExpTreeForFunEval
bUseExpTreeForFunEval is set to true if you wish to use the OS Expression Tree for function evaluatio...
Definition: OSInstance.h:4899
BonminSolver()
the BonminSolver class constructor
int getVariableNumber()
Get number of variables.
void dataEchoCheck()
use this for debugging, print out the instance that the solver thinks it has and compare this with th...
std::string osrl
osrl holds the solution or result of the model
bool setServiceName(std::string serviceName)
Set service name.
bool setVariableNumber(int variableNumber)
Set the variable number.
Definition: OSResult.cpp:4712
virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)
Method to return the gradient of the objective.
std::string osil
osil holds the problem instance as a std::string
std::string errormsg
errormsg is the error that is causing the exception to be thrown
Definition: OSErrorClass.h:42
int getLinearConstraintCoefficientNumber()
Get number of specified (usually nonzero) linear constraint coefficient values.
virtual void buildSolverInstance()
buildSolverInstance is a virtual function – the actual solvers will implement their own buildSolverIn...
int * getNonlinearExpressionTreeModIndexes()
Get all the nonlinear expression tree indexes, i.e., indexes of rows (objectives or constraints) that...
std::string maxOrMin
declare the objective function to be a max or a min
Definition: OSInstance.h:157
the InitVarValue class.
Definition: OSOption.h:1159
The Result Class.
Definition: OSResult.h:2548
virtual bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number &obj_value)
Method to return the objective value.
SparseJacobianMatrix * calculateAllConstraintFunctionGradients(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate the gradient of all constraint functions.
bool bCallbuildSolverInstance
bCallbuildSolverInstance is set to true if buildSolverService has been called
std::string name
name holds the text of the name attribute of the OtherVariableResult element
Take an OSResult object and write a string that validates against OSrL.
Definition: OSrLWriter.h:30
OSResult * osresult
osresult holds the solution or result of the model in-memory as an OSResult object ...
bool bSetSolverOptions
bSetSolverOptions is set to true if setSolverOptions has been called, false otherwise ...
int getNumberOfNonlinearExpressionTreeModIndexes()
Get the number of unique nonlinear expression tree indexes after modifying the expression tree to con...
int * hessColIdx
hessColIdx is an integer array of column indices in the range 0, ..., n - 1.
Definition: OSGeneral.h:399
int getObjectiveNumber()
Get number of objectives.
bool setObjectiveNumber(int objectiveNumber)
Set the objective number.
Definition: OSResult.cpp:4721
bool setInstanceName(std::string instanceName)
Set instance name.
virtual bool get_variables_types(Ipopt::Index n, VariableType *var_types)
Pass the type of the variables (INTEGER, BINARY, CONTINUOUS) to the optimizer.
OSInstance * readOSiL(const std::string &osil)
parse the OSiL model instance.
Definition: OSiLReader.cpp:53
std::map< int, int > getAllNonlinearVariablesIndexMap()
std::string * getVariableNames()
Get variable names.
int * hessRowIdx
hessRowIdx is an integer array of row indices in the range 0, ..., n - 1.
Definition: OSGeneral.h:394
int getNumberOfNonlinearExpressions()
Get number of nonlinear expressions.
std::string writeOSrL(OSResult *theosresult)
create an osrl string from an OSResult object
Definition: OSrLWriter.cpp:45
int numberOfObjectives
numberOfObjectives is the number of objective functions in the instance
Definition: OSInstance.h:201
virtual bool get_constraints_linearity(Ipopt::Index m, Ipopt::TNLP::LinearityType *const_types)
Pass the type of the constraints (LINEAR, NON_LINEAR) to the optimizer.
The Option Class.
Definition: OSOption.h:3564
int idx
variable index
Definition: OSOption.h:1164
Bonmin::Bab bb
int * indexes
indexes holds an integer array of rowIdx (or colIdx) elements in coefMatrix (AMatrix).
Definition: OSGeneral.h:258
std::string osol
osol holds the options for the solver
bool setSolutionNumber(int number)
set the number of solutions.
Definition: OSResult.cpp:4740
double ** getDenseObjectiveCoefficients()
getDenseObjectiveCoefficients.
SparseJacobianMatrix * getJacobianSparsityPattern()
OSInstance * osinstance
virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number *x_l, Ipopt::Number *x_u, Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
Bonmin specific methods for defining the nlp problem.
virtual void solve()
solve results in an instance being read into the Bonmin data structrues and optimized ...
virtual void finalize_solution(Bonmin::TMINLP::SolverReturn status_, Ipopt::Index n, const Ipopt::Number *x, Ipopt::Number obj_value)
Method called by Ipopt at the end of optimization.
bool setObjectiveValues(int solIdx, double *objectiveValues, int n)
Set the [i]th optimization solution&#39;s objective values, where i equals the given solution index...
Definition: OSResult.cpp:1130
int valueSize
valueSize is the dimension of the values array
Definition: OSGeneral.h:318
Used to read an OSiL string.
Definition: OSiLReader.h:37
int * indexes
indexes holds an integer array of variable indices.
Definition: OSGeneral.h:335
double * calculateAllConstraintFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the constraint function values.
double lb
lb corresponds to the optional attribute that holds the variable lower bound.
Definition: OSInstance.h:56
bool setPrimalVariableValues(int solIdx, double *x, int n)
Set the [i]th optimization solution&#39;s primal variable values, where i equals the given solution index...
Definition: OSResult.cpp:1028
Variable ** var
Here we define a pointer to an array of var pointers.
Definition: OSInstance.h:97
std::string bonminErrorMsg
int hessDimension
hessDimension is the number of nonzeros in each array.
Definition: OSGeneral.h:389
int * varOneIndexes
varOneIndexes holds an integer array of the first variable indexes of all the quadratic terms...
Definition: OSGeneral.h:445
double value
initial value
Definition: OSOption.h:1170
virtual bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g, Ipopt::Index &nnz_h_lag, Ipopt::TNLP::IndexStyleEnum &index_style)
Method to pass the main dimensions of the problem to Ipopt.
SparseHessianMatrix * getLagrangianHessianSparsityPattern()
OSResult * osresult
void fint fint * k
const double OSDBL_MAX
Definition: OSParameters.h:93
std::string * getObjectiveMaxOrMins()
Get objective maxOrMins.
BonminProblem(OSInstance *osinstance_, OSOption *osoption_)
the BonminProblemclass constructor
double ub
ub corresponds to the optional attribute that holds the variable upper bound.
Definition: OSInstance.h:61
double * hessValues
hessValues is a double array of the Hessian values.
Definition: OSGeneral.h:404
virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number *x, bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U, Ipopt::Index m, bool init_lambda, Ipopt::Number *lambda)
Method to return the starting point for the algorithm.
Variables * variables
variables is a pointer to a Variables object
Definition: OSInstance.h:2185
virtual bool eval_h(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number *lambda, bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
Method to return: 1) The structure of the hessian of the lagrangian (if &quot;values&quot; is NULL) 2) The valu...
SparseMatrix * getLinearConstraintCoefficientsInColumnMajor()
Get linear constraint coefficients in column major.
OSOption * readOSoL(const std::string &osol)
parse the OSoL solver options.
Definition: OSoLReader.cpp:76
bool setGeneralMessage(std::string message)
Set the general message.
virtual bool get_variables_linearity(Ipopt::Index n, Ipopt::TNLP::LinearityType *var_types)
Pass info about linear and nonlinear variables.
double * values
values holds a double array of value elements in coefMatrix (AMatrix), which contains nonzero element...
Definition: OSGeneral.h:264
OSInstance * osinstance
osinstance holds the problem instance in-memory as an OSInstance object
fint m1
bool setGeneralStatusType(std::string type)
Set the general status type, which can be: success, error, warning.
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:452
a sparse Jacobian matrix data structure
Definition: OSGeneral.h:300
std::string getInstanceName()
Get instance name.
OSiLReader * m_osilreader
m_osilreader is an OSiLReader object used to create an osinstance from an osil string if needed ...
InstanceData * instanceData
A pointer to an InstanceData object.
Definition: OSInstance.h:2278
virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
Method to return: 1) The structure of the jacobian (if &quot;values&quot; is NULL) 2) The values of the jacobia...
OSOption * osoption
int * starts
starts holds an integer array of start elements, each start element points to the start of partials f...
Definition: OSGeneral.h:324
int getConstraintNumber()
Get number of constraints.
Objective ** obj
coef is pointer to an array of ObjCoef object pointers
Definition: OSInstance.h:205
bool setConstraintNumber(int constraintNumber)
Set the constraint number.
Definition: OSResult.cpp:4731
OSrLWriter * osrlwriter
int getNumberOfSolverOptions()
Get the number of solver options.
Definition: OSOption.cpp:2207
int getNumberOfQuadraticTerms()
Get the number of specified (usually nonzero) qTerms in the quadratic coefficients.
Used to read an OSoL string.
Definition: OSoLReader.h:37
Objectives * objectives
objectives is a pointer to a Objectives object
Definition: OSInstance.h:2188
std::string getInstanceSource()
Get instance source.
bool initForAlgDiff()
This should be called by nonlinear solvers using callback functions.
virtual bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Number *g)
Method to return the constraint residuals.
int * rowIndexes
rowIndexes holds an integer array of row indexes of all the quadratic terms.
Definition: OSGeneral.h:440
int * starts
starts holds an integer array of start elements in coefMatrix (AMatrix), which points to the start of...
Definition: OSGeneral.h:252
double * calculateAllObjectiveFunctionValues(double *x, double *objLambda, double *conLambda, bool new_x, int highestOrder)
Calculate all of the objective function values.
virtual bool get_scaling_parameters(Ipopt::Number &obj_scaling, bool &use_x_scaling, Ipopt::Index n, Ipopt::Number *x_scaling, bool &use_g_scaling, Ipopt::Index m, Ipopt::Number *g_scaling)
overload this method to return scaling parameters.
QuadraticTerms * getQuadraticTerms()
Get all the quadratic terms in the instance.
virtual ~BonminProblem()
the BonminProblem class destructor
double * getVariableUpperBounds()
Get variable upper bounds.
void fint fint fint real fint real real real real real real * g
~BonminSolver()
the IpoptSolver class destructor
Ipopt::SmartPtr< BonminProblem > tminlp
void fint * m
The in-memory representation of an OSiL instance..
Definition: OSInstance.h:2262
double * coefficients
coefficients holds a double array all the quadratic term coefficients.
Definition: OSGeneral.h:455
int * varTwoIndexes
varTwoIndexes holds an integer array of the second variable indexes of all the quadratic terms...
Definition: OSGeneral.h:450
The in-memory representation of a SparseHessianMatrix..
Definition: OSGeneral.h:376
std::string * getConstraintNames()
Get constraint names.
used for throwing exceptions.
Definition: OSErrorClass.h:31
void fint * n
std::string getInstanceDescription()
Get instance description.
double * calculateObjectiveFunctionGradient(double *x, double *objLambda, double *conLambda, int objIdx, bool new_x, int highestOrder)
Calculate the gradient of the objective function indexed by objIdx.
void fint fint fint real fint real * x
std::string bonminErrorMsg