0
2
0
1 | 1 |
/* -*- mode: C++; indent-tabs-mode: nil; -*- |
2 | 2 |
* |
3 | 3 |
* This file is a part of LEMON, a generic C++ optimization library. |
4 | 4 |
* |
5 | 5 |
* Copyright (C) 2003-2008 |
6 | 6 |
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
7 | 7 |
* (Egervary Research Group on Combinatorial Optimization, EGRES). |
8 | 8 |
* |
9 | 9 |
* Permission to use, modify and distribute this software is granted |
10 | 10 |
* provided that this copyright notice appears in all copies. For |
11 | 11 |
* precise terms see the accompanying LICENSE file. |
12 | 12 |
* |
13 | 13 |
* This software is provided "AS IS" with no warranty of any kind, |
14 | 14 |
* express or implied, and with no claim as to its suitability for any |
15 | 15 |
* purpose. |
16 | 16 |
* |
17 | 17 |
*/ |
18 | 18 |
|
19 | 19 |
#include <iostream> |
20 | 20 |
#include <lemon/soplex.h> |
21 | 21 |
|
22 |
#include <soplex |
|
22 |
#include <soplex.h> |
|
23 | 23 |
|
24 | 24 |
|
25 | 25 |
///\file |
26 | 26 |
///\brief Implementation of the LEMON-SOPLEX lp solver interface. |
27 | 27 |
namespace lemon { |
28 | 28 |
|
29 | 29 |
SoplexLp::SoplexLp() { |
30 | 30 |
soplex = new soplex::SoPlex; |
31 | 31 |
} |
32 | 32 |
|
33 | 33 |
SoplexLp::~SoplexLp() { |
34 | 34 |
delete soplex; |
35 | 35 |
} |
36 | 36 |
|
37 | 37 |
SoplexLp::SoplexLp(const SoplexLp& lp) { |
38 | 38 |
rows = lp.rows; |
39 | 39 |
cols = lp.cols; |
40 | 40 |
|
41 | 41 |
soplex = new soplex::SoPlex; |
42 | 42 |
(*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex); |
43 | 43 |
|
44 | 44 |
_col_names = lp._col_names; |
45 | 45 |
_col_names_ref = lp._col_names_ref; |
46 | 46 |
|
47 | 47 |
_row_names = lp._row_names; |
48 | 48 |
_row_names_ref = lp._row_names_ref; |
49 | 49 |
|
50 | 50 |
} |
51 | 51 |
|
52 | 52 |
void SoplexLp::_clear_temporals() { |
53 | 53 |
_primal_values.clear(); |
54 | 54 |
_dual_values.clear(); |
55 | 55 |
} |
56 | 56 |
|
57 | 57 |
SoplexLp* SoplexLp::_newSolver() const { |
58 | 58 |
SoplexLp* newlp = new SoplexLp(); |
59 | 59 |
return newlp; |
60 | 60 |
} |
61 | 61 |
|
62 | 62 |
SoplexLp* SoplexLp::_cloneSolver() const { |
63 | 63 |
SoplexLp* newlp = new SoplexLp(*this); |
64 | 64 |
return newlp; |
65 | 65 |
} |
66 | 66 |
|
67 | 67 |
const char* SoplexLp::_solverName() const { return "SoplexLp"; } |
68 | 68 |
|
69 | 69 |
int SoplexLp::_addCol() { |
70 | 70 |
soplex::LPCol c; |
71 | 71 |
c.setLower(-soplex::infinity); |
72 | 72 |
c.setUpper(soplex::infinity); |
73 | 73 |
soplex->addCol(c); |
74 | 74 |
|
75 | 75 |
_col_names.push_back(std::string()); |
76 | 76 |
|
77 | 77 |
return soplex->nCols() - 1; |
78 | 78 |
} |
79 | 79 |
|
80 | 80 |
int SoplexLp::_addRow() { |
81 | 81 |
soplex::LPRow r; |
82 | 82 |
r.setLhs(-soplex::infinity); |
83 | 83 |
r.setRhs(soplex::infinity); |
84 | 84 |
soplex->addRow(r); |
85 | 85 |
|
86 | 86 |
_row_names.push_back(std::string()); |
87 | 87 |
|
88 | 88 |
return soplex->nRows() - 1; |
89 | 89 |
} |
90 | 90 |
|
91 | 91 |
|
92 | 92 |
void SoplexLp::_eraseCol(int i) { |
93 | 93 |
soplex->removeCol(i); |
94 | 94 |
_col_names_ref.erase(_col_names[i]); |
95 | 95 |
_col_names[i] = _col_names.back(); |
96 | 96 |
_col_names_ref[_col_names.back()] = i; |
97 | 97 |
_col_names.pop_back(); |
98 | 98 |
} |
99 | 99 |
|
100 | 100 |
void SoplexLp::_eraseRow(int i) { |
101 | 101 |
soplex->removeRow(i); |
102 | 102 |
_row_names_ref.erase(_row_names[i]); |
103 | 103 |
_row_names[i] = _row_names.back(); |
104 | 104 |
_row_names_ref[_row_names.back()] = i; |
105 | 105 |
_row_names.pop_back(); |
106 | 106 |
} |
107 | 107 |
|
108 | 108 |
void SoplexLp::_eraseColId(int i) { |
109 | 109 |
cols.eraseIndex(i); |
110 | 110 |
cols.relocateIndex(i, cols.maxIndex()); |
111 | 111 |
} |
112 | 112 |
void SoplexLp::_eraseRowId(int i) { |
113 | 113 |
rows.eraseIndex(i); |
114 | 114 |
rows.relocateIndex(i, rows.maxIndex()); |
115 | 115 |
} |
116 | 116 |
|
117 | 117 |
void SoplexLp::_getColName(int c, std::string &name) const { |
118 | 118 |
name = _col_names[c]; |
119 | 119 |
} |
120 | 120 |
|
121 | 121 |
void SoplexLp::_setColName(int c, const std::string &name) { |
122 | 122 |
_col_names_ref.erase(_col_names[c]); |
123 | 123 |
_col_names[c] = name; |
124 | 124 |
if (!name.empty()) { |
125 | 125 |
_col_names_ref.insert(std::make_pair(name, c)); |
126 | 126 |
} |
127 | 127 |
} |
128 | 128 |
|
129 | 129 |
int SoplexLp::_colByName(const std::string& name) const { |
130 | 130 |
std::map<std::string, int>::const_iterator it = |
131 | 131 |
_col_names_ref.find(name); |
132 | 132 |
if (it != _col_names_ref.end()) { |
133 | 133 |
return it->second; |
134 | 134 |
} else { |
135 | 135 |
return -1; |
136 | 136 |
} |
137 | 137 |
} |
138 | 138 |
|
139 | 139 |
void SoplexLp::_getRowName(int r, std::string &name) const { |
140 | 140 |
name = _row_names[r]; |
141 | 141 |
} |
142 | 142 |
|
143 | 143 |
void SoplexLp::_setRowName(int r, const std::string &name) { |
144 | 144 |
_row_names_ref.erase(_row_names[r]); |
145 | 145 |
_row_names[r] = name; |
146 | 146 |
if (!name.empty()) { |
147 | 147 |
_row_names_ref.insert(std::make_pair(name, r)); |
148 | 148 |
} |
149 | 149 |
} |
150 | 150 |
|
151 | 151 |
int SoplexLp::_rowByName(const std::string& name) const { |
152 | 152 |
std::map<std::string, int>::const_iterator it = |
153 | 153 |
_row_names_ref.find(name); |
154 | 154 |
if (it != _row_names_ref.end()) { |
155 | 155 |
return it->second; |
156 | 156 |
} else { |
157 | 157 |
return -1; |
158 | 158 |
} |
159 | 159 |
} |
160 | 160 |
|
161 | 161 |
|
162 | 162 |
void SoplexLp::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) { |
163 | 163 |
for (int j = 0; j < soplex->nCols(); ++j) { |
164 | 164 |
soplex->changeElement(i, j, 0.0); |
165 | 165 |
} |
166 | 166 |
for(ExprIterator it = b; it != e; ++it) { |
167 | 167 |
soplex->changeElement(i, it->first, it->second); |
168 | 168 |
} |
169 | 169 |
} |
170 | 170 |
|
171 | 171 |
void SoplexLp::_getRowCoeffs(int i, InsertIterator b) const { |
172 | 172 |
const soplex::SVector& vec = soplex->rowVector(i); |
173 | 173 |
for (int k = 0; k < vec.size(); ++k) { |
174 | 174 |
*b = std::make_pair(vec.index(k), vec.value(k)); |
175 | 175 |
++b; |
176 | 176 |
} |
177 | 177 |
} |
178 | 178 |
|
179 | 179 |
void SoplexLp::_setColCoeffs(int j, ExprIterator b, ExprIterator e) { |
180 | 180 |
for (int i = 0; i < soplex->nRows(); ++i) { |
181 | 181 |
soplex->changeElement(i, j, 0.0); |
182 | 182 |
} |
183 | 183 |
for(ExprIterator it = b; it != e; ++it) { |
184 | 184 |
soplex->changeElement(it->first, j, it->second); |
185 | 185 |
} |
186 | 186 |
} |
187 | 187 |
|
188 | 188 |
void SoplexLp::_getColCoeffs(int i, InsertIterator b) const { |
189 | 189 |
const soplex::SVector& vec = soplex->colVector(i); |
190 | 190 |
for (int k = 0; k < vec.size(); ++k) { |
191 | 191 |
*b = std::make_pair(vec.index(k), vec.value(k)); |
192 | 192 |
++b; |
193 | 193 |
} |
194 | 194 |
} |
195 | 195 |
|
196 | 196 |
void SoplexLp::_setCoeff(int i, int j, Value value) { |
197 | 197 |
soplex->changeElement(i, j, value); |
198 | 198 |
} |
199 | 199 |
|
200 | 200 |
SoplexLp::Value SoplexLp::_getCoeff(int i, int j) const { |
201 | 201 |
return soplex->rowVector(i)[j]; |
202 | 202 |
} |
203 | 203 |
|
204 | 204 |
void SoplexLp::_setColLowerBound(int i, Value value) { |
205 | 205 |
LEMON_ASSERT(value != INF, "Invalid bound"); |
206 | 206 |
soplex->changeLower(i, value != -INF ? value : -soplex::infinity); |
207 | 207 |
} |
208 | 208 |
|
209 | 209 |
SoplexLp::Value SoplexLp::_getColLowerBound(int i) const { |
210 | 210 |
double value = soplex->lower(i); |
211 | 211 |
return value != -soplex::infinity ? value : -INF; |
212 | 212 |
} |
213 | 213 |
|
214 | 214 |
void SoplexLp::_setColUpperBound(int i, Value value) { |
215 | 215 |
LEMON_ASSERT(value != -INF, "Invalid bound"); |
216 | 216 |
soplex->changeUpper(i, value != INF ? value : soplex::infinity); |
217 | 217 |
} |
218 | 218 |
|
219 | 219 |
SoplexLp::Value SoplexLp::_getColUpperBound(int i) const { |
220 | 220 |
double value = soplex->upper(i); |
221 | 221 |
return value != soplex::infinity ? value : INF; |
222 | 222 |
} |
223 | 223 |
|
224 | 224 |
void SoplexLp::_setRowLowerBound(int i, Value lb) { |
225 | 225 |
LEMON_ASSERT(lb != INF, "Invalid bound"); |
226 | 226 |
soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i)); |
227 | 227 |
} |
228 | 228 |
|
229 | 229 |
SoplexLp::Value SoplexLp::_getRowLowerBound(int i) const { |
230 | 230 |
double res = soplex->lhs(i); |
231 | 231 |
return res == -soplex::infinity ? -INF : res; |
232 | 232 |
} |
233 | 233 |
|
234 | 234 |
void SoplexLp::_setRowUpperBound(int i, Value ub) { |
235 | 235 |
LEMON_ASSERT(ub != -INF, "Invalid bound"); |
236 | 236 |
soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity); |
237 | 237 |
} |
238 | 238 |
|
239 | 239 |
SoplexLp::Value SoplexLp::_getRowUpperBound(int i) const { |
240 | 240 |
double res = soplex->rhs(i); |
241 | 241 |
return res == soplex::infinity ? INF : res; |
242 | 242 |
} |
243 | 243 |
|
244 | 244 |
void SoplexLp::_setObjCoeffs(ExprIterator b, ExprIterator e) { |
245 | 245 |
for (int j = 0; j < soplex->nCols(); ++j) { |
246 | 246 |
soplex->changeObj(j, 0.0); |
247 | 247 |
} |
248 | 248 |
for (ExprIterator it = b; it != e; ++it) { |
249 | 249 |
soplex->changeObj(it->first, it->second); |
250 | 250 |
} |
251 | 251 |
} |
252 | 252 |
|
253 | 253 |
void SoplexLp::_getObjCoeffs(InsertIterator b) const { |
254 | 254 |
for (int j = 0; j < soplex->nCols(); ++j) { |
255 | 255 |
Value coef = soplex->obj(j); |
256 | 256 |
if (coef != 0.0) { |
257 | 257 |
*b = std::make_pair(j, coef); |
258 | 258 |
++b; |
259 | 259 |
} |
260 | 260 |
} |
261 | 261 |
} |
262 | 262 |
|
263 | 263 |
void SoplexLp::_setObjCoeff(int i, Value obj_coef) { |
264 | 264 |
soplex->changeObj(i, obj_coef); |
265 | 265 |
} |
266 | 266 |
|
267 | 267 |
SoplexLp::Value SoplexLp::_getObjCoeff(int i) const { |
268 | 268 |
return soplex->obj(i); |
269 | 269 |
} |
270 | 270 |
|
271 | 271 |
SoplexLp::SolveExitStatus SoplexLp::_solve() { |
272 | 272 |
|
273 | 273 |
_clear_temporals(); |
274 | 274 |
|
275 | 275 |
soplex::SPxSolver::Status status = soplex->solve(); |
276 | 276 |
|
277 | 277 |
switch (status) { |
278 | 278 |
case soplex::SPxSolver::OPTIMAL: |
279 | 279 |
case soplex::SPxSolver::INFEASIBLE: |
280 | 280 |
case soplex::SPxSolver::UNBOUNDED: |
281 | 281 |
return SOLVED; |
282 | 282 |
default: |
283 | 283 |
return UNSOLVED; |
284 | 284 |
} |
285 | 285 |
} |
286 | 286 |
|
287 | 287 |
SoplexLp::Value SoplexLp::_getPrimal(int i) const { |
288 | 288 |
if (_primal_values.empty()) { |
289 | 289 |
_primal_values.resize(soplex->nCols()); |
290 | 290 |
soplex::Vector pv(_primal_values.size(), &_primal_values.front()); |
291 | 291 |
soplex->getPrimal(pv); |
292 | 292 |
} |
293 | 293 |
return _primal_values[i]; |
294 | 294 |
} |
295 | 295 |
|
296 | 296 |
SoplexLp::Value SoplexLp::_getDual(int i) const { |
297 | 297 |
if (_dual_values.empty()) { |
298 | 298 |
_dual_values.resize(soplex->nRows()); |
299 | 299 |
soplex::Vector dv(_dual_values.size(), &_dual_values.front()); |
300 | 300 |
soplex->getDual(dv); |
301 | 301 |
} |
302 | 302 |
return _dual_values[i]; |
303 | 303 |
} |
304 | 304 |
|
305 | 305 |
SoplexLp::Value SoplexLp::_getPrimalValue() const { |
306 | 306 |
return soplex->objValue(); |
307 | 307 |
} |
308 | 308 |
|
309 | 309 |
SoplexLp::VarStatus SoplexLp::_getColStatus(int i) const { |
310 | 310 |
switch (soplex->getBasisColStatus(i)) { |
311 | 311 |
case soplex::SPxSolver::BASIC: |
312 | 312 |
return BASIC; |
313 | 313 |
case soplex::SPxSolver::ON_UPPER: |
314 | 314 |
return UPPER; |
315 | 315 |
case soplex::SPxSolver::ON_LOWER: |
316 | 316 |
return LOWER; |
317 | 317 |
case soplex::SPxSolver::FIXED: |
318 | 318 |
return FIXED; |
319 | 319 |
case soplex::SPxSolver::ZERO: |
320 | 320 |
return FREE; |
321 | 321 |
default: |
322 | 322 |
LEMON_ASSERT(false, "Wrong column status"); |
323 | 323 |
return VarStatus(); |
324 | 324 |
} |
325 | 325 |
} |
326 | 326 |
|
327 | 327 |
SoplexLp::VarStatus SoplexLp::_getRowStatus(int i) const { |
328 | 328 |
switch (soplex->getBasisRowStatus(i)) { |
329 | 329 |
case soplex::SPxSolver::BASIC: |
330 | 330 |
return BASIC; |
331 | 331 |
case soplex::SPxSolver::ON_UPPER: |
332 | 332 |
return UPPER; |
333 | 333 |
case soplex::SPxSolver::ON_LOWER: |
334 | 334 |
return LOWER; |
335 | 335 |
case soplex::SPxSolver::FIXED: |
336 | 336 |
return FIXED; |
337 | 337 |
case soplex::SPxSolver::ZERO: |
338 | 338 |
return FREE; |
339 | 339 |
default: |
340 | 340 |
LEMON_ASSERT(false, "Wrong row status"); |
341 | 341 |
return VarStatus(); |
342 | 342 |
} |
343 | 343 |
} |
344 | 344 |
|
345 | 345 |
SoplexLp::Value SoplexLp::_getPrimalRay(int i) const { |
346 | 346 |
if (_primal_ray.empty()) { |
347 | 347 |
_primal_ray.resize(soplex->nCols()); |
348 | 348 |
soplex::Vector pv(_primal_ray.size(), &_primal_ray.front()); |
349 | 349 |
soplex->getDualfarkas(pv); |
350 | 350 |
} |
351 | 351 |
return _primal_ray[i]; |
352 | 352 |
} |
353 | 353 |
|
354 | 354 |
SoplexLp::Value SoplexLp::_getDualRay(int i) const { |
355 | 355 |
if (_dual_ray.empty()) { |
356 | 356 |
_dual_ray.resize(soplex->nRows()); |
357 | 357 |
soplex::Vector dv(_dual_ray.size(), &_dual_ray.front()); |
358 | 358 |
soplex->getDualfarkas(dv); |
359 | 359 |
} |
360 | 360 |
return _dual_ray[i]; |
361 | 361 |
} |
362 | 362 |
|
363 | 363 |
SoplexLp::ProblemType SoplexLp::_getPrimalType() const { |
364 | 364 |
switch (soplex->status()) { |
365 | 365 |
case soplex::SPxSolver::OPTIMAL: |
366 | 366 |
return OPTIMAL; |
367 | 367 |
case soplex::SPxSolver::UNBOUNDED: |
368 | 368 |
return UNBOUNDED; |
369 | 369 |
case soplex::SPxSolver::INFEASIBLE: |
370 | 370 |
return INFEASIBLE; |
371 | 371 |
default: |
372 | 372 |
return UNDEFINED; |
373 | 373 |
} |
374 | 374 |
} |
375 | 375 |
|
376 | 376 |
SoplexLp::ProblemType SoplexLp::_getDualType() const { |
377 | 377 |
switch (soplex->status()) { |
378 | 378 |
case soplex::SPxSolver::OPTIMAL: |
379 | 379 |
return OPTIMAL; |
380 | 380 |
case soplex::SPxSolver::UNBOUNDED: |
381 | 381 |
return UNBOUNDED; |
382 | 382 |
case soplex::SPxSolver::INFEASIBLE: |
383 | 383 |
return INFEASIBLE; |
384 | 384 |
default: |
385 | 385 |
return UNDEFINED; |
386 | 386 |
} |
387 | 387 |
} |
388 | 388 |
|
389 | 389 |
void SoplexLp::_setSense(Sense sense) { |
390 | 390 |
switch (sense) { |
391 | 391 |
case MIN: |
392 | 392 |
soplex->changeSense(soplex::SPxSolver::MINIMIZE); |
393 | 393 |
break; |
394 | 394 |
case MAX: |
395 | 395 |
soplex->changeSense(soplex::SPxSolver::MAXIMIZE); |
396 | 396 |
} |
397 | 397 |
} |
398 | 398 |
|
399 | 399 |
SoplexLp::Sense SoplexLp::_getSense() const { |
400 | 400 |
switch (soplex->spxSense()) { |
401 | 401 |
case soplex::SPxSolver::MAXIMIZE: |
402 | 402 |
return MAX; |
403 | 403 |
case soplex::SPxSolver::MINIMIZE: |
404 | 404 |
return MIN; |
405 | 405 |
default: |
406 | 406 |
LEMON_ASSERT(false, "Wrong sense."); |
1 | 1 |
AC_DEFUN([LX_CHECK_SOPLEX], |
2 | 2 |
[ |
3 | 3 |
AC_ARG_WITH([soplex], |
4 | 4 |
AS_HELP_STRING([--with-soplex@<:@=PREFIX@:>@], [search for SOPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@]) |
5 | 5 |
AS_HELP_STRING([--without-soplex], [disable checking for SOPLEX]), |
6 | 6 |
[], [with_soplex=yes]) |
7 | 7 |
|
8 | 8 |
AC_ARG_WITH([soplex-includedir], |
9 | 9 |
AS_HELP_STRING([--with-soplex-includedir=DIR], [search for SOPLEX headers in DIR]), |
10 | 10 |
[], [with_soplex_includedir=no]) |
11 | 11 |
|
12 | 12 |
AC_ARG_WITH([soplex-libdir], |
13 | 13 |
AS_HELP_STRING([--with-soplex-libdir=DIR], [search for SOPLEX libraries in DIR]), |
14 | 14 |
[], [with_soplex_libdir=no]) |
15 | 15 |
|
16 | 16 |
lx_soplex_found=no |
17 | 17 |
if test x"$with_soplex" != x"no"; then |
18 | 18 |
AC_MSG_CHECKING([for SOPLEX]) |
19 | 19 |
|
20 | 20 |
if test x"$with_soplex_includedir" != x"no"; then |
21 | 21 |
SOPLEX_CXXFLAGS="-I$with_soplex_includedir" |
22 | 22 |
elif test x"$with_soplex" != x"yes"; then |
23 |
SOPLEX_CXXFLAGS="-I$with_soplex/ |
|
23 |
SOPLEX_CXXFLAGS="-I$with_soplex/src" |
|
24 | 24 |
fi |
25 | 25 |
|
26 | 26 |
if test x"$with_soplex_libdir" != x"no"; then |
27 | 27 |
SOPLEX_LDFLAGS="-L$with_soplex_libdir" |
28 | 28 |
elif test x"$with_soplex" != x"yes"; then |
29 | 29 |
SOPLEX_LDFLAGS="-L$with_soplex/lib" |
30 | 30 |
fi |
31 | 31 |
SOPLEX_LIBS="-lsoplex -lz" |
32 | 32 |
|
33 | 33 |
lx_save_cxxflags="$CXXFLAGS" |
34 | 34 |
lx_save_ldflags="$LDFLAGS" |
35 | 35 |
lx_save_libs="$LIBS" |
36 | 36 |
CXXFLAGS="$SOPLEX_CXXFLAGS" |
37 | 37 |
LDFLAGS="$SOPLEX_LDFLAGS" |
38 | 38 |
LIBS="$SOPLEX_LIBS" |
39 | 39 |
|
40 | 40 |
lx_soplex_test_prog=' |
41 |
#include <soplex |
|
41 |
#include <soplex.h> |
|
42 | 42 |
|
43 | 43 |
int main(int argc, char** argv) |
44 | 44 |
{ |
45 | 45 |
soplex::SoPlex soplex; |
46 | 46 |
return 0; |
47 | 47 |
}' |
48 | 48 |
|
49 | 49 |
AC_LANG_PUSH(C++) |
50 | 50 |
AC_LINK_IFELSE([$lx_soplex_test_prog], [lx_soplex_found=yes], [lx_soplex_found=no]) |
51 | 51 |
AC_LANG_POP(C++) |
52 | 52 |
|
53 | 53 |
CXXFLAGS="$lx_save_cxxflags" |
54 | 54 |
LDFLAGS="$lx_save_ldflags" |
55 | 55 |
LIBS="$lx_save_libs" |
56 | 56 |
|
57 | 57 |
if test x"$lx_soplex_found" = x"yes"; then |
58 | 58 |
AC_DEFINE([HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.]) |
59 | 59 |
lx_lp_found=yes |
60 | 60 |
AC_DEFINE([HAVE_LP], [1], [Define to 1 if you have any LP solver.]) |
61 | 61 |
AC_MSG_RESULT([yes]) |
62 | 62 |
else |
63 | 63 |
SOPLEX_CXXFLAGS="" |
64 | 64 |
SOPLEX_LDFLAGS="" |
65 | 65 |
SOPLEX_LIBS="" |
66 | 66 |
AC_MSG_RESULT([no]) |
67 | 67 |
fi |
68 | 68 |
fi |
69 | 69 |
SOPLEX_LIBS="$SOPLEX_LDFLAGS $SOPLEX_LIBS" |
70 | 70 |
AC_SUBST(SOPLEX_CXXFLAGS) |
71 | 71 |
AC_SUBST(SOPLEX_LIBS) |
72 | 72 |
AM_CONDITIONAL([HAVE_SOPLEX], [test x"$lx_soplex_found" = x"yes"]) |
73 | 73 |
]) |
0 comments (0 inline)