source: branches/devel/Cbc/src/CbcGenSolvers.cpp @ 604

Last change on this file since 604 was 591, checked in by lou, 13 years ago

Initial commit of cbc-generic source.

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