source: trunk/Cbc/src/CbcGenSolvers.cpp @ 1464

Last change on this file since 1464 was 1464, checked in by stefan, 9 years ago

merge split branch into trunk; fix some examples

File size: 6.6 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/*
9  This file contains routines related to handling Osi solvers. The technique
10  is to maintain a map of OsiSolverInterface objects as prototypes of the
11  available solvers.
12*/
13
14#include "CbcConfig.h"
15#include "CoinPragma.hpp"
16
17#include "OsiSolverInterface.hpp"
18
19/*
20  Include class definitions for the solvers that are available. If
21  CBC_DEFAULT_SOLVER is not defined in CbcConfig.h, set it to the first
22  available solver.
23
24  NOTE: Processing of keyword parameters is made case-independent by forcing
25        lower case comparison. Maps, on the other hand, are case-sensitive.
26        The solver names given here must contain only lower case letters and
27        must match the keywords used when defining the keywords for the
28        solver parameter.
29*/
30
31#ifdef COIN_HAS_CLP
32# include "OsiClpSolverInterface.hpp"
33# ifndef CBC_DEFAULT_SOLVER
34#   define CBC_DEFAULT_SOLVER "clp"
35# endif
36#endif
37
38#ifdef COIN_HAS_CPX
39# include "OsiCpxSolverInterface.hpp"
40# ifndef CBC_DEFAULT_SOLVER
41#   define CBC_DEFAULT_SOLVER "cpx"
42# endif
43#endif
44
45#ifdef COIN_HAS_DYLP
46# include "OsiDylpSolverInterface.hpp"
47# ifndef CBC_DEFAULT_SOLVER
48#   define CBC_DEFAULT_SOLVER "dylp"
49# endif
50#endif
51
52#ifdef COIN_HAS_GLPK
53# include "OsiGlpkSolverInterface.hpp"
54# ifndef CBC_DEFAULT_SOLVER
55#   define CBC_DEFAULT_SOLVER "glpk"
56# endif
57#endif
58
59#ifdef COIN_HAS_MSK
60# include "OsiMskSolverInterface.hpp"
61# ifndef CBC_DEFAULT_SOLVER
62#   define CBC_DEFAULT_SOLVER "msk"
63# endif
64#endif
65
66#include "CoinParam.hpp"
67
68#include "CbcModel.hpp"
69#include "CbcGenCtlBlk.hpp"
70
71#include "CbcGenParam.hpp"
72#include "CbcGenCbcParam.hpp"
73#include "CbcGenOsiParam.hpp"
74
75namespace {
76
77char svnid[] = "$Id: CbcGenSolvers.cpp 1173 2009-06-04 09:44:10Z forrest $" ;
78
79}
80
81/*
82  Unnamed local namespace to hide the data structures used to maintain the
83  vector of OsiSolverInterface objects.
84*/
85
86namespace {
87
88/*
89  Data types for a vector of OsiSolverInterface objects.
90*/
91typedef std::map<std::string, OsiSolverInterface*> solverMap_t ;
92typedef solverMap_t::const_iterator solverMapIter_t ;
93
94/*
95  The solver map.
96*/
97
98solverMap_t solvers ;
99
100} // end unnamed local namespace
101
102
103namespace CbcGenSolvers {
104
105/*
106  Create a vector of solver prototypes and establish a default solver.
107
108  Creating multiple solvers is moderately expensive; if you're not interested
109  in experimenting with solvers other than clp, you're likely better off just
110  working with the cbc main program (CoinSolve.cpp).
111
112  The businesss with CBC_DEFAULT_SOLVER will select the first available
113  solver as the default, unless overridden at compile time.
114
115*/
116
117OsiSolverInterface *setupSolvers ()
118
119{
120    /*
121      Populate the vector of OsiSolverInterface objects.
122    */
123# ifdef COIN_HAS_CLP
124    solvers["clp"] = new OsiClpSolverInterface ;
125# endif
126# ifdef COIN_HAS_CPX
127    solvers["cpx"] = new OsiCpxSolverInterface ;
128# endif
129# ifdef COIN_HAS_DYLP
130    solvers["dylp"] = new OsiDylpSolverInterface  ;
131# endif
132# ifdef COIN_HAS_GLPK
133    solvers["glpk"] = new OsiGlpkSolverInterface  ;
134# endif
135# ifdef COIN_HAS_MSK
136    solvers["msk"] = new OsiMskSolverInterface  ;
137# endif
138    /*
139      Set the standard default values in each solver.
140    */
141    for (solverMapIter_t solverIter = solvers.begin() ;
142            solverIter != solvers.end() ;
143            solverIter++) {
144        OsiSolverInterface *osi = solverIter->second ;
145        osi->messageHandler()->setLogLevel(0) ;
146        CbcOsiParamUtils::setOsiSolverInterfaceDefaults(osi) ;
147    }
148    /*
149      If we don't have a default solver, we're deeply confused.
150    */
151    OsiSolverInterface *dflt_solver = solvers[CBC_DEFAULT_SOLVER] ;
152    if (dflt_solver) {
153        std::cout << "Default solver is " << CBC_DEFAULT_SOLVER << std::endl ;
154    } else {
155        std::cerr << "No solvers!" << std::endl ;
156    }
157
158    return (dflt_solver) ;
159}
160
161
162/*
163  Cleanup routine to delete the vector of OsiSolverInterface objects.
164*/
165
166void deleteSolvers ()
167{
168    for (solverMapIter_t solverIter = solvers.begin() ;
169            solverIter != solvers.end() ;
170            solverIter++) {
171        if (solverIter->second) delete solverIter->second ;
172    }
173}
174
175/*
176  The `push' routine for the solver parameter.
177
178  The basic operation is to clone the requested solver and assign it to the
179  current CbcModel object.
180*/
181
182int changeCbcSolver (CoinParam *param)
183
184{
185    assert (param != 0) ;
186    CbcGenParam *genParam = dynamic_cast<CbcGenParam *>(param) ;
187    assert (genParam != 0) ;
188    CbcGenCtlBlk *ctlBlk = genParam->obj() ;
189    assert (ctlBlk != 0) ;
190    CoinMessageHandler *msghandler = ctlBlk->messageHandler() ;
191    /*
192      Setup to return nonfatal/fatal error (1/-1) by default.
193    */
194    int retval ;
195    if (CoinParamUtils::isInteractive()) {
196        retval = 1 ;
197    } else {
198        retval = -1 ;
199    }
200    /*
201      Try to locate the solver specified by the user.
202    */
203    const std::string solverName = genParam->kwdVal() ;
204    OsiSolverInterface *protoOsi = solvers[solverName] ;
205    if (protoOsi == 0) {
206        std::cerr
207            << "Can't find solver \"" << solverName
208            << "\" in the solvers vector." << std::endl ;
209        return (retval) ;
210    }
211    ctlBlk->dfltSolver_ = protoOsi ;
212    /*
213      We have a solver.
214    */
215    ctlBlk->message(CBCGEN_NEW_SOLVER)
216    << solverName << CoinMessageEol ;
217    CbcModel *model = ctlBlk->model_ ;
218    assert (model != 0) ;
219    OsiSolverInterface *newOsi = protoOsi->clone() ;
220    model->assignSolver(newOsi) ;
221
222    return (0) ;
223}
224
225
226/*
227  This routine sets up a solver parameter object. It doesn't initialise the
228  object being acted upon (a CbcGenCtlBlk); that's done back in the calling
229  routine where we're setting up the cbc-generic parameter vector.
230*/
231
232void setupSolverParam (CbcGenParam &solverParam)
233
234{
235    /*
236      Basic setup: parameter type, name, parameter code.
237    */
238    solverParam.setType(CoinParam::coinParamKwd) ;
239    solverParam.setName("solver") ;
240    solverParam.setParamCode(CbcGenParam::SOLVER) ;
241    /*
242      Add the solvers and set the default value.
243    */
244    for (solverMapIter_t solverIter = solvers.begin() ;
245            solverIter != solvers.end() ;
246            solverIter++) {
247        solverParam.appendKwd(solverIter->first) ;
248    }
249    solverParam.setKwdVal(CBC_DEFAULT_SOLVER) ;
250    solverParam.setDisplay(true) ;
251    solverParam.setPushFunc(changeCbcSolver) ;
252    /*
253      And add the help strings.
254    */
255    solverParam.setShortHelp("Specify underlying LP solver") ;
256    solverParam.setLongHelp(
257        "Select the underlying LP solver that will be used to solve the continuous relaxations of subproblems."
258    ) ;
259}
260
261} // end namespace CbcGenSolvers
262
Note: See TracBrowser for help on using the repository browser.