source: trunk/Bonmin/src/BonminAmplInterface/AmplTMINLP.cpp @ 1

Last change on this file since 1 was 1, checked in by andreasw, 13 years ago

imported initial code

  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Revision"
File size: 20.8 KB
Line 
1// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2004
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// Authors :
6// Carl D. Laird, Carnegie Mellon University,
7// Andreas Waechter, International Business Machines Corporation
8// Pierre Bonami, Carnegie Mellon University,
9//
10// Date : 12/01/2004
11#include "IpBlas.hpp"
12
13#include "AmplTNLP.hpp"
14#include "AmplTMINLP.hpp"
15#include <iostream>
16
17#include "asl.h"
18#include "asl_pfgh.h"
19#include "getstub.h"
20#include "CoinHelperFunctions.hpp"
21
22namespace ampl_utils
23{
24  void sos_kludge(int nsos, int *sosbeg, double *sosref);
25}
26namespace Ipopt
27{
28
29  AmplTMINLP::AmplTMINLP()
30      :
31      TMINLP(),
32      ampl_tnlp_(NULL),
33      branch_(),
34      sos_()
35  {}
36
37
38  AmplTMINLP::AmplTMINLP(const SmartPtr<const Journalist>& jnlst,
39      const SmartPtr<OptionsList> options,
40      char**& argv,
41      AmplSuffixHandler* suffix_handler /*=NULL*/,
42      const std::string& appName,
43      std::string* nl_file_content /* = NULL */)
44      :
45      TMINLP(),
46      ampl_tnlp_(NULL),
47      branch_(),
48      sos_(),
49      suffix_handler_(NULL)
50  {
51    Initialize(jnlst, options, argv, suffix_handler, appName, nl_file_content);
52  }
53
54  void
55  AmplTMINLP::Initialize(const SmartPtr<const Journalist>& jnlst,
56      const SmartPtr<OptionsList> options,
57      char**& argv,
58      AmplSuffixHandler* suffix_handler /*=NULL*/,
59      const std::string& appName,
60      std::string* nl_file_content /* = NULL */)
61  {
62
63
64    if(suffix_handler==NULL)
65      suffix_handler_ = suffix_handler = new AmplSuffixHandler();
66
67    // Add the suffix handler for scaling
68    suffix_handler->AddAvailableSuffix("scaling_factor", AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Number_Type);
69    suffix_handler->AddAvailableSuffix("scaling_factor", AmplSuffixHandler::Constraint_Source, AmplSuffixHandler::Number_Type);
70    suffix_handler->AddAvailableSuffix("scaling_factor", AmplSuffixHandler::Objective_Source, AmplSuffixHandler::Number_Type);
71 
72    // priority suffix
73    suffix_handler->AddAvailableSuffix("priority", AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Index_Type);
74    suffix_handler->AddAvailableSuffix("direction", AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Number_Type);
75    suffix_handler->AddAvailableSuffix("downPseudocost", AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Number_Type);
76    suffix_handler->AddAvailableSuffix("upPseudocost", AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Number_Type);
77
78
79
80    // sos suffixes
81    suffix_handler->AddAvailableSuffix("ref", AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Number_Type);
82    suffix_handler->AddAvailableSuffix("sos",AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Index_Type);
83    suffix_handler->AddAvailableSuffix("sos",AmplSuffixHandler::Constraint_Source, AmplSuffixHandler::Index_Type);
84    suffix_handler->AddAvailableSuffix("sosno",AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Number_Type);
85    suffix_handler->AddAvailableSuffix("sosref",AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Number_Type);
86    suffix_handler->AddAvailableSuffix("sstatus", AmplSuffixHandler::Variable_Source, AmplSuffixHandler::Index_Type);
87    suffix_handler->AddAvailableSuffix("sstatus", AmplSuffixHandler::Constraint_Source, AmplSuffixHandler::Index_Type);
88   
89
90    SmartPtr<AmplOptionsList> ampl_options_list = new AmplOptionsList();
91    fillAmplOptionList(GetRawPtr(ampl_options_list));
92    fillApplicationOptions(GetRawPtr(ampl_options_list) );
93    std::string options_id = appName + "_options";
94    ampl_tnlp_ = new AmplTNLP(jnlst, options, argv, suffix_handler, true,
95         ampl_options_list, options_id.c_str(),
96        appName.c_str(), appName.c_str(), nl_file_content);
97    /* Read suffixes */
98    read_priorities();
99    read_sos();
100  }
101
102  AmplTMINLP::~AmplTMINLP()
103  {}
104
105  void
106  AmplTMINLP::read_priorities()
107  {
108    int numcols, m, dummy1, dummy2;
109    TNLP::IndexStyleEnum index_style;
110    ampl_tnlp_->get_nlp_info(numcols, m, dummy1, dummy2, index_style);
111
112    const AmplSuffixHandler * suffix_handler = GetRawPtr(suffix_handler_);
113
114    const Index* pri = suffix_handler->GetIntegerSuffixValues("priority", AmplSuffixHandler::Variable_Source);
115    const Index* brac = suffix_handler->GetIntegerSuffixValues("direction", AmplSuffixHandler::Variable_Source);
116    const Number* upPs = suffix_handler->GetNumberSuffixValues("upPseudocost", AmplSuffixHandler::Variable_Source);
117    const Number* dwPs = suffix_handler->GetNumberSuffixValues("downPseudocost", AmplSuffixHandler::Variable_Source);
118
119
120    branch_.gutsOfDestructor();
121    branch_.size = numcols;
122    if(pri) {
123      branch_.priorities = new int[numcols];
124      for(int i = 0 ; i < numcols ; i++) {
125        branch_.priorities [i] = -pri[i] + 9999;
126      }
127    }
128    if(brac) {
129      branch_.branchingDirections = CoinCopyOfArray(brac,numcols);
130    }
131    if(upPs && !dwPs) dwPs = upPs;
132    else if(dwPs && !upPs) upPs = dwPs;
133 
134    if(upPs) {
135      branch_.upPsCosts = CoinCopyOfArray(upPs,numcols);
136    }
137    if(dwPs) {
138      branch_.downPsCosts = CoinCopyOfArray(dwPs,numcols);
139    }
140  } 
141
142  void
143  AmplTMINLP::read_sos()
144  {
145    ASL_pfgh* asl = ampl_tnlp_->AmplSolverObject();
146
147    int i = ASL_suf_sos_explict_free;
148    int copri[2], **p_sospri;
149    copri[0] = 0;
150    copri[1] = 0;
151    int * starts = NULL;
152    int * indices = NULL;
153    char * types = NULL;
154    double * weights = NULL;
155    int * priorities = NULL;
156    p_sospri = &priorities;
157
158    sos_.gutsOfDestructor();
159
160    sos_.num = suf_sos(i, &sos_.numNz, &types, p_sospri, copri,
161        &starts, &indices, &weights);
162    if (sos_.num) {
163      //Copy sos information
164      sos_.priorities = CoinCopyOfArray(priorities,sos_.num);
165      sos_.starts = CoinCopyOfArray(starts, sos_.num + 1);
166      sos_.indices = CoinCopyOfArray(indices, sos_.numNz);
167      sos_.types = CoinCopyOfArray(types, sos_.num);
168      sos_.weights = CoinCopyOfArray(weights, sos_.numNz);
169
170      ampl_utils::sos_kludge(sos_.num, sos_.starts, sos_.weights);
171      for (int ii=0;ii<sos_.num;ii++) {
172        int ichar = sos_.types[ii];
173        if(ichar != '1') {
174          std::cerr<<"Unsuported type of sos constraint: "<<sos_.types[ii]<<std::endl;
175          throw;
176        }
177        sos_.types[ii]= 1;
178      }
179    }
180  }
181
182  bool AmplTMINLP::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, Index& nnz_h_lag, TNLP::IndexStyleEnum& index_style)
183  {
184    return ampl_tnlp_->get_nlp_info(n, m, nnz_jac_g, nnz_h_lag, index_style);
185  }
186
187  bool AmplTMINLP::get_var_types(Index n, VariableType* var_types)
188  {
189    // The variables are sorted by type in AMPL, so all we need to
190    // know are the counts of each type.
191
192
193    Index n_non_linear_b= 0;
194    Index n_non_linear_bi= 0;
195    Index n_non_linear_c= 0;
196    Index n_non_linear_ci = 0;
197    Index n_non_linear_o= 0;
198    Index n_non_linear_oi = 0;
199    Index n_binaries = 0;
200    Index n_integers = 0;
201    ampl_tnlp_->get_discrete_info(n_non_linear_b, n_non_linear_bi, n_non_linear_c,
202        n_non_linear_ci, n_non_linear_o, n_non_linear_oi,
203        n_binaries, n_integers);
204    int totalNumberOfNonContinuous = 0;
205    //begin with variables non-linear both in the objective function and in some constraints
206    // The first ones are continuous
207    Index start = 0;
208    Index end = n_non_linear_b - n_non_linear_bi;
209    for (int i=start; i<end; i++) {
210      var_types[i] = CONTINUOUS;
211    }
212
213    // The second ones are integers
214    start = end;
215    end = start + n_non_linear_bi;
216    for (int i=start; i < end; i++) {
217      var_types[i] = INTEGER;
218      totalNumberOfNonContinuous++;
219    }
220
221    //next variables non-linear in some constraints
222    // The first ones are continuous
223    start = end;
224    end = max(start,end + n_non_linear_c - n_non_linear_ci - n_non_linear_b);
225    for (int i=start; i<end; i++) {
226      var_types[i] = CONTINUOUS;
227    }
228
229    // The second ones are integers
230    start = end;
231    end = start + n_non_linear_ci;
232    for (int i=start; i < end; i++) {
233      var_types[i] = INTEGER;
234      totalNumberOfNonContinuous++;
235    }
236
237    //next variables non-linear in the objective function
238    // The first ones are continuous
239    start = end;
240    end = max(start,end + n_non_linear_o - max(n_non_linear_b, n_non_linear_c) - n_non_linear_oi);
241    for (int i=start; i<end; i++) {
242      var_types[i] = CONTINUOUS;
243    }
244
245    // The second ones are integers
246    start = end;
247    end = start + n_non_linear_oi;
248    for (int i=start; i < end; i++) {
249      var_types[i] = INTEGER;
250      totalNumberOfNonContinuous++;
251    }
252
253    //At last the linear variables
254    // The first ones are continuous
255    start = end;
256    end = n - n_binaries - n_integers;
257    for (int i=start; i<end; i++) {
258      var_types[i] = CONTINUOUS;
259    }
260
261    // The second ones are binaries
262    start = end;
263    end = start + n_binaries;
264    for (int i=start; i < end; i++) {
265      var_types[i] = BINARY;
266      totalNumberOfNonContinuous++;
267    }
268
269    // The third ones are integers
270    start = end;
271    end = start + n_integers;
272    for (int i=start; i < end; i++) {
273      var_types[i] = INTEGER;
274      totalNumberOfNonContinuous++;
275    }
276    //    std::cout<<"Number of integer and binaries : "<<totalNumberOfNonContinuous<<std::endl;
277    return true;
278  }
279
280  bool AmplTMINLP::get_constraints_types(Index n, ConstraintType* const_types)
281  {
282    ASL_pfgh* asl = ampl_tnlp_->AmplSolverObject();
283    //check that n is good
284    DBG_ASSERT(n == n_con);
285    // check that there are no network constraints
286    DBG_ASSERT(nlnc == 0 && lnc == 0);
287    //the first nlc constraints are non linear the rest is linear
288    int i;
289    for(i = 0 ; i < nlc ; i++)
290      const_types[i]=NON_LINEAR;
291    // the rest is linear
292    for(; i < n_con ; i++)
293      const_types[i]=LINEAR;
294    return true;
295  }
296
297  bool AmplTMINLP::get_bounds_info(Index n, Number* x_l, Number* x_u,
298      Index m, Number* g_l, Number* g_u)
299  {
300    return ampl_tnlp_->get_bounds_info(n, x_l, x_u, m, g_l, g_u);
301  }
302
303  bool AmplTMINLP::get_starting_point(Index n, bool init_x, Number* x,
304      Index m, bool init_lambda, Number* lambda)
305  {
306    return ampl_tnlp_->get_starting_point(n, init_x, x,
307        false, NULL, NULL,
308        m, init_lambda, lambda);
309  }
310
311  bool AmplTMINLP::eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
312  {
313    return ampl_tnlp_->eval_f(n, x, new_x, obj_value);
314  }
315
316  bool AmplTMINLP::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
317  {
318    return ampl_tnlp_->eval_grad_f(n, x, new_x, grad_f);
319  }
320
321  bool AmplTMINLP::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
322  {
323    return ampl_tnlp_->eval_g(n, x, new_x, m, g);
324  }
325
326  bool AmplTMINLP::eval_jac_g(Index n, const Number* x, bool new_x,
327      Index m, Index nele_jac, Index* iRow,
328      Index *jCol, Number* values)
329  {
330    return ampl_tnlp_->eval_jac_g(n, x, new_x,
331        m, nele_jac, iRow, jCol,
332        values);
333  }
334
335  bool AmplTMINLP::eval_h(Index n, const Number* x, bool new_x,
336      Number obj_factor, Index m, const Number* lambda,
337      bool new_lambda, Index nele_hess, Index* iRow,
338      Index* jCol, Number* values)
339  {
340    return ampl_tnlp_->eval_h(n, x, new_x, obj_factor,
341        m, lambda, new_lambda, nele_hess, iRow,
342        jCol, values);
343  }
344
345  void AmplTMINLP::finalize_solution(SolverReturn status,
346      Index n, const Number* x, const Number* z_L, const Number* z_U,
347      Index m, const Number* g, const Number* lambda,
348      Number obj_value)
349  {
350    // Not sure if ampl require a different form of solution file
351    // for MINLPs - we may have to write a different solution file here instead of
352    // passing this back to ampl.
353    ampl_tnlp_->finalize_solution(status,
354        n, x, z_L, z_U,
355        m, g, lambda,
356        obj_value);
357
358    ASL_pfgh* asl = ampl_tnlp_->AmplSolverObject();
359    solve_result_num = 0;
360  }
361
362  void AmplTMINLP::write_solution(const std::string & message, const Number *x_sol, const Number * lambda_sol)
363  {
364    ASL_pfgh* asl = ampl_tnlp_->AmplSolverObject();
365    ;
366    DBG_ASSERT(asl);
367    //    DBG_ASSERT(x_sol);
368
369    // We need to copy the message into a non-const char array to make
370    // it work with the AMPL C function.
371    char* cmessage = new char[message.length()+1];
372    strcpy(cmessage, message.c_str());
373
374    // In order to avoid casting into non-const, we copy the data here...
375    double* x_sol_copy = NULL;
376    if (x_sol) {
377      x_sol_copy = new double[n_var];
378      for (int i=0; i<n_var; i++) {
379        x_sol_copy[i] = x_sol[i];
380      }
381    }
382    double* lambda_sol_copy = NULL;
383    if (lambda_sol_copy) {
384      lambda_sol_copy = new double[n_con];
385      for (int i=0; i<n_con; i++) {
386        lambda_sol_copy[i] = lambda_sol[i];
387      }
388    }
389    write_sol(cmessage, x_sol_copy, lambda_sol_copy, NULL);
390
391    delete [] x_sol_copy;
392    delete [] lambda_sol_copy;
393    delete [] cmessage;
394
395  }
396
397
398  /** This methods gives the linear part of the objective function */
399  void AmplTMINLP::getLinearPartOfObjective(double * obj)
400  {
401    Index n, m, nnz_jac_g, nnz_h_lag;
402    TNLP::IndexStyleEnum index_style = TNLP::FORTRAN_STYLE;
403    get_nlp_info( n, m, nnz_jac_g, nnz_h_lag, index_style);
404    eval_grad_f(n, NULL, 0,obj);
405    Index n_non_linear_b= 0;
406    Index n_non_linear_bi= 0;
407    Index n_non_linear_c= 0;
408    Index n_non_linear_ci = 0;
409    Index n_non_linear_o= 0;
410    Index n_non_linear_oi = 0;
411    Index n_binaries = 0;
412    Index n_integers = 0;
413    ampl_tnlp_->get_discrete_info(n_non_linear_b, n_non_linear_bi, n_non_linear_c,
414        n_non_linear_ci, n_non_linear_o, n_non_linear_oi,
415        n_binaries, n_integers);
416
417    // Now get the coefficients of variables wich are linear in the objective
418    // The first ones are not
419    Index start = 0;
420    Index end = n_non_linear_b;
421    for (int i=start; i<end; i++) {
422      obj[i] = 0.;
423    }
424
425    //next variables should be linear in the objective just skip them
426    // (from current end to (end + n_non_linear_c - n_non_linear_ci - n_non_linear_b;)
427
428
429    // Those are nonlinear in the objective
430    start = end + n_non_linear_c;
431    end = start + n_non_linear_o;
432    for (int i=start; i < end; i++) {
433      obj[i]=0.;
434    }
435    //The rest is linear keep the values of the gradient
436  }
437
438
439  void
440  AmplTMINLP::fillAmplOptionList(AmplOptionsList* amplOptList)
441  {
442    amplOptList->AddAmplOption("bonmin.algorithm","bonmin.algorithm",
443        AmplOptionsList::String_Option,
444        "Choice of the algorithm.");
445
446    amplOptList->AddAmplOption("bonmin.bb_log_level","bonmin.bb_log_level",
447        AmplOptionsList::Integer_Option,
448        "specify BB log level");
449
450    amplOptList->AddAmplOption("bonmin.lp_log_level","bonmin.lp_log_level",
451        AmplOptionsList::Integer_Option,
452        "specify sub-LP log level");
453
454    amplOptList->AddAmplOption("bonmin.milp_log_level","bonmin.milp_log_level",
455        AmplOptionsList::Integer_Option,
456        "specify sub-MILP log level");
457
458    amplOptList->AddAmplOption("bonmin.oa_log_level","bonmin.oa_log_level",
459        AmplOptionsList::Integer_Option,
460        "specify OA log level");
461
462    amplOptList->AddAmplOption("bonmin.oa_log_frequency","bonmin.oa_log_frequency",
463        AmplOptionsList::Number_Option,
464        "specify OA log frequency");
465
466    amplOptList->AddAmplOption("bonmin.nlp_log_level","bonmin.nlp_log_level",
467        AmplOptionsList::Integer_Option,
468        "specify sub-NLP log level");
469
470    amplOptList->AddAmplOption("bonmin.print_user_options","bonmin.print_user_options",
471        AmplOptionsList::String_Option,
472        "print options list");
473
474    amplOptList->AddAmplOption("bonmin.bb_log_interval","bonmin.bb_log_interval",
475        AmplOptionsList::Integer_Option,
476        "Interval at which bound output is given");
477
478    amplOptList->AddAmplOption("bonmin.allowable_gap","bonmin.allowable_gap",
479        AmplOptionsList::Number_Option,
480        "Specify allowable absolute gap");
481
482    amplOptList->AddAmplOption("bonmin.allowable_fraction_gap","bonmin.allowable_fraction_gap",
483        AmplOptionsList::Number_Option,
484        "Specify allowable relative gap");
485
486    amplOptList->AddAmplOption("bonmin.cutoff_decr","bonmin.cutoff_decr",
487        AmplOptionsList::Number_Option,
488        "Specify cutoff decrement");
489
490    amplOptList->AddAmplOption("bonmin.cutoff","bonmin.cutoff",
491        AmplOptionsList::Number_Option,
492        "Specify cutoff");
493
494    amplOptList->AddAmplOption("bonmin.nodeselect_stra","bonmin.nodeselect_stra",
495        AmplOptionsList::String_Option,
496        "Choose the node selection strategy");
497
498
499    amplOptList->AddAmplOption("bonmin.number_strong_branch", "bonmin.number_strong_branch",
500        AmplOptionsList::Integer_Option,
501        "Chooes number of variable for strong branching");
502
503    amplOptList->AddAmplOption("bonmin.number_before_trust", "bonmin.number_before_trust",
504        AmplOptionsList::Integer_Option,
505        "Set number of branches on a variable before its pseudo-costs are to be believed");
506
507    amplOptList->AddAmplOption("bonmin.time_limit", "bonmin.time_limit",
508        AmplOptionsList::Number_Option,
509        "Set maximum computation time for Algorithm");
510
511    amplOptList->AddAmplOption("bonmin.node_limit","bonmin.node_limit",
512        AmplOptionsList::Integer_Option,
513        "Set maximum number of nodes explored");
514
515    amplOptList->AddAmplOption("bonmin.integer_tolerance", "bonmin.integer_tolerance",
516        AmplOptionsList::Number_Option,
517        "Set integer tolerance");
518
519    amplOptList->AddAmplOption("bonmin.warm_start","bonmin.warm_start",
520        AmplOptionsList::String_Option,
521        "Set warm start method");
522
523    amplOptList->AddAmplOption("bonmin.sos_constraints","bonmin.sos_constraints",
524        AmplOptionsList::String_Option,
525        "Disable SOS contraints");
526
527    amplOptList->AddAmplOption("bonmin.max_random_point_radius",
528        "bonmin.max_random_point_radius",
529        AmplOptionsList::Number_Option,
530        "Set max value for a random point");
531
532    amplOptList->AddAmplOption("bonmin.max_consecutive_failures",
533        "bonmin.max_consecutive_failures",
534        AmplOptionsList::Integer_Option,
535        "Number of consecutive unsolved problems before aborting.");
536
537    amplOptList->AddAmplOption("bonmin.num_iterations_suspect",
538        "bonmin.num_iterations_suspect",
539        AmplOptionsList::Integer_Option,
540        "Number of iteration over which a node is considered suspect");
541
542    amplOptList->AddAmplOption("bonmin.nlp_failure_behavior",
543        "bonmin.nlp_failure_behavior",
544        AmplOptionsList::String_Option,
545        "Set the behavior when the nlp fails.");
546
547    amplOptList->AddAmplOption("bonmin.num_retry_unsolved_random_point",
548        "bonmin.num_retry_unsolved_random_point",
549        AmplOptionsList::Integer_Option,
550        "Number of tries to resolve a failed NLP with a random starting point");
551
552    amplOptList->AddAmplOption("bonmin.max_consecutive_infeasible",
553        "bonmin.max_consecutive_infeasible",
554        AmplOptionsList::Integer_Option,
555        "Number of consecutive infeasible problems before continuing a"
556        " branch.");
557
558    amplOptList->AddAmplOption("bonmin.num_resolve_at_root", "bonmin.num_resolve_at_root",
559        AmplOptionsList::Integer_Option,
560        "Number of tries to resolve the root node with different starting point (only usefull in non-convex).");
561
562    amplOptList->AddAmplOption("bonmin.num_resolve_at_node","bonmin.num_resolve_at_node",
563        AmplOptionsList::Integer_Option,
564        "Number of tries to resolve a non root node with different starting point (only usefull in non-convex).");
565
566
567    amplOptList->AddAmplOption("bonmin.nlp_solve_frequency","bonmin.nlp_solve_frequency",
568        AmplOptionsList::Integer_Option,
569        "Specify the frequency at which nlp relaxations are solved in hybrid.");
570
571    amplOptList->AddAmplOption("bonmin.oa_dec_time_limit", "bonmin.oa_dec_time_limit",
572        AmplOptionsList::Number_Option,
573        "Specify the maximum amount of time spent in OA decomposition iteratrions.");
574
575    amplOptList->AddAmplOption("bonmin.tiny_element","bonmin.tiny_element",
576        AmplOptionsList::Number_Option,
577        "Value for tiny element in OA cut");
578
579    amplOptList->AddAmplOption("bonmin.very_tiny_element","bonmin.very_tiny_element",
580        AmplOptionsList::Number_Option,
581        "Value for very tiny element in OA cut");
582
583    amplOptList->AddAmplOption("bonmin.milp_subsolver", "bonmin.milp_subsolver",
584        AmplOptionsList::String_Option,
585        "Choose the subsolver to solve MILPs sub-problems in OA decompositions.");
586
587    amplOptList->AddAmplOption("bonmin.Gomory_cuts", "bonmin.Gomory_cuts",
588        AmplOptionsList::Integer_Option,
589        "Frequency for Generating Gomory cuts in branch-and-cut.");
590
591    amplOptList->AddAmplOption("bonmin.probing_cuts", "bonmin.probing_cuts",
592        AmplOptionsList::Integer_Option,
593        "Frequency for Generating probing cuts in branch-and-cut");
594
595    amplOptList->AddAmplOption("bonmin.cover_cuts", "bonmin.cover_cuts",
596        AmplOptionsList::Integer_Option,
597        "Frequency for Generating cover cuts in branch-and-cut");
598
599
600    amplOptList->AddAmplOption("bonmin.mir_cuts", "bonmin.mir_cuts",
601        AmplOptionsList::Integer_Option,
602        "Frequency for Generating MIR cuts in branch-and-cut");
603
604  }
605} // namespace Ipopt
Note: See TracBrowser for help on using the repository browser.