source: trunk/Cbc/src/CbcGenSolvers.cpp

Last change on this file was 2499, checked in by stefan, 9 months ago

add OsiHiGHS as additional LP solver option for CbcGeneric?

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