Limbo 3.5.4
Loading...
Searching...
No Matches
LPSolveApi.h
Go to the documentation of this file.
1
7
8#ifndef LIMBO_SOLVERS_API_LPSOLVEAPI_H
9#define LIMBO_SOLVERS_API_LPSOLVEAPI_H
10
11#include <iostream>
12#include <string>
13#include <vector>
14#include <list>
16// make sure lpsolve is configured properly
17extern "C"
18{
19#include "lp_lib.h" // use lpsolve as ILP solver
20}
21
22// lpsolve has macro definitions that cause conflicts
23// temporarily uncomment them
24#undef OPTIMAL
25#undef SUBOPTIMAL
26#undef INFEASIBLE
27#undef UNBOUNDED
32{
33 switch (status)
34 {
35 case 0: // OPTIMAL
36 case 8: // PRESOLVED
38 case 1: // SUBOPTIMAL
39 case 6: // USERABORT
40 case 7: // TIMEOUT
42 case 2: // INFEASIBLE
43 case 4: // DEGENERATE
44 case 5: // NUMFAILURE, numerical failure
45 case 25: // NUMFAILURE, accuracy error encountered
47 case 3: // UNBOUNDED
49 default:
50 limboAssertMsg(0, "unknown status %d", status);
51 }
52}
53
55namespace limbo
56{
58namespace solvers
59{
60
63{
64 public:
67 : m_verbose(SEVERE)
68 , m_bbRule(NODE_PSEUDONONINTSELECT|NODE_RCOSTFIXING)
69 // various options in presolve to tune
70 // I found PRESOLVE_COLDOMINATE may result in INFEASIBLE model, which may be a bug in lpsolve
71 // PRESOLVE_COLDOMINATE is buggy, do not use it
72 , m_presolve(PRESOLVE_ROWS+PRESOLVE_COLS+PRESOLVE_LINDEP+PRESOLVE_SOS+PRESOLVE_REDUCEMIP+PRESOLVE_KNAPSACK
73 +PRESOLVE_ELIMEQ2+PRESOLVE_IMPLIEDFREE+PRESOLVE_REDUCEGCD+PRESOLVE_PROBEFIX+PRESOLVE_PROBEREDUCE
74 +PRESOLVE_ROWDOMINATE/*+PRESOLVE_COLDOMINATE*/+PRESOLVE_MERGEROWS+PRESOLVE_COLFIXDUAL
75 +PRESOLVE_BOUNDS/*+PRESOLVE_DUALS+PRESOLVE_SENSDUALS*/)
76 {
77 }
78
79 virtual ~LPSolveParameters() {}
82 virtual void operator()(lprec* lp) const
83 {
84 set_verbose(lp, m_verbose);
85 // various options in presolve to tune
86 set_bb_rule(lp, m_bbRule);
87 set_presolve(lp, m_presolve, get_presolveloops(lp));
88 }
89
92 void setVerbose(int v) {m_verbose = v;}
95 void setBbRule(int v) {m_bbRule = v;}
98 void setPresolve(int v) {m_presolve = v;}
99
100 protected:
104};
105
108template <typename T, typename V>
110{
111 public:
115 typedef typename model_type::coefficient_value_type coefficient_value_type;
116 typedef typename model_type::variable_value_type variable_value_type;
117 typedef typename model_type::variable_type variable_type;
118 typedef typename model_type::constraint_type constraint_type;
119 typedef typename model_type::expression_type expression_type;
120 typedef typename model_type::term_type term_type;
121 typedef typename model_type::property_type property_type;
122 typedef LPSolveParameters parameter_type;
124
128 : m_model(model)
129 , m_lpModel(NULL)
130 {
131 }
132
134 {
135 }
136
139 SolverProperty operator()(parameter_type* param = NULL)
140 {
141 bool defaultParam = false;
142 if (param == NULL)
143 {
144 param = new LPSolveParameters;
145 defaultParam = true;
146 }
147
148 // column indices
149 std::vector<int> vIdx;
150 // coefficients
151 std::vector<double> vValue;
152 // buffer for name
153 char buf[64];
154
155 m_lpModel = make_lp(m_model->constraints().size(), m_model->numVariables());
156
157 set_lp_name(m_lpModel, (char*)"LPSolveLinearApi");
158 // set verbose level
159 set_verbose(m_lpModel, SEVERE);
160
161 // create variables
162 for (unsigned int i = 0, ie = m_model->numVariables(); i < ie; ++i)
163 {
164 variable_type var (i);
165 limboAssertMsg(set_bounds(m_lpModel, i+1, m_model->variableLowerBound(var), m_model->variableUpperBound(var)), "failed to set bounds of variable for LP");
166 sprintf(buf, "%s", m_model->variableName(var).c_str());
167 limboAssertMsg(set_col_name(m_lpModel, i+1, buf), "failed to set name of variable %s", m_model->variableName(var).c_str());
168 switch (m_model->variableNumericType(var))
169 {
170 case CONTINUOUS:
171 break;
172 case BINARY:
173 limboAssertMsg(set_binary(m_lpModel, i+1, TRUE), "failed to set binary variable for LP");
174 break;
175 case INTEGER:
176 limboAssertMsg(set_int(m_lpModel, i+1, TRUE), "failed to set integer variable for LP");
177 break;
178 default:
179 limboAssertMsg(0, "unknown numeric type");
180 }
181 }
182
183 // create objective
184 vIdx.clear();
185 vValue.clear();
186 for (typename std::vector<term_type>::const_iterator it = m_model->objective().terms().begin(), ite = m_model->objective().terms().end(); it != ite; ++it)
187 {
188 vIdx.push_back(it->variable().id()+1); // variable id starts from 1 for LPSolve
189 vValue.push_back(it->coefficient());
190 }
191 limboAssertMsg(set_obj_fnex(m_lpModel, vIdx.size(), &vValue[0], &vIdx[0]), "failed to set objective for LP");
192 if (m_model->optimizeType() == MIN)
193 {
194 set_minim(m_lpModel);
195 }
196 else
197 {
198 set_maxim(m_lpModel);
199 }
200
201 // create constraints
202 for (unsigned int i = 0, ie = m_model->constraints().size(); i < ie; ++i)
203 {
204 constraint_type const& constr = m_model->constraints().at(i);
205
206 vIdx.clear();
207 vValue.clear();
208 for (typename std::vector<term_type>::const_iterator it = constr.expression().terms().begin(), ite = constr.expression().terms().end(); it != ite; ++it)
209 {
210 vIdx.push_back(it->variable().id()+1); // variable id starts from 1 for LPSolve
211 vValue.push_back(it->coefficient());
212 }
213
214 limboAssertMsg(set_rowex(m_lpModel, i+1, vIdx.size(), &vValue[0], &vIdx[0]), "failed to set constraint for LP");
215 switch (constr.sense())
216 {
217 case '>':
218 limboAssertMsg(set_constr_type(m_lpModel, i+1, GE), "failed to set constraint type for LP");
219 break;
220 case '<':
221 limboAssertMsg(set_constr_type(m_lpModel, i+1, LE), "failed to set constraint type for LP");
222 break;
223 case '=':
224 limboAssertMsg(set_constr_type(m_lpModel, i+1, EQ), "failed to set constraint type for LP");
225 break;
226 default:
227 limboAssertMsg(0, "unknown sense");
228 }
229 limboAssertMsg(set_rh(m_lpModel, i+1, constr.rightHandSide()), "failed to set constraint right-hand side for LP");
230 sprintf(buf, "%s", m_model->constraintName(constr).c_str());
231 limboAssertMsg(set_row_name(m_lpModel, i+1, buf), "failed to set constraint name %s for LP", m_model->constraintName(constr).c_str());
232 }
233
234 // solve LP
235#ifdef DEBUG_LPSOLVEAPI
236 write_lp(m_lpModel, (char*)"problem.lp");
237#endif
238 set_scaling(m_lpModel, SCALE_RANGE);
239 // call parameter setting before optimization
240 param->operator()(m_lpModel);
241 int status = solve(m_lpModel);
242
243 // apply solution
244 for (unsigned int i = 0; i < m_model->numVariables(); ++i)
245 {
246 REAL value = get_var_primalresult(m_lpModel, m_model->constraints().size()+1+i);
247 m_model->setVariableSolution(m_model->variable(i), value);
248 }
249
250#ifdef DEBUG_LPSOLVEAPI
251 std::vector<REAL> vSol (1+m_model->constraints().size()+m_model->numVariables());
252 limboAssertMsg(get_primal_solution(m_lpModel, &vSol[0]), "failed to get_primal_solution for LP");
253 std::ofstream out ("problem.sol");
254 limboAssertMsg(out.good(), "failed to open %s for write", "problem.sol");
255 out << "# Solution for model " << get_lp_name(m_lpModel) << "\n";
256 out << "# Objective value = " << get_objective(m_lpModel) << "\n";
257 for (unsigned int i = 0; i < m_model->numVariables(); ++i)
258 {
259 out << get_col_name(m_lpModel, i+1) << " " << vSol[1+m_model->constraints().size()+i] << "\n";
260 }
261 out.close();
262#endif
263
264 if (defaultParam)
265 delete param;
266 delete_lp(m_lpModel);
267
268 return getSolveStatus(status);
269 //switch (status)
270 //{
271 // case 0: // OPTIMAL
272 // case 8: // PRESOLVED
273 // return OPTIMAL;
274 // case 1: // SUBOPTIMAL
275 // case 6: // USERABORT
276 // case 7: // TIMEOUT
277 // return SUBOPTIMAL;
278 // case 2: // INFEASIBLE
279 // case 4: // DEGENERATE
280 // case 5: // NUMFAILURE, numerical failure
281 // case 25: // NUMFAILURE, accuracy error encountered
282 // return INFEASIBLE;
283 // case 3: // UNBOUNDED
284 // return UNBOUNDED;
285 // default:
286 // limboAssertMsg(0, "unknown status %d", status);
287 //}
288 }
289 protected:
296
298 lprec* m_lpModel;
299};
300
301} // namespace solvers
302} // namespace limbo
303
304#endif
#define limboAssertMsg(condition, args...)
custom assertion with message
Definition AssertMsg.h:24
limbo::solvers::SolverProperty getSolveStatus(int status)
convert lpsolve status to limbo::solvers status
Definition LPSolveApi.h:31
Basic utilities such as variables and linear expressions in solvers.
lprec * m_lpModel
model for LPSolve
Definition LPSolveApi.h:298
LPSolveLinearApi(model_type *model)
constructor
Definition LPSolveApi.h:127
SolverProperty operator()(parameter_type *param=NULL)
API to run the algorithm.
Definition LPSolveApi.h:139
LPSolveLinearApi & operator=(LPSolveLinearApi const &rhs)
assignment, forbidden
model_type * m_model
model for the problem
Definition LPSolveApi.h:297
LinearModel< T, V > model_type
linear model type for the problem
Definition LPSolveApi.h:113
LPSolveLinearApi(LPSolveLinearApi const &rhs)
copy constructor, forbidden
Base class for custom LPSolve parameters.
Definition LPSolveApi.h:63
int m_bbRule
branch and bound rule
Definition LPSolveApi.h:102
virtual void operator()(lprec *lp) const
customize environment
Definition LPSolveApi.h:82
void setPresolve(int v)
set presolve strategy
Definition LPSolveApi.h:98
void setBbRule(int v)
set branch and bound rule
Definition LPSolveApi.h:95
int m_presolve
presolve strategy
Definition LPSolveApi.h:103
void setVerbose(int v)
set verbose level
Definition LPSolveApi.h:92
virtual ~LPSolveParameters()
destructor
Definition LPSolveApi.h:79
coefficient_value_type rightHandSide() const
Definition Solvers.h:1034
expression_type const & expression() const
Definition Solvers.h:1028
std::vector< term_type > const & terms() const
Definition Solvers.h:655
model to describe an optimization problem
Definition Solvers.h:1161
V variable_value_type
V variable.
Definition Solvers.h:1166
VariableProperty< variable_value_type > property_type
variable property type
Definition Solvers.h:1178
Variable< coefficient_value_type > variable_type
variable type
Definition Solvers.h:1170
T coefficient_value_type
T coefficient.
Definition Solvers.h:1164
LinearConstraint< coefficient_value_type > constraint_type
constraint type
Definition Solvers.h:1176
LinearExpression< coefficient_value_type > expression_type
expression type
Definition Solvers.h:1174
LinearTerm< coefficient_value_type > term_type
term type
Definition Solvers.h:1172
namespace for Limbo.Solvers
SolverProperty
Some enums used in solver.
Definition Solvers.h:30
@ OPTIMAL
optimally solved
Definition Solvers.h:36
@ CONTINUOUS
floating point number
Definition Solvers.h:35
@ BINARY
binary number
Definition Solvers.h:33
@ MIN
minimize objective
Definition Solvers.h:31
@ SUBOPTIMAL
the model is suboptimal
Definition Solvers.h:38
@ INFEASIBLE
the model is infeasible
Definition Solvers.h:37
@ UNBOUNDED
the model is unbounded
Definition Solvers.h:39
@ INTEGER
integer number
Definition Solvers.h:34
namespace for Limbo