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