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

Last change on this file since 836 was 836, checked in by lou, 14 years ago

Updates to match OsiMsk? updates, Osi r1140.

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