NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
2 * lemon/lp_glpk.cc - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_LP_GLPK_CC
18 #define LEMON_LP_GLPK_CC
21 ///\brief Implementation of the LEMON-GLPK lp solver interface.
23 #include <lemon/lp_glpk.h>
28 LpGlpk::LpGlpk() : Parent(),
29 lp(lpx_create_prob()) {
30 ///\todo constrol function for this:
31 lpx_set_int_parm(lp, LPX_K_DUAL, 1);
39 int LpGlpk::_addCol() {
40 int i=lpx_add_cols(lp, 1);
41 _setColLowerBound(i, -INF);
42 _setColUpperBound(i, INF);
49 LpSolverBase &LpGlpk::_newLp()
51 LpGlpk* newlp=new LpGlpk();
57 LpSolverBase &LpGlpk::_copyLp()
59 LpGlpk* newlp=new LpGlpk();
61 //Coefficient matrix, row bounds
62 lpx_add_rows(newlp->lp, lpx_get_num_rows(lp));
63 lpx_add_cols(newlp->lp, lpx_get_num_cols(lp));
65 int ind[1+lpx_get_num_cols(lp)];
66 Value val[1+lpx_get_num_cols(lp)];
67 for (int i=1;i<=lpx_get_num_rows(lp);++i){
68 len=lpx_get_mat_row(lp,i,ind,val);
69 lpx_set_mat_row(newlp->lp, i,len,ind,val);
70 lpx_set_row_bnds(newlp->lp,i,lpx_get_row_type(lp,i),
71 lpx_get_row_lb(lp,i),lpx_get_row_ub(lp,i));
74 //Objective function, coloumn bounds
75 lpx_set_obj_dir(newlp->lp, lpx_get_obj_dir(lp));
76 //Objectif function's constant term treated separately
77 lpx_set_obj_coef(newlp->lp,0,lpx_get_obj_coef(lp,0));
78 for (int i=1;i<=lpx_get_num_cols(lp);++i){
79 lpx_set_obj_coef(newlp->lp,i,lpx_get_obj_coef(lp,i));
80 lpx_set_col_bnds(newlp->lp,i,lpx_get_col_type(lp,i),
81 lpx_get_col_lb(lp,i),lpx_get_col_ub(lp,i));
89 int LpGlpk::_addRow() {
90 int i=lpx_add_rows(lp, 1);
95 void LpGlpk::_eraseCol(int i) {
98 lpx_del_cols(lp, 1, cols);
101 void LpGlpk::_eraseRow(int i) {
104 lpx_del_rows(lp, 1, rows);
107 void LpGlpk::_setRowCoeffs(int i,
110 const Value * values )
112 lpx_set_mat_row(lp, i, length,
113 const_cast<int * >(indices) ,
114 const_cast<Value * >(values));
117 void LpGlpk::_setColCoeffs(int i,
120 const Value * values)
122 lpx_set_mat_col(lp, i, length,
123 const_cast<int * >(indices),
124 const_cast<Value * >(values));
128 void LpGlpk::_setCoeff(int row, int col, Value value)
130 ///FIXME Of course this is not efficient at all, but GLPK knows not more.
131 // First approach: get one row, apply changes and set it again
132 //(one idea to improve this: maybe it is better to do this with 1 coloumn)
134 int mem_length=2+lpx_get_num_cols(lp);
135 int* indices = new int[mem_length];
136 Value* values = new Value[mem_length];
139 int length=lpx_get_mat_row(lp, row, indices, values);
141 //The following code does not suppose that the elements of the array indices are sorted
144 while (i <= length && !found){
145 if (indices[i]==col){
154 values[length]=value;
157 lpx_set_mat_row(lp, row, length, indices, values);
163 void LpGlpk::_setColLowerBound(int i, Value lo)
168 int b=lpx_get_col_type(lp, i);
169 double up=lpx_get_col_ub(lp, i);
174 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
180 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
189 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
195 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
197 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
206 void LpGlpk::_setColUpperBound(int i, Value up)
211 int b=lpx_get_col_type(lp, i);
212 double lo=lpx_get_col_lb(lp, i);
219 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
223 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
231 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
234 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
240 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
242 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
250 // void LpGlpk::_setRowLowerBound(int i, Value lo)
255 // int b=lpx_get_row_type(lp, i);
256 // double up=lpx_get_row_ub(lp, i);
261 // lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
267 // lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
276 // lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
282 // lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
284 // lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
292 // void LpGlpk::_setRowUpperBound(int i, Value up)
297 // int b=lpx_get_row_type(lp, i);
298 // double lo=lpx_get_row_lb(lp, i);
305 // lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
309 // lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
317 // lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
320 // lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
326 // lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
328 // lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
336 void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
339 if (lb==INF || ub==-INF) {
345 lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
348 lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
353 lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
358 lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
361 lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
368 void LpGlpk::_setObjCoeff(int i, Value obj_coef)
370 //i=0 means the constant term (shift)
371 lpx_set_obj_coef(lp, i, obj_coef);
374 void LpGlpk::_clearObj()
376 for (int i=0;i<=lpx_get_num_cols(lp);++i){
377 lpx_set_obj_coef(lp, i, 0);
380 // void LpGlpk::_setObj(int length,
381 // int const * indices,
382 // Value const * values )
384 // Value new_values[1+lpx_num_cols()];
385 // for (i=0;i<=lpx_num_cols();++i){
388 // for (i=1;i<=length;++i){
389 // new_values[indices[i]]=values[i];
392 // for (i=0;i<=lpx_num_cols();++i){
393 // lpx_set_obj_coef(lp, i, new_values[i]);
397 LpGlpk::SolveExitStatus LpGlpk::_solve()
399 int i = lpx_simplex(lp);
408 LpGlpk::Value LpGlpk::_getPrimal(int i)
410 return lpx_get_col_prim(lp,i);
413 LpGlpk::Value LpGlpk::_getDual(int i)
415 return lpx_get_row_dual(lp,i);
418 LpGlpk::Value LpGlpk::_getPrimalValue()
420 return lpx_get_obj_val(lp);
424 LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
426 int stat= lpx_get_status(lp);
428 case LPX_UNDEF://Undefined (no solve has been run yet)
430 case LPX_NOFEAS://There is no feasible solution (primal, I guess)
431 case LPX_INFEAS://Infeasible
433 case LPX_UNBND://Unbounded
435 case LPX_FEAS://Feasible
437 case LPX_OPT://Feasible
440 return UNDEFINED; //to avoid gcc warning
445 LpGlpk::SolutionStatus LpGlpk::_getDualStatus()
447 // std::cout<<"Itt megy: "<<lpx_get_dual_stat(lp)<<std::endl;
448 // std::cout<<"Itt a primal: "<<lpx_get_prim_stat(lp)<<std::endl;
450 switch (lpx_get_dual_stat(lp)) {
451 case LPX_D_UNDEF://Undefined (no solve has been run yet)
453 case LPX_D_NOFEAS://There is no dual feasible solution
454 // case LPX_D_INFEAS://Infeasible
456 case LPX_D_FEAS://Feasible
457 switch (lpx_get_status(lp)) {
466 return UNDEFINED; //to avoid gcc warning
471 LpGlpk::ProblemTypes LpGlpk::_getProblemType()
473 //int stat= lpx_get_status(lp);
474 int statp= lpx_get_prim_stat(lp);
475 int statd= lpx_get_dual_stat(lp);
476 if (statp==LPX_P_FEAS && statd==LPX_D_FEAS)
477 return PRIMAL_DUAL_FEASIBLE;
478 if (statp==LPX_P_FEAS && statd==LPX_D_NOFEAS)
479 return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
480 if (statp==LPX_P_NOFEAS && statd==LPX_D_FEAS)
481 return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
482 if (statp==LPX_P_NOFEAS && statd==LPX_D_NOFEAS)
483 return PRIMAL_DUAL_INFEASIBLE;
488 void LpGlpk::_setMax()
490 lpx_set_obj_dir(lp, LPX_MAX);
493 void LpGlpk::_setMin()
495 lpx_set_obj_dir(lp, LPX_MIN);
499 void LpGlpk::messageLevel(int m)
501 lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
504 void LpGlpk::presolver(bool b)
506 lpx_set_int_parm(lp, LPX_K_PRESOL, b);
510 } //END OF NAMESPACE LEMON
512 #endif //LEMON_LP_GLPK_CC