source: stable/2.4/Cbc/src/CbcGenCbcParamUtils.cpp @ 1271

Last change on this file since 1271 was 1271, checked in by forrest, 10 years ago

Creating new stable branch 2.4 from trunk (rev 1270)

File size: 12.8 KB
Line 
1/*
2  Copyright (C) 2007, Lou Hafer, International Business Machines Corporation
3  and others.  All Rights Reserved.
4
5  This file is part of cbc-generic.
6*/
7
8#if defined(_MSC_VER)
9// Turn off compiler warning about long names
10#  pragma warning(disable:4786)
11#endif
12
13#include <string>
14#include <cassert>
15
16#include "CoinFinite.hpp"
17#include "CoinParam.hpp"
18
19#include "CbcModel.hpp"
20
21#include "CbcGenCtlBlk.hpp"
22#include "CbcGenParam.hpp"
23#include "CbcGenCbcParam.hpp"
24
25/*! \file CbcGenParamUtils
26    \brief Implementation functions for CbcGenParam parameters.
27*/
28
29namespace {
30
31  char svnid[] = "$Id: CbcGenCbcParamUtils.cpp 1173 2009-06-04 09:44:10Z forrest $" ;
32
33}
34
35namespace CbcCbcParamUtils
36{
37
38
39/* Function to set up cbc (CbcModel) parameters.  */
40
41void addCbcCbcParams (int &numberParameters, CoinParamVec &parameters,
42                      CbcModel *model)
43
44{ CbcCbcParam *param ;
45
46  param = new CbcCbcParam(CbcCbcParam::ALLOWABLEGAP,
47        "allow!ableGap",
48        "Stop when gap between best possible and incumbent is less than this",
49        0.0,1.0e20) ;
50  param->setDblVal(0.0) ;
51  param->setPushFunc(pushCbcCbcDbl) ;
52  param->setObj(model) ;
53  param->setLongHelp(
54        "If the gap between best solution and best possible solution is less than this then the search will be terminated. Also see ratioGap."
55        ) ;
56  parameters.push_back(param) ;
57
58  param = new CbcCbcParam(CbcCbcParam::CUTOFF,
59        "cuto!ff","All solutions must be better than this", -1.0e60,1.0e60) ;
60  param->setDblVal(1.0e50) ;
61  param->setPushFunc(pushCbcCbcDbl) ;
62  param->setObj(model) ;
63  param->setLongHelp(
64        "All solutions must be better than this value (in a minimization sense).  This is also set by cbc whenever it obtains a solution and is set to the value of the objective for the solution minus the cutoff increment."
65        ) ;
66  parameters.push_back(param) ;
67
68  param = new CbcCbcParam(CbcCbcParam::DIRECTION,
69                          "direction","Minimize or maximize","min!imize",0) ;
70  param->appendKwd("max!imize") ;
71  param->appendKwd("zero") ;
72  param->setObj(model) ;
73  param->setLongHelp(
74        "The default is minimize - use 'direction maximize' for maximization.\nYou can also use the parameters 'maximize' or 'minimize'."
75        ) ;
76  parameters.push_back(param) ;
77
78  param = new CbcCbcParam(CbcCbcParam::INCREMENT,
79        "inc!rement",
80        "A new solution must be at least this much better than the incumbent",
81        -1.0e20,1.0e20,model->getDblParam(CbcModel::CbcCutoffIncrement)) ;
82  param->setPushFunc(pushCbcCbcDbl) ;
83  param->setObj(model) ;
84  param->setLongHelp(
85        "Whenever a solution is found the bound on future solutions is set to the objective of the solution (in a minimization sense) plus the specified increment.  If this option is not specified, the code will try and work out an increment.  E.g., if all objective coefficients are multiples of 0.01 and only integer variables have entries in objective then the increment can be set to 0.01.  Be careful if you set this negative!"
86        ) ;
87  parameters.push_back(param) ;
88
89  param = new CbcCbcParam(CbcCbcParam::INFEASIBILITYWEIGHT,
90        "inf!easibilityWeight",
91        "Each integer infeasibility is expected to cost this much",
92        0.0,1.0e20,model->getDblParam(CbcModel::CbcInfeasibilityWeight)) ;
93  param->setPushFunc(pushCbcCbcDbl) ;
94  param->setObj(model) ;
95  param->setLongHelp(
96        "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is expected to cost this much."
97        ) ;
98  parameters.push_back(param) ;
99
100  param = new CbcCbcParam(CbcCbcParam::INTEGERTOLERANCE,
101        "integerT!olerance",
102        "For an optimal solution, no integer variable may be farther than this from an integer value",
103        1.0e-20,0.5,model->getDblParam(CbcModel::CbcIntegerTolerance)) ;
104  param->setPushFunc(pushCbcCbcDbl) ;
105  param->setObj(model) ;
106  param->setLongHelp(
107        "When checking a solution for feasibility, if the difference between the value of a variable and the nearest integer is less than the integer tolerance, the value is considered to be integral. Beware of setting this smaller than the primal tolerance."
108        ) ;
109  parameters.push_back(param) ;
110
111  param = new CbcCbcParam(CbcCbcParam::LOGLEVEL,
112        "bclog!Level","Level of detail in Coin branch and Cut output",
113        -1,63,model->messageHandler()->logLevel()) ;
114  param->setPushFunc(pushCbcCbcInt) ;
115  param->setObj(model) ;
116  param->setLongHelp(
117        "If set to 0 then there should be no output in normal circumstances. A value of 1 is probably the best value for most uses, while 2 and 3 give more information."
118        ) ;
119  parameters.push_back(param) ;
120
121  param = new CbcCbcParam(CbcCbcParam::MAXIMIZE,
122        "max!imize","Set optimization direction to maximize") ;
123  param->setObj(model) ;
124  param->setLongHelp(
125        "The default is minimize - use 'maximize' for maximization.\n A synonym for 'direction maximize'."
126        ) ;
127  parameters.push_back(param) ;
128
129  param = new CbcCbcParam(CbcCbcParam::MAXNODES,
130        "maxN!odes","Maximum number of nodes to evaluate",1,2147483647) ;
131  param->setObj(model) ;
132  param->setLongHelp(
133        "This is a repeatable way to limit search.  Normally using time is easier but then the results may not be repeatable."
134        ) ;
135  parameters.push_back(param) ;
136
137  param = new CbcCbcParam(CbcCbcParam::MINIMIZE,
138        "min!imize","Set optimization direction to minimize") ;
139  param->setObj(model) ;
140  param->setLongHelp(
141        "The default is minimize - use 'maximize' for maximization.\nThis should only be necessary if you have previously set maximization. A synonym for 'direction minimize'."
142        ) ;
143  parameters.push_back(param) ;
144
145  param = new CbcCbcParam(CbcCbcParam::MIPOPTIONS,
146        "mipO!ptions","Dubious options for mip",0,COIN_INT_MAX,0,false) ;
147  parameters.push_back(param) ;
148
149  param = new CbcCbcParam(CbcCbcParam::MOREMIPOPTIONS,
150        "more!MipOptions","More dubious options for mip",-1,COIN_INT_MAX,0,false) ;
151  parameters.push_back(param) ;
152
153  param = new CbcCbcParam(CbcCbcParam::NUMBERMINI,
154        "miniT!ree","Size of fast mini tree",0,COIN_INT_MAX,0,false) ;
155  param->setObj(model) ;
156  param->setLongHelp(
157        "The idea is that I can do a small tree fast. This is a first try and will hopefully become more sophisticated."
158        ) ;
159  parameters.push_back(param) ;
160
161  param = new CbcCbcParam(CbcCbcParam::NUMBERANALYZE,
162        "numberA!nalyze",
163        "Number of analysis iterations",-COIN_INT_MAX,COIN_INT_MAX,false) ;
164  param->setObj(model) ;
165  param->setLongHelp(
166        "This says how many iterations to spend at the root node analyzing the problem.  This is a first try and will hopefully become more sophisticated."
167        ) ; 
168  parameters.push_back(param) ;
169
170  param = new CbcCbcParam(CbcCbcParam::CUTPASS,
171        "passC!uts","Number of cut passes at root node",
172        -999999,999999,model->getMaximumCutPassesAtRoot()) ;
173  param->setObj(model) ;
174  param->setLongHelp(
175        "The default is 100 passes if less than 500 columns, 100 passes (but stop if the drop is small) if less than 5000 columns, 20 otherwise."
176        ) ;
177  parameters.push_back(param) ;
178
179  param = new CbcCbcParam(CbcCbcParam::GAPRATIO,
180        "ratio!Gap",
181        "Stop when the gap between the best possible solution and the incumbent is less than this fraction of the larger of the two",
182        0.0,1.0e20,model->getDblParam(CbcModel::CbcAllowableFractionGap)) ;
183  param->setPushFunc(pushCbcCbcDbl) ;
184  param->setObj(model) ;
185  param->setLongHelp(
186        "If the gap between the best solution and the best possible solution is less than this fraction of the objective value at the root node then the search will terminate.  See 'allowableGap' for a way of using absolute value rather than fraction."
187        ) ;
188  parameters.push_back(param) ;
189
190  param = new CbcCbcParam(CbcCbcParam::TIMELIMIT_BAB,
191        "sec!onds","Maximum seconds for branch and cut",-1.0,1.0e12) ;
192  param->setPushFunc(pushCbcCbcDbl) ;
193  param->setObj(model) ;
194  param->setLongHelp(
195        "After this many seconds the program will act as if maximum nodes had been reached."
196        ) ;
197  parameters.push_back(param) ;
198
199  param = new CbcCbcParam(CbcCbcParam::STRONGBRANCHING,
200        "strong!Branching",
201        "Number of variables to look at in strong branching",0,999999,
202        model->numberStrong()) ;
203  param->setObj(model) ;
204  param->setLongHelp(
205        "In order to decide which variable to branch on, the code will choose up to this number of unsatisfied variables and try mini up and down branches.  The most effective one is chosen. If a variable is branched on many times then the previous average up and down costs may be used - see number before trust."
206        ) ;
207  parameters.push_back(param) ;
208
209  param = new CbcCbcParam(CbcCbcParam::NUMBERBEFORE,
210        "trust!PseudoCosts","Number of branches before we trust pseudocosts",
211        -1,2000000,model->numberBeforeTrust()) ;
212  param->setObj(model) ;
213  param->setPushFunc(pushCbcCbcInt) ;
214  param->setLongHelp(
215        "Using strong branching computes pseudo-costs.  After this many times for a variable we just trust the pseudo costs and do not do any more strong branching."
216        ) ;
217  parameters.push_back(param) ;
218
219  numberParameters = parameters.size() ;
220
221  assert (numberParameters <= parameters.capacity()) ;
222
223}
224
225void loadCbcParamObj (const CoinParamVec paramVec, int first, int last,
226                      CbcModel *obj)
227
228{ int i ;
229
230/*
231  Load the CbcModel object into the parameters
232*/
233  for (i = first ; i <= last ; i++)
234  { CbcCbcParam *cbcParam = dynamic_cast<CbcCbcParam *>(paramVec[i]) ;
235    assert (cbcParam != 0) ;
236    cbcParam->setObj(obj) ; }
237
238  return ; }
239
240/*
241  Set CbcModel defaults appropriate for cbc-generic.
242*/
243
244void setCbcModelDefaults (CbcModel *model)
245
246{ model->setIntParam(CbcModel::CbcMaxNumNode,(COIN_INT_MAX/2)) ;
247  model->setIntParam(CbcModel::CbcMaxNumSol,999999) ;
248  model->setIntParam(CbcModel::CbcFathomDiscipline,0) ;
249
250  model->setDblParam(CbcModel::CbcIntegerTolerance,1.0e-6) ;
251  model->setDblParam(CbcModel::CbcInfeasibilityWeight,0.0) ;
252  model->setDblParam(CbcModel::CbcCutoffIncrement,1.0e-5) ;
253  model->setDblParam(CbcModel::CbcAllowableGap,1.0e-10) ;
254  model->setDblParam(CbcModel::CbcAllowableFractionGap,0.0) ;
255  // One year is 60x60x24x365 = 31,536,000 seconds.
256  model->setDblParam(CbcModel::CbcMaximumSeconds,3.0e7) ;
257  model->setDblParam(CbcModel::CbcCurrentCutoff,1.0e100) ;
258  model->setDblParam(CbcModel::CbcOptimizationDirection,1.0) ;
259  model->setDblParam(CbcModel::CbcCurrentObjectiveValue,1.0e100) ;
260  model->setDblParam(CbcModel::CbcCurrentMinimizationObjectiveValue,1.0e100) ;
261  model->setDblParam(CbcModel::CbcStartSeconds,0.0) ;
262
263  model->setNumberBeforeTrust(5) ;
264  model->setNumberStrong(5) ;
265
266  return ; }
267
268
269/*
270  Function to push a double parameter.
271*/
272
273int pushCbcCbcDbl (CoinParam *param)
274
275{ assert (param != 0) ;
276
277  CbcCbcParam *cbcParam = dynamic_cast<CbcCbcParam *>(param) ;
278  assert (cbcParam != 0) ;
279
280  CbcModel *model = cbcParam->obj() ;
281  double val = cbcParam->dblVal() ;
282  CbcCbcParam::CbcCbcParamCode code = cbcParam->paramCode() ;
283
284  assert (model != 0) ;
285
286  int retval = 0 ;
287/*
288  Translate the parameter code from CbcCbcParamCode into the correct key for
289  CbcDblParam.
290*/
291  CbcModel::CbcDblParam key ;
292  switch (code)
293  { case CbcCbcParam::INTEGERTOLERANCE:
294    { key = CbcModel::CbcIntegerTolerance ;
295      break ; }
296    case CbcCbcParam::INFEASIBILITYWEIGHT:
297    { key = CbcModel::CbcInfeasibilityWeight ;
298      break ; }
299    case CbcCbcParam::INCREMENT:
300    { key = CbcModel::CbcCutoffIncrement ;
301      break ; }
302    case CbcCbcParam::ALLOWABLEGAP:
303    { key = CbcModel::CbcAllowableGap ;
304      break ; }
305    case CbcCbcParam::GAPRATIO:
306    { key = CbcModel::CbcAllowableFractionGap ;
307      break ; }
308    case CbcCbcParam::TIMELIMIT_BAB:
309    { key = CbcModel::CbcMaximumSeconds ;
310      break ; }
311    case CbcCbcParam::CUTOFF:
312    { key = CbcModel::CbcCurrentCutoff ;
313      break ; }
314    default:
315    { std::cerr << "pushCbcCbcDbl: no equivalent CbcDblParam for "
316                << "parameter code `" << code << "'." << std::endl ;
317      retval = -1 ;
318      break ; } }
319
320  bool result = model->setDblParam(key,val) ;
321  if (result == false)
322  { retval = -1 ; }
323
324  return (retval) ; }
325
326
327/*
328  Function to push an integer parameter.
329*/
330
331int pushCbcCbcInt (CoinParam *param)
332
333{ assert (param != 0) ;
334
335  CbcCbcParam *cbcParam = dynamic_cast<CbcCbcParam *>(param) ;
336  assert (cbcParam != 0) ;
337
338  CbcModel *model = cbcParam->obj() ;
339  int val = cbcParam->intVal() ;
340  CbcCbcParam::CbcCbcParamCode code = cbcParam->paramCode() ;
341
342  assert (model != 0) ;
343
344  int retval = 0 ;
345/*
346  Translate the parameter code from CbcCbcParamCode into the correct key for
347  CbcIntParam, or call the appropriate method directly.
348*/
349  CbcModel::CbcIntParam key = CbcModel::CbcLastIntParam ;
350  switch (code)
351  { case CbcCbcParam::CUTPASS:
352    { model->setMaximumCutPassesAtRoot(val) ;
353      break ; }
354    case CbcCbcParam::LOGLEVEL:
355    { CoinMessageHandler *hndl = model->messageHandler() ;
356      assert (hndl != 0) ;
357      hndl->setLogLevel(val) ;
358      break ; }
359    case CbcCbcParam::NUMBERBEFORE:
360    { model->setNumberBeforeTrust(val) ;
361      break ; }
362    default:
363    { std::cerr << "pushCbcCbcInt: no equivalent CbcIntParam for "
364                << "parameter code `" << code << "'." << std::endl ;
365      retval = -1 ;
366      break ; } }
367
368  if (key != CbcModel::CbcLastIntParam)
369  { bool result = model->setIntParam(key,val) ;
370    if (result == false)
371    { retval = -1 ; } }
372
373  return (retval) ; }
374
375} // end namespace CbcCbcParamUtils
376
Note: See TracBrowser for help on using the repository browser.