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

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

add (back) option to use SoPlex? as LP solver

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