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) { |
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)