source: branches/devel/Bonmin/src/BonminAmplInterface/BonAmplTMINLP.cpp @ 62

Last change on this file since 62 was 62, checked in by pbonami, 13 years ago

astyled the devel branch

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