source: stable/2.5/Cbc/src/CbcGenCbcParamUtils.cpp @ 1510

Last change on this file since 1510 was 1510, checked in by tkr, 9 years ago

Merging r1508 from trunk

File size: 14.5 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
31char svnid[] = "$Id: CbcGenCbcParamUtils.cpp 1173 2009-06-04 09:44:10Z forrest $" ;
32
33}
34
35namespace CbcCbcParamUtils {
36
37
38/* Function to set up cbc (CbcModel) parameters.  */
39
40void addCbcCbcParams (int &numberParameters, CoinParamVec &parameters,
41                      CbcModel *model)
42
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{
229    int i ;
230
231    /*
232      Load the CbcModel object into the parameters
233    */
234    for (i = first ; i <= last ; i++) {
235        CbcCbcParam *cbcParam = dynamic_cast<CbcCbcParam *>(paramVec[i]) ;
236        assert (cbcParam != 0) ;
237        cbcParam->setObj(obj) ;
238    }
239
240    return ;
241}
242
243/*
244  Set CbcModel defaults appropriate for cbc-generic.
245*/
246
247void setCbcModelDefaults (CbcModel *model)
248
249{
250    model->setIntParam(CbcModel::CbcMaxNumNode, (COIN_INT_MAX / 2)) ;
251    model->setIntParam(CbcModel::CbcMaxNumSol, 999999) ;
252    model->setIntParam(CbcModel::CbcFathomDiscipline, 0) ;
253
254    model->setDblParam(CbcModel::CbcIntegerTolerance, 1.0e-6) ;
255    model->setDblParam(CbcModel::CbcInfeasibilityWeight, 0.0) ;
256    model->setDblParam(CbcModel::CbcCutoffIncrement, 1.0e-5) ;
257    model->setDblParam(CbcModel::CbcAllowableGap, 1.0e-10) ;
258    model->setDblParam(CbcModel::CbcAllowableFractionGap, 0.0) ;
259    // One year is 60x60x24x365 = 31,536,000 seconds.
260    model->setDblParam(CbcModel::CbcMaximumSeconds, 3.0e7) ;
261    model->setDblParam(CbcModel::CbcCurrentCutoff, 1.0e100) ;
262    model->setDblParam(CbcModel::CbcOptimizationDirection, 1.0) ;
263    model->setDblParam(CbcModel::CbcCurrentObjectiveValue, 1.0e100) ;
264    model->setDblParam(CbcModel::CbcCurrentMinimizationObjectiveValue, 1.0e100) ;
265    model->setDblParam(CbcModel::CbcStartSeconds, 0.0) ;
266
267    model->setNumberBeforeTrust(5) ;
268    model->setNumberStrong(5) ;
269
270    return ;
271}
272
273
274/*
275  Function to push a double parameter.
276*/
277
278int pushCbcCbcDbl (CoinParam *param)
279
280{
281    assert (param != 0) ;
282
283    CbcCbcParam *cbcParam = dynamic_cast<CbcCbcParam *>(param) ;
284    assert (cbcParam != 0) ;
285
286    CbcModel *model = cbcParam->obj() ;
287    double val = cbcParam->dblVal() ;
288    CbcCbcParam::CbcCbcParamCode code = cbcParam->paramCode() ;
289
290    assert (model != 0) ;
291
292    int retval = 0 ;
293    /*
294      Translate the parameter code from CbcCbcParamCode into the correct key for
295      CbcDblParam.
296    */
297    CbcModel::CbcDblParam key ;
298    switch (code) {
299    case CbcCbcParam::INTEGERTOLERANCE: {
300        key = CbcModel::CbcIntegerTolerance ;
301        break ;
302    }
303    case CbcCbcParam::INFEASIBILITYWEIGHT: {
304        key = CbcModel::CbcInfeasibilityWeight ;
305        break ;
306    }
307    case CbcCbcParam::INCREMENT: {
308        key = CbcModel::CbcCutoffIncrement ;
309        break ;
310    }
311    case CbcCbcParam::ALLOWABLEGAP: {
312        key = CbcModel::CbcAllowableGap ;
313        break ;
314    }
315    case CbcCbcParam::GAPRATIO: {
316        key = CbcModel::CbcAllowableFractionGap ;
317        break ;
318    }
319    case CbcCbcParam::TIMELIMIT_BAB: {
320        key = CbcModel::CbcMaximumSeconds ;
321        break ;
322    }
323    case CbcCbcParam::CUTOFF: {
324        key = CbcModel::CbcCurrentCutoff ;
325        break ;
326    }
327    default: {
328        std::cerr << "pushCbcCbcDbl: no equivalent CbcDblParam for "
329                  << "parameter code `" << code << "'." << std::endl ;
330        retval = -1 ;
331        break ;
332    }
333    }
334
335    bool result = model->setDblParam(key, val) ;
336    if (result == false) {
337        retval = -1 ;
338    }
339
340    return (retval) ;
341}
342
343
344/*
345  Function to push an integer parameter.
346*/
347
348int pushCbcCbcInt (CoinParam *param)
349
350{
351    assert (param != 0) ;
352
353    CbcCbcParam *cbcParam = dynamic_cast<CbcCbcParam *>(param) ;
354    assert (cbcParam != 0) ;
355
356    CbcModel *model = cbcParam->obj() ;
357    int val = cbcParam->intVal() ;
358    CbcCbcParam::CbcCbcParamCode code = cbcParam->paramCode() ;
359
360    assert (model != 0) ;
361
362    int retval = 0 ;
363    /*
364      Translate the parameter code from CbcCbcParamCode into the correct key for
365      CbcIntParam, or call the appropriate method directly.
366    */
367    CbcModel::CbcIntParam key = CbcModel::CbcLastIntParam ;
368    switch (code) {
369    case CbcCbcParam::CUTPASS: {
370        model->setMaximumCutPassesAtRoot(val) ;
371        break ;
372    }
373    case CbcCbcParam::LOGLEVEL: {
374        CoinMessageHandler *hndl = model->messageHandler() ;
375        assert (hndl != 0) ;
376        hndl->setLogLevel(val) ;
377        break ;
378    }
379    case CbcCbcParam::NUMBERBEFORE: {
380        model->setNumberBeforeTrust(val) ;
381        break ;
382    }
383    default: {
384        std::cerr << "pushCbcCbcInt: no equivalent CbcIntParam for "
385                  << "parameter code `" << code << "'." << std::endl ;
386        retval = -1 ;
387        break ;
388    }
389    }
390
391    if (key != CbcModel::CbcLastIntParam) {
392        bool result = model->setIntParam(key, val) ;
393        if (result == false) {
394            retval = -1 ;
395        }
396    }
397
398    return (retval) ;
399}
400
401} // end namespace CbcCbcParamUtils
402
Note: See TracBrowser for help on using the repository browser.