source: trunk/Cbc/src/CbcGenCbcParamUtils.cpp @ 1899

Last change on this file since 1899 was 1899, checked in by stefan, 6 years ago

fixup svn properties

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