19 ///\file |
19 ///\file |
20 ///\brief Implementation of the LEMON-GLPK lp solver interface. |
20 ///\brief Implementation of the LEMON-GLPK lp solver interface. |
21 |
21 |
22 #include <lemon/lp_glpk.h> |
22 #include <lemon/lp_glpk.h> |
23 //#include <iostream> |
23 //#include <iostream> |
|
24 |
|
25 #if GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION > 15) |
|
26 #define LEMON_glp(func) (glp_##func) |
|
27 #define LEMON_lpx(func) (lpx_##func) |
|
28 |
|
29 #define LEMON_GLP(def) (GLP_##def) |
|
30 #define LEMON_LPX(def) (LPX_##def) |
|
31 |
|
32 #else |
|
33 |
|
34 #define LEMON_glp(func) (lpx_##func) |
|
35 #define LEMON_lpx(func) (lpx_##func) |
|
36 |
|
37 #define LEMON_GLP(def) (LPX_##def) |
|
38 #define LEMON_LPX(def) (LPX_##def) |
|
39 |
|
40 #endif |
|
41 |
24 namespace lemon { |
42 namespace lemon { |
25 |
43 |
26 |
|
27 LpGlpk::LpGlpk() : Parent() { |
44 LpGlpk::LpGlpk() : Parent() { |
|
45 solved = false; |
28 rows = _lp_bits::LpId(1); |
46 rows = _lp_bits::LpId(1); |
29 cols = _lp_bits::LpId(1); |
47 cols = _lp_bits::LpId(1); |
30 lp = lpx_create_prob(); |
48 lp = LEMON_glp(create_prob)(); |
31 lpx_create_index(lp); |
49 LEMON_glp(create_index)(lp); |
32 ///\todo control function for this: |
50 LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_DUAL), 1); |
33 lpx_set_int_parm(lp, LPX_K_DUAL, 1); |
|
34 messageLevel(0); |
51 messageLevel(0); |
35 } |
52 } |
36 |
53 |
37 LpGlpk::LpGlpk(const LpGlpk &glp) : Parent() { |
54 LpGlpk::LpGlpk(const LpGlpk &glp) : Parent() { |
|
55 solved = false; |
38 rows = _lp_bits::LpId(1); |
56 rows = _lp_bits::LpId(1); |
39 cols = _lp_bits::LpId(1); |
57 cols = _lp_bits::LpId(1); |
40 lp = lpx_create_prob(); |
58 lp = LEMON_glp(create_prob)(); |
41 lpx_create_index(lp); |
59 LEMON_glp(create_index)(lp); |
42 ///\todo control function for this: |
60 ///\todo control function for this: |
43 lpx_set_int_parm(lp, LPX_K_DUAL, 1); |
61 LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_DUAL), 1); |
44 messageLevel(0); |
62 messageLevel(0); |
45 //Coefficient matrix, row bounds |
63 //Coefficient matrix, row bounds |
46 lpx_add_rows(lp, lpx_get_num_rows(glp.lp)); |
64 LEMON_glp(add_rows)(lp, LEMON_glp(get_num_rows)(glp.lp)); |
47 lpx_add_cols(lp, lpx_get_num_cols(glp.lp)); |
65 LEMON_glp(add_cols)(lp, LEMON_glp(get_num_cols)(glp.lp)); |
48 int len; |
66 int len; |
49 int ind[1+lpx_get_num_cols(glp.lp)]; |
67 int ind[1+LEMON_glp(get_num_cols)(glp.lp)]; |
50 Value val[1+lpx_get_num_cols(glp.lp)]; |
68 Value val[1+LEMON_glp(get_num_cols)(glp.lp)]; |
51 for (int i=1;i<=lpx_get_num_rows(glp.lp);++i) |
69 for (int i=1;i<=LEMON_glp(get_num_rows)(glp.lp);++i) |
52 { |
70 { |
53 len=lpx_get_mat_row(glp.lp,i,ind,val); |
71 len=LEMON_glp(get_mat_row)(glp.lp,i,ind,val); |
54 lpx_set_mat_row(lp, i,len,ind,val); |
72 LEMON_glp(set_mat_row)(lp, i,len,ind,val); |
55 lpx_set_row_bnds(lp,i,lpx_get_row_type(glp.lp,i), |
73 LEMON_glp(set_row_bnds)(lp,i, |
56 lpx_get_row_lb(glp.lp,i),lpx_get_row_ub(glp.lp,i)); |
74 LEMON_glp(get_row_type)(glp.lp,i), |
|
75 LEMON_glp(get_row_lb)(glp.lp,i), |
|
76 LEMON_glp(get_row_ub)(glp.lp,i)); |
57 } |
77 } |
58 |
78 |
59 //Objective function, coloumn bounds |
79 //Objective function, coloumn bounds |
60 lpx_set_obj_dir(lp, lpx_get_obj_dir(glp.lp)); |
80 LEMON_glp(set_obj_dir)(lp, LEMON_glp(get_obj_dir)(glp.lp)); |
61 //Objectif function's constant term treated separately |
81 //Objectif function's constant term treated separately |
62 lpx_set_obj_coef(lp,0,lpx_get_obj_coef(glp.lp,0)); |
82 LEMON_glp(set_obj_coef)(lp,0,LEMON_glp(get_obj_coef)(glp.lp,0)); |
63 for (int i=1;i<=lpx_get_num_cols(glp.lp);++i) |
83 for (int i=1;i<=LEMON_glp(get_num_cols)(glp.lp);++i) |
64 { |
84 { |
65 lpx_set_obj_coef(lp,i,lpx_get_obj_coef(glp.lp,i)); |
85 LEMON_glp(set_obj_coef)(lp,i, |
66 lpx_set_col_bnds(lp,i,lpx_get_col_type(glp.lp,i), |
86 LEMON_glp(get_obj_coef)(glp.lp,i)); |
67 lpx_get_col_lb(glp.lp,i),lpx_get_col_ub(glp.lp,i)); |
87 LEMON_glp(set_col_bnds)(lp,i, |
|
88 LEMON_glp(get_col_type)(glp.lp,i), |
|
89 LEMON_glp(get_col_lb)(glp.lp,i), |
|
90 LEMON_glp(get_col_ub)(glp.lp,i)); |
68 } |
91 } |
69 } |
92 } |
70 |
93 |
71 LpGlpk::~LpGlpk() { |
94 LpGlpk::~LpGlpk() { |
72 lpx_delete_prob(lp); |
95 LEMON_glp(delete_prob)(lp); |
73 } |
96 } |
74 |
97 |
75 int LpGlpk::_addCol() { |
98 int LpGlpk::_addCol() { |
76 int i=lpx_add_cols(lp, 1); |
99 int i=LEMON_glp(add_cols)(lp, 1); |
77 _setColLowerBound(i, -INF); |
100 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), 0.0, 0.0); |
78 _setColUpperBound(i, INF); |
101 solved = false; |
79 return i; |
102 return i; |
80 } |
103 } |
81 |
104 |
82 ///\e |
105 ///\e |
83 |
106 |
95 LpGlpk* newlp=new LpGlpk(*this); |
118 LpGlpk* newlp=new LpGlpk(*this); |
96 return *newlp; |
119 return *newlp; |
97 } |
120 } |
98 |
121 |
99 int LpGlpk::_addRow() { |
122 int LpGlpk::_addRow() { |
100 int i=lpx_add_rows(lp, 1); |
123 int i=LEMON_glp(add_rows)(lp, 1); |
|
124 solved = false; |
101 return i; |
125 return i; |
102 } |
126 } |
103 |
127 |
104 |
128 |
105 void LpGlpk::_eraseCol(int i) { |
129 void LpGlpk::_eraseCol(int i) { |
106 int ca[2]; |
130 int ca[2]; |
107 ca[1]=i; |
131 ca[1]=i; |
108 lpx_del_cols(lp, 1, ca); |
132 LEMON_glp(del_cols)(lp, 1, ca); |
|
133 solved = false; |
109 } |
134 } |
110 |
135 |
111 void LpGlpk::_eraseRow(int i) { |
136 void LpGlpk::_eraseRow(int i) { |
112 int ra[2]; |
137 int ra[2]; |
113 ra[1]=i; |
138 ra[1]=i; |
114 lpx_del_rows(lp, 1, ra); |
139 LEMON_glp(del_rows)(lp, 1, ra); |
|
140 solved = false; |
115 } |
141 } |
116 |
142 |
117 void LpGlpk::_getColName(int c, std::string & name) const |
143 void LpGlpk::_getColName(int c, std::string & name) const |
118 { |
144 { |
119 |
145 |
120 char *n = lpx_get_col_name(lp,c); |
146 const char *n = LEMON_glp(get_col_name)(lp,c); |
121 name = n?n:""; |
147 name = n?n:""; |
122 } |
148 } |
123 |
149 |
124 |
150 |
125 void LpGlpk::_setColName(int c, const std::string & name) |
151 void LpGlpk::_setColName(int c, const std::string & name) |
126 { |
152 { |
127 lpx_set_col_name(lp,c,const_cast<char*>(name.c_str())); |
153 LEMON_glp(set_col_name)(lp,c,const_cast<char*>(name.c_str())); |
128 |
154 |
129 } |
155 } |
130 |
156 |
131 int LpGlpk::_colByName(const std::string& name) const |
157 int LpGlpk::_colByName(const std::string& name) const |
132 { |
158 { |
133 int k = lpx_find_col(lp, const_cast<char*>(name.c_str())); |
159 int k = LEMON_glp(find_col)(lp, const_cast<char*>(name.c_str())); |
134 return k > 0 ? k : -1; |
160 return k > 0 ? k : -1; |
135 } |
161 } |
136 |
162 |
137 |
163 |
138 void LpGlpk::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) |
164 void LpGlpk::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) |
146 for(ConstRowIterator it=b; it!=e; ++it) { |
172 for(ConstRowIterator it=b; it!=e; ++it) { |
147 indices.push_back(it->first); |
173 indices.push_back(it->first); |
148 values.push_back(it->second); |
174 values.push_back(it->second); |
149 } |
175 } |
150 |
176 |
151 lpx_set_mat_row(lp, i, values.size() - 1, &indices[0], &values[0]); |
177 LEMON_glp(set_mat_row)(lp, i, values.size() - 1, |
|
178 &indices[0], &values[0]); |
|
179 |
|
180 solved = false; |
152 } |
181 } |
153 |
182 |
154 void LpGlpk::_getRowCoeffs(int ix, RowIterator b) const |
183 void LpGlpk::_getRowCoeffs(int ix, RowIterator b) const |
155 { |
184 { |
156 int length = lpx_get_mat_row(lp, ix, 0, 0); |
185 int length = LEMON_glp(get_mat_row)(lp, ix, 0, 0); |
157 |
186 |
158 std::vector<int> indices(length + 1); |
187 std::vector<int> indices(length + 1); |
159 std::vector<Value> values(length + 1); |
188 std::vector<Value> values(length + 1); |
160 |
189 |
161 lpx_get_mat_row(lp, ix, &indices[0], &values[0]); |
190 LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]); |
162 |
191 |
163 for (int i = 1; i <= length; ++i) { |
192 for (int i = 1; i <= length; ++i) { |
164 *b = std::make_pair(indices[i], values[i]); |
193 *b = std::make_pair(indices[i], values[i]); |
165 ++b; |
194 ++b; |
166 } |
195 } |
177 for(ConstColIterator it=b; it!=e; ++it) { |
206 for(ConstColIterator it=b; it!=e; ++it) { |
178 indices.push_back(it->first); |
207 indices.push_back(it->first); |
179 values.push_back(it->second); |
208 values.push_back(it->second); |
180 } |
209 } |
181 |
210 |
182 lpx_set_mat_col(lp, ix, values.size() - 1, &indices[0], &values[0]); |
211 LEMON_glp(set_mat_col)(lp, ix, values.size() - 1, |
|
212 &indices[0], &values[0]); |
|
213 |
|
214 solved = false; |
183 } |
215 } |
184 |
216 |
185 void LpGlpk::_getColCoeffs(int ix, ColIterator b) const |
217 void LpGlpk::_getColCoeffs(int ix, ColIterator b) const |
186 { |
218 { |
187 int length = lpx_get_mat_col(lp, ix, 0, 0); |
219 int length = LEMON_glp(get_mat_col)(lp, ix, 0, 0); |
188 |
220 |
189 std::vector<int> indices(length + 1); |
221 std::vector<int> indices(length + 1); |
190 std::vector<Value> values(length + 1); |
222 std::vector<Value> values(length + 1); |
191 |
223 |
192 lpx_get_mat_col(lp, ix, &indices[0], &values[0]); |
224 LEMON_glp(get_mat_col)(lp, ix, &indices[0], &values[0]); |
193 |
225 |
194 for (int i = 1; i <= length; ++i) { |
226 for (int i = 1; i <= length; ++i) { |
195 *b = std::make_pair(indices[i], values[i]); |
227 *b = std::make_pair(indices[i], values[i]); |
196 ++b; |
228 ++b; |
197 } |
229 } |
198 } |
230 } |
199 |
231 |
200 void LpGlpk::_setCoeff(int ix, int jx, Value value) |
232 void LpGlpk::_setCoeff(int ix, int jx, Value value) |
201 { |
233 { |
202 |
234 |
203 if (lpx_get_num_cols(lp) < lpx_get_num_rows(lp)) { |
235 if (LEMON_glp(get_num_cols)(lp) < LEMON_glp(get_num_rows)(lp)) { |
204 |
236 |
205 int length=lpx_get_mat_row(lp, ix, 0, 0); |
237 int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0); |
206 |
238 |
207 std::vector<int> indices(length + 2); |
239 std::vector<int> indices(length + 2); |
208 std::vector<Value> values(length + 2); |
240 std::vector<Value> values(length + 2); |
209 |
241 |
210 lpx_get_mat_row(lp, ix, &indices[0], &values[0]); |
242 LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]); |
211 |
243 |
212 //The following code does not suppose that the elements of the |
244 //The following code does not suppose that the elements of the |
213 //array indices are sorted |
245 //array indices are sorted |
214 bool found=false; |
246 bool found=false; |
215 for (int i = 1; i <= length; ++i) { |
247 for (int i = 1; i <= length; ++i) { |
223 ++length; |
255 ++length; |
224 indices[length]=jx; |
256 indices[length]=jx; |
225 values[length]=value; |
257 values[length]=value; |
226 } |
258 } |
227 |
259 |
228 lpx_set_mat_row(lp, ix, length, &indices[0], &values[0]); |
260 LEMON_glp(set_mat_row)(lp, ix, length, &indices[0], &values[0]); |
229 |
261 |
230 } else { |
262 } else { |
231 |
263 |
232 int length=lpx_get_mat_col(lp, jx, 0, 0); |
264 int length=LEMON_glp(get_mat_col)(lp, jx, 0, 0); |
233 |
265 |
234 std::vector<int> indices(length + 2); |
266 std::vector<int> indices(length + 2); |
235 std::vector<Value> values(length + 2); |
267 std::vector<Value> values(length + 2); |
236 |
268 |
237 lpx_get_mat_col(lp, jx, &indices[0], &values[0]); |
269 LEMON_glp(get_mat_col)(lp, jx, &indices[0], &values[0]); |
238 |
270 |
239 //The following code does not suppose that the elements of the |
271 //The following code does not suppose that the elements of the |
240 //array indices are sorted |
272 //array indices are sorted |
241 bool found=false; |
273 bool found=false; |
242 for (int i = 1; i <= length; ++i) { |
274 for (int i = 1; i <= length; ++i) { |
250 ++length; |
282 ++length; |
251 indices[length]=ix; |
283 indices[length]=ix; |
252 values[length]=value; |
284 values[length]=value; |
253 } |
285 } |
254 |
286 |
255 lpx_set_mat_col(lp, jx, length, &indices[0], &values[0]); |
287 LEMON_glp(set_mat_col)(lp, jx, length, &indices[0], &values[0]); |
256 } |
288 } |
|
289 |
|
290 solved = false; |
257 } |
291 } |
258 |
292 |
259 LpGlpk::Value LpGlpk::_getCoeff(int ix, int jx) const |
293 LpGlpk::Value LpGlpk::_getCoeff(int ix, int jx) const |
260 { |
294 { |
261 |
295 |
262 int length=lpx_get_mat_row(lp, ix, 0, 0); |
296 int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0); |
263 |
297 |
264 std::vector<int> indices(length + 1); |
298 std::vector<int> indices(length + 1); |
265 std::vector<Value> values(length + 1); |
299 std::vector<Value> values(length + 1); |
266 |
300 |
267 lpx_get_mat_row(lp, ix, &indices[0], &values[0]); |
301 LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]); |
268 |
302 |
269 //The following code does not suppose that the elements of the |
303 //The following code does not suppose that the elements of the |
270 //array indices are sorted |
304 //array indices are sorted |
271 for (int i = 1; i <= length; ++i) { |
305 for (int i = 1; i <= length; ++i) { |
272 if (indices[i]==jx){ |
306 if (indices[i]==jx){ |
281 void LpGlpk::_setColLowerBound(int i, Value lo) |
315 void LpGlpk::_setColLowerBound(int i, Value lo) |
282 { |
316 { |
283 if (lo==INF) { |
317 if (lo==INF) { |
284 //FIXME error |
318 //FIXME error |
285 } |
319 } |
286 int b=lpx_get_col_type(lp, i); |
320 int b=LEMON_glp(get_col_type)(lp, i); |
287 double up=lpx_get_col_ub(lp, i); |
321 double up=LEMON_glp(get_col_ub)(lp, i); |
288 if (lo==-INF) { |
322 if (lo==-INF) { |
289 switch (b) { |
323 switch (b) { |
290 case LPX_FR: |
324 case LEMON_GLP(FR): |
291 case LPX_LO: |
325 case LEMON_GLP(LO): |
292 lpx_set_col_bnds(lp, i, LPX_FR, lo, up); |
326 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up); |
293 break; |
327 break; |
294 case LPX_UP: |
328 case LEMON_GLP(UP): |
295 break; |
329 break; |
296 case LPX_DB: |
330 case LEMON_GLP(DB): |
297 case LPX_FX: |
331 case LEMON_GLP(FX): |
298 lpx_set_col_bnds(lp, i, LPX_UP, lo, up); |
332 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up); |
299 break; |
333 break; |
300 default: ; |
334 default: ; |
301 //FIXME error |
335 //FIXME error |
302 } |
336 } |
303 } else { |
337 } else { |
304 switch (b) { |
338 switch (b) { |
305 case LPX_FR: |
339 case LEMON_GLP(FR): |
306 case LPX_LO: |
340 case LEMON_GLP(LO): |
307 lpx_set_col_bnds(lp, i, LPX_LO, lo, up); |
341 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up); |
308 break; |
342 break; |
309 case LPX_UP: |
343 case LEMON_GLP(UP): |
310 case LPX_DB: |
344 case LEMON_GLP(DB): |
311 case LPX_FX: |
345 case LEMON_GLP(FX): |
312 if (lo==up) |
346 if (lo==up) |
313 lpx_set_col_bnds(lp, i, LPX_FX, lo, up); |
347 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up); |
314 else |
348 else |
315 lpx_set_col_bnds(lp, i, LPX_DB, lo, up); |
349 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up); |
316 break; |
350 break; |
317 default: ; |
351 default: ; |
318 //FIXME error |
352 //FIXME error |
319 } |
353 } |
320 } |
354 } |
321 |
355 |
|
356 solved = false; |
322 } |
357 } |
323 |
358 |
324 LpGlpk::Value LpGlpk::_getColLowerBound(int i) const |
359 LpGlpk::Value LpGlpk::_getColLowerBound(int i) const |
325 { |
360 { |
326 int b=lpx_get_col_type(lp, i); |
361 int b=LEMON_glp(get_col_type)(lp, i); |
327 switch (b) { |
362 switch (b) { |
328 case LPX_LO: |
363 case LEMON_GLP(LO): |
329 case LPX_DB: |
364 case LEMON_GLP(DB): |
330 case LPX_FX: |
365 case LEMON_GLP(FX): |
331 return lpx_get_col_lb(lp, i); |
366 return LEMON_glp(get_col_lb)(lp, i); |
332 default: ; |
367 default: ; |
333 return -INF; |
368 return -INF; |
334 } |
369 } |
335 } |
370 } |
336 |
371 |
337 void LpGlpk::_setColUpperBound(int i, Value up) |
372 void LpGlpk::_setColUpperBound(int i, Value up) |
338 { |
373 { |
339 if (up==-INF) { |
374 if (up==-INF) { |
340 //FIXME error |
375 //FIXME error |
341 } |
376 } |
342 int b=lpx_get_col_type(lp, i); |
377 int b=LEMON_glp(get_col_type)(lp, i); |
343 double lo=lpx_get_col_lb(lp, i); |
378 double lo=LEMON_glp(get_col_lb)(lp, i); |
344 if (up==INF) { |
379 if (up==INF) { |
345 switch (b) { |
380 switch (b) { |
346 case LPX_FR: |
381 case LEMON_GLP(FR): |
347 case LPX_LO: |
382 case LEMON_GLP(LO): |
348 break; |
383 break; |
349 case LPX_UP: |
384 case LEMON_GLP(UP): |
350 lpx_set_col_bnds(lp, i, LPX_FR, lo, up); |
385 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up); |
351 break; |
386 break; |
352 case LPX_DB: |
387 case LEMON_GLP(DB): |
353 case LPX_FX: |
388 case LEMON_GLP(FX): |
354 lpx_set_col_bnds(lp, i, LPX_LO, lo, up); |
389 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up); |
355 break; |
390 break; |
356 default: ; |
391 default: ; |
357 //FIXME error |
392 //FIXME error |
358 } |
393 } |
359 } else { |
394 } else { |
360 switch (b) { |
395 switch (b) { |
361 case LPX_FR: |
396 case LEMON_GLP(FR): |
362 lpx_set_col_bnds(lp, i, LPX_UP, lo, up); |
397 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up); |
363 break; |
398 break; |
364 case LPX_UP: |
399 case LEMON_GLP(UP): |
365 lpx_set_col_bnds(lp, i, LPX_UP, lo, up); |
400 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up); |
366 break; |
401 break; |
367 case LPX_LO: |
402 case LEMON_GLP(LO): |
368 case LPX_DB: |
403 case LEMON_GLP(DB): |
369 case LPX_FX: |
404 case LEMON_GLP(FX): |
370 if (lo==up) |
405 if (lo==up) |
371 lpx_set_col_bnds(lp, i, LPX_FX, lo, up); |
406 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up); |
372 else |
407 else |
373 lpx_set_col_bnds(lp, i, LPX_DB, lo, up); |
408 LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up); |
374 break; |
409 break; |
375 default: ; |
410 default: ; |
376 //FIXME error |
411 //FIXME error |
377 } |
412 } |
378 } |
413 } |
|
414 |
|
415 solved = false; |
379 } |
416 } |
380 |
417 |
381 LpGlpk::Value LpGlpk::_getColUpperBound(int i) const |
418 LpGlpk::Value LpGlpk::_getColUpperBound(int i) const |
382 { |
419 { |
383 int b=lpx_get_col_type(lp, i); |
420 int b=LEMON_glp(get_col_type)(lp, i); |
384 switch (b) { |
421 switch (b) { |
385 case LPX_UP: |
422 case LEMON_GLP(UP): |
386 case LPX_DB: |
423 case LEMON_GLP(DB): |
387 case LPX_FX: |
424 case LEMON_GLP(FX): |
388 return lpx_get_col_ub(lp, i); |
425 return LEMON_glp(get_col_ub)(lp, i); |
389 default: ; |
426 default: ; |
390 return INF; |
427 return INF; |
391 } |
428 } |
392 } |
429 } |
393 |
430 |
398 //FIXME error |
435 //FIXME error |
399 } |
436 } |
400 |
437 |
401 if (lb == -INF){ |
438 if (lb == -INF){ |
402 if (ub == INF){ |
439 if (ub == INF){ |
403 lpx_set_row_bnds(lp, i, LPX_FR, lb, ub); |
440 LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FR), lb, ub); |
404 } |
441 } |
405 else{ |
442 else{ |
406 lpx_set_row_bnds(lp, i, LPX_UP, lb, ub); |
443 LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(UP), lb, ub); |
407 } |
444 } |
408 } |
445 } |
409 else{ |
446 else{ |
410 if (ub==INF){ |
447 if (ub==INF){ |
411 lpx_set_row_bnds(lp, i, LPX_LO, lb, ub); |
448 LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(LO), lb, ub); |
412 |
449 |
413 } |
450 } |
414 else{ |
451 else{ |
415 if (lb == ub){ |
452 if (lb == ub){ |
416 lpx_set_row_bnds(lp, i, LPX_FX, lb, ub); |
453 LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FX), lb, ub); |
417 } |
454 } |
418 else{ |
455 else{ |
419 lpx_set_row_bnds(lp, i, LPX_DB, lb, ub); |
456 LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(DB), lb, ub); |
420 } |
457 } |
421 } |
458 } |
422 } |
459 } |
423 |
460 |
|
461 solved = false; |
424 } |
462 } |
425 |
463 |
426 void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub) const |
464 void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub) const |
427 { |
465 { |
428 |
466 |
429 int b=lpx_get_row_type(lp, i); |
467 int b=LEMON_glp(get_row_type)(lp, i); |
430 switch (b) { |
468 switch (b) { |
431 case LPX_FR: |
469 case LEMON_GLP(FR): |
432 case LPX_UP: |
470 case LEMON_GLP(UP): |
433 lb = -INF; |
471 lb = -INF; |
434 break; |
472 break; |
435 default: |
473 default: |
436 lb=lpx_get_row_lb(lp, i); |
474 lb=LEMON_glp(get_row_lb)(lp, i); |
437 } |
475 } |
438 |
476 |
439 switch (b) { |
477 switch (b) { |
440 case LPX_FR: |
478 case LEMON_GLP(FR): |
441 case LPX_LO: |
479 case LEMON_GLP(LO): |
442 ub = INF; |
480 ub = INF; |
443 break; |
481 break; |
444 default: |
482 default: |
445 ub=lpx_get_row_ub(lp, i); |
483 ub=LEMON_glp(get_row_ub)(lp, i); |
446 } |
484 } |
447 |
485 |
448 } |
486 } |
449 |
487 |
450 void LpGlpk::_setObjCoeff(int i, Value obj_coef) |
488 void LpGlpk::_setObjCoeff(int i, Value obj_coef) |
451 { |
489 { |
452 //i=0 means the constant term (shift) |
490 //i=0 means the constant term (shift) |
453 lpx_set_obj_coef(lp, i, obj_coef); |
491 LEMON_glp(set_obj_coef)(lp, i, obj_coef); |
|
492 |
|
493 solved = false; |
454 } |
494 } |
455 |
495 |
456 LpGlpk::Value LpGlpk::_getObjCoeff(int i) const { |
496 LpGlpk::Value LpGlpk::_getObjCoeff(int i) const { |
457 //i=0 means the constant term (shift) |
497 //i=0 means the constant term (shift) |
458 return lpx_get_obj_coef(lp, i); |
498 return LEMON_glp(get_obj_coef)(lp, i); |
459 } |
499 } |
460 |
500 |
461 void LpGlpk::_clearObj() |
501 void LpGlpk::_clearObj() |
462 { |
502 { |
463 for (int i=0;i<=lpx_get_num_cols(lp);++i){ |
503 for (int i=0;i<=LEMON_glp(get_num_cols)(lp);++i){ |
464 lpx_set_obj_coef(lp, i, 0); |
504 LEMON_glp(set_obj_coef)(lp, i, 0); |
465 } |
505 } |
|
506 |
|
507 solved = false; |
466 } |
508 } |
467 |
509 |
468 LpGlpk::SolveExitStatus LpGlpk::_solve() |
510 LpGlpk::SolveExitStatus LpGlpk::_solve() |
469 { |
511 { |
470 // A way to check the problem to be solved |
512 // A way to check the problem to be solved |
471 //lpx_write_cpxlp(lp,"naittvan.cpx"); |
513 //LEMON_glp(write_cpxlp(lp,"naittvan.cpx"); |
472 |
514 |
473 lpx_std_basis(lp); |
515 LEMON_lpx(std_basis)(lp); |
474 int i = lpx_simplex(lp); |
516 int i = LEMON_lpx(simplex)(lp); |
475 |
517 |
476 switch (i) { |
518 switch (i) { |
477 case LPX_E_OK: |
519 case LEMON_LPX(E_OK): |
|
520 solved = true; |
478 return SOLVED; |
521 return SOLVED; |
479 default: |
522 default: |
480 return UNSOLVED; |
523 return UNSOLVED; |
481 } |
524 } |
482 } |
525 } |
483 |
526 |
484 LpGlpk::Value LpGlpk::_getPrimal(int i) const |
527 LpGlpk::Value LpGlpk::_getPrimal(int i) const |
485 { |
528 { |
486 return lpx_get_col_prim(lp,i); |
529 return LEMON_glp(get_col_prim)(lp,i); |
487 } |
530 } |
488 |
531 |
489 LpGlpk::Value LpGlpk::_getDual(int i) const |
532 LpGlpk::Value LpGlpk::_getDual(int i) const |
490 { |
533 { |
491 return lpx_get_row_dual(lp,i); |
534 return LEMON_glp(get_row_dual)(lp,i); |
492 } |
535 } |
493 |
536 |
494 LpGlpk::Value LpGlpk::_getPrimalValue() const |
537 LpGlpk::Value LpGlpk::_getPrimalValue() const |
495 { |
538 { |
496 return lpx_get_obj_val(lp); |
539 return LEMON_glp(get_obj_val)(lp); |
497 } |
540 } |
498 bool LpGlpk::_isBasicCol(int i) const |
541 bool LpGlpk::_isBasicCol(int i) const |
499 { |
542 { |
500 return (lpx_get_col_stat(lp, i)==LPX_BS); |
543 return (LEMON_glp(get_col_stat)(lp, i)==LEMON_GLP(BS)); |
501 } |
544 } |
502 |
545 |
503 |
546 |
504 LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus() const |
547 LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus() const |
505 { |
548 { |
506 int stat= lpx_get_status(lp); |
549 if (!solved) return UNDEFINED; |
|
550 int stat= LEMON_lpx(get_status)(lp); |
507 switch (stat) { |
551 switch (stat) { |
508 case LPX_UNDEF://Undefined (no solve has been run yet) |
552 case LEMON_LPX(UNDEF)://Undefined (no solve has been run yet) |
509 return UNDEFINED; |
553 return UNDEFINED; |
510 case LPX_NOFEAS://There is no feasible solution (primal, I guess) |
554 case LEMON_LPX(NOFEAS)://There is no feasible solution (primal, I guess) |
511 case LPX_INFEAS://Infeasible |
555 case LEMON_LPX(INFEAS)://Infeasible |
512 return INFEASIBLE; |
556 return INFEASIBLE; |
513 case LPX_UNBND://Unbounded |
557 case LEMON_LPX(UNBND)://Unbounded |
514 return INFINITE; |
558 return INFINITE; |
515 case LPX_FEAS://Feasible |
559 case LEMON_LPX(FEAS)://Feasible |
516 return FEASIBLE; |
560 return FEASIBLE; |
517 case LPX_OPT://Feasible |
561 case LEMON_LPX(OPT)://Feasible |
518 return OPTIMAL; |
562 return OPTIMAL; |
519 default: |
563 default: |
520 return UNDEFINED; //to avoid gcc warning |
564 return UNDEFINED; //to avoid gcc warning |
521 //FIXME error |
565 //FIXME error |
522 } |
566 } |
523 } |
567 } |
524 |
568 |
525 LpGlpk::SolutionStatus LpGlpk::_getDualStatus() const |
569 LpGlpk::SolutionStatus LpGlpk::_getDualStatus() const |
526 { |
570 { |
527 switch (lpx_get_dual_stat(lp)) { |
571 if (!solved) return UNDEFINED; |
528 case LPX_D_UNDEF://Undefined (no solve has been run yet) |
572 switch (LEMON_lpx(get_dual_stat)(lp)) { |
|
573 case LEMON_LPX(D_UNDEF)://Undefined (no solve has been run yet) |
529 return UNDEFINED; |
574 return UNDEFINED; |
530 case LPX_D_NOFEAS://There is no dual feasible solution |
575 case LEMON_LPX(D_NOFEAS)://There is no dual feasible solution |
531 // case LPX_D_INFEAS://Infeasible |
576 // case LEMON_LPX(D_INFEAS://Infeasible |
532 return INFEASIBLE; |
577 return INFEASIBLE; |
533 case LPX_D_FEAS://Feasible |
578 case LEMON_LPX(D_FEAS)://Feasible |
534 switch (lpx_get_status(lp)) { |
579 switch (LEMON_lpx(get_status)(lp)) { |
535 case LPX_NOFEAS: |
580 case LEMON_LPX(NOFEAS): |
536 return INFINITE; |
581 return INFINITE; |
537 case LPX_OPT: |
582 case LEMON_LPX(OPT): |
538 return OPTIMAL; |
583 return OPTIMAL; |
539 default: |
584 default: |
540 return FEASIBLE; |
585 return FEASIBLE; |
541 } |
586 } |
542 default: |
587 default: |
545 } |
590 } |
546 } |
591 } |
547 |
592 |
548 LpGlpk::ProblemTypes LpGlpk::_getProblemType() const |
593 LpGlpk::ProblemTypes LpGlpk::_getProblemType() const |
549 { |
594 { |
550 //int stat= lpx_get_status(lp); |
595 if (!solved) return UNKNOWN; |
551 int statp= lpx_get_prim_stat(lp); |
596 //int stat= LEMON_glp(get_status(lp); |
552 int statd= lpx_get_dual_stat(lp); |
597 int statp= LEMON_lpx(get_prim_stat)(lp); |
553 if (statp==LPX_P_FEAS && statd==LPX_D_FEAS) |
598 int statd= LEMON_lpx(get_dual_stat)(lp); |
|
599 if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_FEAS)) |
554 return PRIMAL_DUAL_FEASIBLE; |
600 return PRIMAL_DUAL_FEASIBLE; |
555 if (statp==LPX_P_FEAS && statd==LPX_D_NOFEAS) |
601 if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_NOFEAS)) |
556 return PRIMAL_FEASIBLE_DUAL_INFEASIBLE; |
602 return PRIMAL_FEASIBLE_DUAL_INFEASIBLE; |
557 if (statp==LPX_P_NOFEAS && statd==LPX_D_FEAS) |
603 if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_FEAS)) |
558 return PRIMAL_INFEASIBLE_DUAL_FEASIBLE; |
604 return PRIMAL_INFEASIBLE_DUAL_FEASIBLE; |
559 if (statp==LPX_P_NOFEAS && statd==LPX_D_NOFEAS) |
605 if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_NOFEAS)) |
560 return PRIMAL_DUAL_INFEASIBLE; |
606 return PRIMAL_DUAL_INFEASIBLE; |
561 //In all other cases |
607 //In all other cases |
562 return UNKNOWN; |
608 return UNKNOWN; |
563 } |
609 } |
564 |
610 |
565 void LpGlpk::_setMax() |
611 void LpGlpk::_setMax() |
566 { |
612 { |
567 lpx_set_obj_dir(lp, LPX_MAX); |
613 solved = false; |
|
614 LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MAX)); |
568 } |
615 } |
569 |
616 |
570 void LpGlpk::_setMin() |
617 void LpGlpk::_setMin() |
571 { |
618 { |
572 lpx_set_obj_dir(lp, LPX_MIN); |
619 solved = false; |
|
620 LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MIN)); |
573 } |
621 } |
574 |
622 |
575 bool LpGlpk::_isMax() const |
623 bool LpGlpk::_isMax() const |
576 { |
624 { |
577 return (lpx_get_obj_dir(lp)==LPX_MAX); |
625 return (LEMON_glp(get_obj_dir)(lp)==LEMON_GLP(MAX)); |
578 } |
626 } |
579 |
627 |
580 |
628 |
581 |
629 |
582 void LpGlpk::messageLevel(int m) |
630 void LpGlpk::messageLevel(int m) |
583 { |
631 { |
584 lpx_set_int_parm(lp, LPX_K_MSGLEV, m); |
632 LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_MSGLEV), m); |
585 } |
633 } |
586 |
634 |
587 void LpGlpk::presolver(bool b) |
635 void LpGlpk::presolver(bool b) |
588 { |
636 { |
589 lpx_set_int_parm(lp, LPX_K_PRESOL, b); |
637 LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_PRESOL), b); |
590 } |
638 } |
591 |
639 |
592 |
640 |
593 } //END OF NAMESPACE LEMON |
641 } //END OF NAMESPACE LEMON |