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

Last change on this file since 855 was 855, checked in by lou, 11 years ago

Allow use of OsiCpx?, now that Matt's buffing it up a bit.

File size: 6.2 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
77  char svnid[] = "$Id$" ;
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  If we don't have a default solver, we're deeply confused.
149*/
150  OsiSolverInterface *dflt_solver = solvers[CBC_DEFAULT_SOLVER] ;
151  if (dflt_solver)
152  { std::cout << "Default solver is " << CBC_DEFAULT_SOLVER << std::endl ; }
153  else
154  { std::cerr << "No solvers!" << std::endl ; }
155
156  return (dflt_solver) ;
157}
158
159
160/*
161  Cleanup routine to delete the vector of OsiSolverInterface objects.
162*/
163
164void deleteSolvers ()
165{
166  for (solverMapIter_t solverIter = solvers.begin() ;
167         solverIter != solvers.end() ;
168         solverIter++)
169    { if (solverIter->second) delete solverIter->second ; }
170}
171
172/*
173  The `push' routine for the solver parameter.
174
175  The basic operation is to clone the requested solver and assign it to the
176  current CbcModel object.
177*/
178
179int changeCbcSolver (CoinParam *param)
180
181{ assert (param != 0) ;
182  CbcGenParam *genParam = dynamic_cast<CbcGenParam *>(param) ;
183  assert (genParam != 0) ;
184  CbcGenCtlBlk *ctlBlk = genParam->obj() ;
185  assert (ctlBlk != 0) ;
186  CoinMessageHandler *msghandler = ctlBlk->messageHandler() ;
187/*
188  Setup to return nonfatal/fatal error (1/-1) by default.
189*/
190  int retval ;
191  if (CoinParamUtils::isInteractive())
192  { retval = 1 ; }
193  else
194  { retval = -1 ; }
195/*
196  Try to locate the solver specified by the user.
197*/
198  const std::string solverName = genParam->kwdVal() ;
199  OsiSolverInterface *protoOsi = solvers[solverName] ;
200  if (protoOsi == 0)
201  { std::cerr
202      << "Can't find solver \"" << solverName
203      << "\" in the solvers vector." << std::endl ;
204    return (retval) ; }
205  ctlBlk->dfltSolver_ = protoOsi ;
206/*
207  We have a solver.
208*/
209  ctlBlk->message(CBCGEN_NEW_SOLVER)
210    << solverName << CoinMessageEol ;
211  CbcModel *model = ctlBlk->model_ ;
212  assert (model != 0) ;
213  OsiSolverInterface *newOsi = protoOsi->clone() ;
214  model->assignSolver(newOsi) ;
215
216  return (0) ; }
217
218
219/*
220  This routine sets up a solver parameter object. It doesn't initialise the
221  object being acted upon (a CbcGenCtlBlk); that's done back in the calling
222  routine where we're setting up the cbc-generic parameter vector.
223*/
224
225void setupSolverParam (CbcGenParam &solverParam)
226
227{
228/*
229  Basic setup: parameter type, name, parameter code.
230*/
231  solverParam.setType(CoinParam::coinParamKwd) ;
232  solverParam.setName("solver") ;
233  solverParam.setParamCode(CbcGenParam::SOLVER) ;
234/*
235  Add the solvers and set the default value.
236*/
237  for (solverMapIter_t solverIter = solvers.begin() ;
238       solverIter != solvers.end() ;
239       solverIter++)
240  { solverParam.appendKwd(solverIter->first) ; }
241  solverParam.setKwdVal(CBC_DEFAULT_SOLVER) ;
242  solverParam.setDisplay(true) ;
243  solverParam.setPushFunc(changeCbcSolver) ;
244/*
245  And add the help strings.
246*/
247  solverParam.setShortHelp("Specify underlying LP solver") ;
248  solverParam.setLongHelp(
249        "Select the underlying LP solver that will be used to solve the continuous relaxations of subproblems."
250        ) ;
251}
252
253} // end namespace CbcGenSolvers
254
Note: See TracBrowser for help on using the repository browser.