COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/marci/lp/lp_solver_base.h @ 1111:88ade201ffc6

Last change on this file since 1111:88ade201ffc6 was 1111:88ade201ffc6, checked in by marci, 19 years ago

lower and upper bound handling functions for rows

File size: 24.1 KB
Line 
1// -*- c++ -*-
2#ifndef LEMON_LP_SOLVER_WRAPPER_H
3#define LEMON_LP_SOLVER_WRAPPER_H
4
5///\ingroup misc
6///\file
7///\brief Dijkstra algorithm.
8
9// #include <stdio.h>
10#include <stdlib.h>
11#include <iostream>
12#include <map>
13#include <limits>
14// #include <stdio>
15//#include <stdlib>
16extern "C" {
17#include "glpk.h"
18}
19
20#include <iostream>
21#include <vector>
22#include <string>
23#include <list>
24#include <memory>
25#include <utility>
26
27//#include <lemon/list_graph.h>
28#include <lemon/invalid.h>
29#include <expression.h>
30//#include <bfs_dfs.h>
31//#include <stp.h>
32//#include <lemon/max_flow.h>
33//#include <augmenting_flow.h>
34//#include <iter_map.h>
35
36using std::cout;
37using std::cin;
38using std::endl;
39
40namespace lemon {
41 
42  /// \addtogroup misc
43  /// @{
44
45  /// \brief A partitioned vector with iterable classes.
46  ///
47  /// This class implements a container in which the data is stored in an
48  /// stl vector, the range is partitioned into sets and each set is
49  /// doubly linked in a list.
50  /// That is, each class is iterable by lemon iterators, and any member of
51  /// the vector can bo moved to an other class.
52  template <typename T>
53  class IterablePartition {
54  protected:
55    struct Node {
56      T data;
57      int prev; //invalid az -1
58      int next;
59    };
60    std::vector<Node> nodes;
61    struct Tip {
62      int first;
63      int last;
64    };
65    std::vector<Tip> tips;
66  public:
67    /// The classes are indexed by integers from \c 0 to \c classNum()-1.
68    int classNum() const { return tips.size(); }
69    /// This lemon style iterator iterates through a class.
70    class ClassIt;
71    /// Constructor. The number of classes is to be given which is fixed
72    /// over the life of the container.
73    /// The partition classes are indexed from 0 to class_num-1.
74    IterablePartition(int class_num) {
75      for (int i=0; i<class_num; ++i) {
76        Tip t;
77        t.first=t.last=-1;
78        tips.push_back(t);
79      }
80    }
81  protected:
82    void befuz(ClassIt it, int class_id) {
83      if (tips[class_id].first==-1) {
84        if (tips[class_id].last==-1) {
85          nodes[it.i].prev=nodes[it.i].next=-1;
86          tips[class_id].first=tips[class_id].last=it.i;
87        }
88      } else {
89        nodes[it.i].prev=tips[class_id].last;
90        nodes[it.i].next=-1;
91        nodes[tips[class_id].last].next=it.i;
92        tips[class_id].last=it.i;
93      }
94    }
95    void kifuz(ClassIt it, int class_id) {
96      if (tips[class_id].first==it.i) {
97        if (tips[class_id].last==it.i) {
98          tips[class_id].first=tips[class_id].last=-1;
99        } else {
100          tips[class_id].first=nodes[it.i].next;
101          nodes[nodes[it.i].next].prev=-1;
102        }
103      } else {
104        if (tips[class_id].last==it.i) {
105          tips[class_id].last=nodes[it.i].prev;
106          nodes[nodes[it.i].prev].next=-1;
107        } else {
108          nodes[nodes[it.i].next].prev=nodes[it.i].prev;
109          nodes[nodes[it.i].prev].next=nodes[it.i].next;
110        }
111      }
112    }
113  public:
114    /// A new element with data \c t is pushed into the vector and into class
115    /// \c class_id.
116    ClassIt push_back(const T& t, int class_id) {
117      Node n;
118      n.data=t;
119      nodes.push_back(n);
120      int i=nodes.size()-1;
121      befuz(i, class_id);
122      return i;
123    }
124    /// A member is moved to an other class.
125    void set(ClassIt it, int old_class_id, int new_class_id) {
126      kifuz(it.i, old_class_id);
127      befuz(it.i, new_class_id);
128    }
129    /// Returns the data pointed by \c it.
130    T& operator[](ClassIt it) { return nodes[it.i].data; }
131    /// Returns the data pointed by \c it.
132    const T& operator[](ClassIt it) const { return nodes[it.i].data; }
133    ///.
134    class ClassIt {
135      friend class IterablePartition;
136    protected:
137      int i;
138    public:
139      /// Default constructor.
140      ClassIt() { }
141      /// This constructor constructs an iterator which points
142      /// to the member of th container indexed by the integer _i.
143      ClassIt(const int& _i) : i(_i) { }
144      /// Invalid constructor.
145      ClassIt(const Invalid&) : i(-1) { }
146      friend bool operator<(const ClassIt& x, const ClassIt& y);
147      friend std::ostream& operator<<(std::ostream& os,
148                                      const ClassIt& it);
149    };
150    friend bool operator<(const ClassIt& x, const ClassIt& y) {
151      return (x.i < y.i);
152    }
153    friend std::ostream& operator<<(std::ostream& os,
154                                    const ClassIt& it) {
155      os << it.i;
156      return os;
157    }
158    /// First member of class \c class_id.
159    ClassIt& first(ClassIt& it, int class_id) const {
160      it.i=tips[class_id].first;
161      return it;
162    }
163    /// Next member.
164    ClassIt& next(ClassIt& it) const {
165      it.i=nodes[it.i].next;
166      return it;
167    }
168    /// True iff the iterator is valid.
169    bool valid(const ClassIt& it) const { return it.i!=-1; }
170  };
171
172
173  /*! \e
174    \todo A[x,y]-t cserel. Jobboldal, baloldal csere.
175    \todo LEKERDEZESEK!!!
176    \todo DOKSI!!!! Doxygen group!!!
177    The aim of this class is to give a general surface to different
178    solvers, i.e. it makes possible to write algorithms using LP's,
179    in which the solver can be changed to an other one easily.
180  */
181  template <typename _Value>
182  class LPSolverBase {
183  public:
184    /// \e
185    typedef _Value Value;
186    /// \e
187    typedef IterablePartition<int>::ClassIt RowIt;
188    /// \e
189    typedef IterablePartition<int>::ClassIt ColIt;
190  public:
191    /// \e
192    IterablePartition<int> row_iter_map;
193    /// \e
194    IterablePartition<int> col_iter_map;
195    /// \e
196    const int VALID_CLASS;
197    /// \e
198    const int INVALID_CLASS;
199    /// \e
200    static const _Value INF;
201  public:
202    /// \e
203    LPSolverBase() : row_iter_map(2),
204                     col_iter_map(2),
205                     VALID_CLASS(0), INVALID_CLASS(1) { }
206    /// \e
207    virtual ~LPSolverBase() { }
208
209    //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
210
211  public:
212    /// \e
213    virtual void setMinimize() = 0;
214    /// \e
215    virtual void setMaximize() = 0;
216
217    //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS
218
219  protected:
220    /// \e
221    virtual int _addCol() = 0;
222    /// \e
223    virtual int _addRow() = 0;
224    /// \e
225    virtual void _eraseCol(int i) = 0;
226    /// \e
227    virtual void _eraseRow(int i) = 0;
228    /// \e
229    virtual void _setRowCoeffs(int i,
230                               const std::vector<std::pair<int, _Value> >& coeffs) = 0;
231    /// \e
232    virtual void _setColCoeffs(int i,
233                               const std::vector<std::pair<int, _Value> >& coeffs) = 0;
234  public:
235    /// \e
236    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
237  protected:
238    /// \e
239    /// The lower bound of a variable (column) have to be given by an
240    /// extended number of type _Value, i.e. a finite number of type
241    /// _Value or -INF.
242    virtual void _setColLowerBound(int i, _Value value) = 0;
243    /// \e
244    /// The lower bound of a variable (column) is an
245    /// extended number of type _Value, i.e. a finite number of type
246    /// _Value or -INF.
247    virtual _Value _getColLowerBound(int i) = 0;
248    /// \e
249    /// The upper bound of a variable (column) have to be given by an
250    /// extended number of type _Value, i.e. a finite number of type
251    /// _Value or INF.
252    virtual void _setColUpperBound(int i, _Value value) = 0;
253    /// \e
254    /// The upper bound of a variable (column) is an
255    /// extended number of type _Value, i.e. a finite number of type
256    /// _Value or INF.
257    virtual _Value _getColUpperBound(int i) = 0;
258    /// \e
259    /// The lower bound of a linear expression (row) have to be given by an
260    /// extended number of type _Value, i.e. a finite number of type
261    /// _Value or -INF.
262    virtual void _setRowLowerBound(int i, _Value value) = 0;
263    /// \e
264    /// The lower bound of a linear expression (row) is an
265    /// extended number of type _Value, i.e. a finite number of type
266    /// _Value or -INF.
267    virtual _Value _getRowLowerBound(int i) = 0;
268    /// \e
269    /// The upper bound of a linear expression (row) have to be given by an
270    /// extended number of type _Value, i.e. a finite number of type
271    /// _Value or INF.
272    virtual void _setRowUpperBound(int i, _Value value) = 0;
273    /// \e
274    /// The upper bound of a linear expression (row) is an
275    /// extended number of type _Value, i.e. a finite number of type
276    /// _Value or INF.
277    virtual _Value _getRowUpperBound(int i) = 0;
278    /// \e
279    virtual void _setObjCoef(int i, _Value obj_coef) = 0;
280    /// \e
281    virtual _Value _getObjCoef(int i) = 0;
282
283    //LOW LEVEL, SOLUTION RETRIEVING FUNCTIONS
284
285  protected:
286    /// \e
287    virtual _Value _getPrimal(int i) = 0;
288
289    //HIGH LEVEL INTERFACE, MATRIX MANIPULATING FUNTIONS
290
291  public:
292    /// \e
293    ColIt addCol() {
294      int i=_addCol(); 
295      ColIt col_it;
296      col_iter_map.first(col_it, INVALID_CLASS);
297      if (col_iter_map.valid(col_it)) { //van hasznalhato hely
298        col_iter_map.set(col_it, INVALID_CLASS, VALID_CLASS);
299        col_iter_map[col_it]=i;
300      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
301        col_it=col_iter_map.push_back(i, VALID_CLASS);
302      }
303      return col_it;
304    }
305    /// \e
306    RowIt addRow() {
307      int i=_addRow();
308      RowIt row_it;
309      row_iter_map.first(row_it, INVALID_CLASS);
310      if (row_iter_map.valid(row_it)) { //van hasznalhato hely
311        row_iter_map.set(row_it, INVALID_CLASS, VALID_CLASS);
312        row_iter_map[row_it]=i;
313      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
314        row_it=row_iter_map.push_back(i, VALID_CLASS);
315      }
316      return row_it;
317    }
318    /// \e
319    void eraseCol(const ColIt& col_it) {
320      col_iter_map.set(col_it, VALID_CLASS, INVALID_CLASS);
321      int cols[2];
322      cols[1]=col_iter_map[col_it];
323      _eraseCol(cols[1]);
324      col_iter_map[col_it]=0; //glpk specifikus, de kell ez??
325      ColIt it;
326      for (col_iter_map.first(it, VALID_CLASS);
327           col_iter_map.valid(it); col_iter_map.next(it)) {
328        if (col_iter_map[it]>cols[1]) --col_iter_map[it];
329      }
330    }
331    /// \e
332    void eraseRow(const RowIt& row_it) {
333      row_iter_map.set(row_it, VALID_CLASS, INVALID_CLASS);
334      int rows[2];
335      rows[1]=row_iter_map[row_it];
336      _eraseRow(rows[1]);
337      row_iter_map[row_it]=0; //glpk specifikus, de kell ez??
338      RowIt it;
339      for (row_iter_map.first(it, VALID_CLASS);
340           row_iter_map.valid(it); row_iter_map.next(it)) {
341        if (row_iter_map[it]>rows[1]) --row_iter_map[it];
342      }
343    }
344    /// \e
345    template <typename Begin, typename End>
346    void setRowCoeffs(RowIt row_it, Begin begin, End end) {
347      std::vector<std::pair<int, double> > coeffs;
348      for ( ; begin!=end; ++begin) {
349        coeffs.push_back(std::
350                         make_pair(col_iter_map[begin->first], begin->second));
351      }
352      _setRowCoeffs(row_iter_map[row_it], coeffs);
353    }
354    /// \e
355    template <typename Begin, typename End>
356    void setColCoeffs(ColIt col_it, Begin begin, End end) {
357      std::vector<std::pair<int, double> > coeffs;
358      for ( ; begin!=end; ++begin) {
359        coeffs.push_back(std::
360                         make_pair(row_iter_map[begin->first], begin->second));
361      }
362      _setColCoeffs(col_iter_map[col_it], coeffs);
363    }
364    /// \e
365    void setColLowerBound(ColIt col_it, _Value lo) {
366      _setColLowerBound(col_iter_map[col_it], lo);
367    }
368    /// \e
369    _Value getColLowerBound(ColIt col_it) {
370      return _getColLowerBound(col_iter_map[col_it]);
371    }
372    /// \e
373    void setColUpperBound(ColIt col_it, _Value up) {
374      _setColUpperBound(col_iter_map[col_it], up);
375    }
376    /// \e
377    _Value getColUpperBound(ColIt col_it) {     
378      return _getColUpperBound(col_iter_map[col_it]);
379    }
380    /// \e
381    void setRowLowerBound(RowIt row_it, _Value lo) {
382      _setRowLowerBound(row_iter_map[row_it], lo);
383    }
384    /// \e
385    _Value getRowLowerBound(RowIt row_it) {
386      return _getRowLowerBound(row_iter_map[row_it]);
387    }
388    /// \e
389    void setRowUpperBound(RowIt row_it, _Value up) {
390      _setRowUpperBound(row_iter_map[row_it], up);
391    }
392    /// \e
393    _Value getRowUpperBound(RowIt row_it) {     
394      return _getRowUpperBound(row_iter_map[row_it]);
395    }
396    /// \e
397    void setObjCoef(const ColIt& col_it, _Value obj_coef) {
398      _setObjCoef(col_iter_map[col_it], obj_coef);
399    }
400    /// \e
401    _Value getObjCoef(const ColIt& col_it) {
402      return _getObjCoef(col_iter_map[col_it]);
403    }
404
405    //MOST HIGH LEVEL, USER FRIEND FUNCTIONS
406
407    /// \e
408    typedef Expr<ColIt, _Value> Expression;
409    /// \e
410    typedef Expr<RowIt, _Value> DualExpression;
411    /// \e
412    void setRowCoeffs(RowIt row_it, const Expression& expr) {
413      std::vector<std::pair<int, _Value> > row_coeffs;
414      for(typename Expression::Data::const_iterator i=expr.data.begin();
415          i!=expr.data.end(); ++i) {
416        row_coeffs.push_back(std::make_pair
417                             (col_iter_map[(*i).first], (*i).second));
418      }
419      _setRowCoeffs(row_iter_map[row_it], row_coeffs);
420    }
421    /// \e
422    void setColCoeffs(ColIt col_it, const DualExpression& expr) {
423      std::vector<std::pair<int, _Value> > col_coeffs;
424      for(typename DualExpression::Data::const_iterator i=expr.data.begin();
425          i!=expr.data.end(); ++i) {
426        col_coeffs.push_back(std::make_pair
427                             (row_iter_map[(*i).first], (*i).second));
428      }
429      _setColCoeffs(col_iter_map[col_it], col_coeffs);
430    }
431    /// \e
432    void setObjCoeffs(const Expression& expr) {
433      for(typename Expression::Data::const_iterator i=expr.data.begin();
434          i!=expr.data.end(); ++i) {
435        setObjCoef((*i).first, (*i).second);
436      }
437    }
438
439    //SOLVER FUNCTIONS
440
441    /// \e
442    virtual void solveSimplex() = 0;
443    /// \e
444    virtual void solvePrimalSimplex() = 0;
445    /// \e
446    virtual void solveDualSimplex() = 0;
447    /// \e
448
449    //HIGH LEVEL, SOLUTION RETRIEVING FUNCTIONS
450
451  public:
452
453    /// \e
454    _Value getPrimal(const ColIt& col_it) {
455      return _getPrimal(col_iter_map[col_it]);
456    }
457    /// \e
458    virtual _Value getObjVal() = 0;
459
460    //OTHER FUNCTIONS
461
462    /// \e
463    virtual int rowNum() const = 0;
464    /// \e
465    virtual int colNum() const = 0;
466    /// \e
467    virtual int warmUp() = 0;
468    /// \e
469    virtual void printWarmUpStatus(int i) = 0;
470    /// \e
471    virtual int getPrimalStatus() = 0;
472    /// \e
473    virtual void printPrimalStatus(int i) = 0;
474    /// \e
475    virtual int getDualStatus() = 0;
476    /// \e
477    virtual void printDualStatus(int i) = 0;
478    /// Returns the status of the slack variable assigned to row \c row_it.
479    virtual int getRowStat(const RowIt& row_it) = 0;
480    /// \e
481    virtual void printRowStatus(int i) = 0;
482    /// Returns the status of the variable assigned to column \c col_it.
483    virtual int getColStat(const ColIt& col_it) = 0;
484    /// \e
485    virtual void printColStatus(int i) = 0;
486  };
487 
488  template <typename _Value>
489  const _Value LPSolverBase<_Value>::INF=std::numeric_limits<_Value>::infinity();
490
491
492  /// \brief Wrapper for GLPK solver
493  ///
494  /// This class implements a lemon wrapper for GLPK.
495  class LPGLPK : public LPSolverBase<double> {
496  public:
497    typedef LPSolverBase<double> Parent;
498
499  public:
500    /// \e
501    LPX* lp;
502
503  public:
504    /// \e
505    LPGLPK() : Parent(),
506                        lp(lpx_create_prob()) {
507      lpx_set_int_parm(lp, LPX_K_DUAL, 1);
508    }
509    /// \e
510    ~LPGLPK() {
511      lpx_delete_prob(lp);
512    }
513
514    //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
515
516    /// \e
517    void setMinimize() {
518      lpx_set_obj_dir(lp, LPX_MIN);
519    }
520    /// \e
521    void setMaximize() {
522      lpx_set_obj_dir(lp, LPX_MAX);
523    }
524
525    //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS
526
527  protected:
528    /// \e
529    int _addCol() {
530      int i=lpx_add_cols(lp, 1);
531      _setColLowerBound(i, -INF);
532      _setColUpperBound(i, INF);
533      return i;
534    }
535    /// \e
536    int _addRow() {
537      int i=lpx_add_rows(lp, 1);
538      return i;
539    }
540    /// \e
541    virtual void _setRowCoeffs(int i,
542                               const std::vector<std::pair<int, double> >& coeffs) {
543      int mem_length=1+colNum();
544      int* indices = new int[mem_length];
545      double* doubles = new double[mem_length];
546      int length=0;
547      for (std::vector<std::pair<int, double> >::
548             const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
549        ++length;
550        indices[length]=it->first;
551        doubles[length]=it->second;
552//      std::cout << "  " << indices[length] << " "
553//                << doubles[length] << std::endl;
554      }
555//      std::cout << i << " " << length << std::endl;
556      lpx_set_mat_row(lp, i, length, indices, doubles);
557      delete [] indices;
558      delete [] doubles;
559    }
560    /// \e
561    virtual void _setColCoeffs(int i,
562                               const std::vector<std::pair<int, double> >& coeffs) {
563      int mem_length=1+rowNum();
564      int* indices = new int[mem_length];
565      double* doubles = new double[mem_length];
566      int length=0;
567      for (std::vector<std::pair<int, double> >::
568             const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
569        ++length;
570        indices[length]=it->first;
571        doubles[length]=it->second;
572      }
573      lpx_set_mat_col(lp, i, length, indices, doubles);
574      delete [] indices;
575      delete [] doubles;
576    }
577    /// \e
578    virtual void _eraseCol(int i) {
579      int cols[2];
580      cols[1]=i;
581      lpx_del_cols(lp, 1, cols);
582    }
583    virtual void _eraseRow(int i) {
584      int rows[2];
585      rows[1]=i;
586      lpx_del_rows(lp, 1, rows);
587    }
588    virtual void _setColLowerBound(int i, double lo) {
589      if (lo==INF) {
590        //FIXME error
591      }
592      int b=lpx_get_col_type(lp, i);
593      double up=lpx_get_col_ub(lp, i); 
594      if (lo==-INF) {
595        switch (b) {
596        case LPX_FR:
597        case LPX_LO:
598          lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
599          break;
600        case LPX_UP:
601          break;
602        case LPX_DB:
603        case LPX_FX:
604          lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
605          break;
606        default: ;
607          //FIXME error
608        }
609      } else {
610        switch (b) {
611        case LPX_FR:
612        case LPX_LO:
613          lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
614          break;
615        case LPX_UP:     
616        case LPX_DB:
617        case LPX_FX:
618          if (lo==up)
619            lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
620          else
621            lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
622          break;
623        default: ;
624          //FIXME error
625        }
626      }
627    }
628    virtual double _getColLowerBound(int i) {
629      int b=lpx_get_col_type(lp, i);
630      switch (b) {
631      case LPX_FR:
632        return -INF;
633      case LPX_LO:
634        return lpx_get_col_lb(lp, i);
635      case LPX_UP:
636        return -INF;
637      case LPX_DB:
638      case LPX_FX:
639        return lpx_get_col_lb(lp, i);
640      default: ;
641        //FIXME error
642        return 0.0;
643      }
644    }
645    virtual void _setColUpperBound(int i, double up) {
646      if (up==-INF) {
647        //FIXME error
648      }
649      int b=lpx_get_col_type(lp, i);
650      double lo=lpx_get_col_lb(lp, i);
651      if (up==INF) {
652        switch (b) {
653        case LPX_FR:
654        case LPX_LO:
655          break;
656        case LPX_UP:
657          lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
658          break;
659        case LPX_DB:
660        case LPX_FX:
661          lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
662          break;
663        default: ;
664          //FIXME error
665        }
666      } else {
667        switch (b) {
668        case LPX_FR:
669          lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
670        case LPX_LO:
671          if (lo==up)
672            lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
673          else
674            lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
675          break;
676        case LPX_UP:
677          lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
678          break;
679        case LPX_DB:
680        case LPX_FX:
681          if (lo==up)
682            lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
683          else
684            lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
685          break;
686        default: ;
687          //FIXME error
688        }
689      }
690    }
691    virtual double _getColUpperBound(int i) {
692      int b=lpx_get_col_type(lp, i);
693      switch (b) {
694      case LPX_FR:
695      case LPX_LO:
696        return INF;
697      case LPX_UP:
698      case LPX_DB:
699      case LPX_FX:
700        return lpx_get_col_ub(lp, i);
701      default: ;
702        //FIXME error
703        return 0.0;
704      }
705    }
706    virtual void _setRowLowerBound(int i, double lo) {
707      if (lo==INF) {
708        //FIXME error
709      }
710      int b=lpx_get_row_type(lp, i);
711      double up=lpx_get_row_ub(lp, i); 
712      if (lo==-INF) {
713        switch (b) {
714        case LPX_FR:
715        case LPX_LO:
716          lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
717          break;
718        case LPX_UP:
719          break;
720        case LPX_DB:
721        case LPX_FX:
722          lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
723          break;
724        default: ;
725          //FIXME error
726        }
727      } else {
728        switch (b) {
729        case LPX_FR:
730        case LPX_LO:
731          lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
732          break;
733        case LPX_UP:     
734        case LPX_DB:
735        case LPX_FX:
736          if (lo==up)
737            lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
738          else
739            lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
740          break;
741        default: ;
742          //FIXME error
743        }
744      }
745    }
746    virtual double _getRowLowerBound(int i) {
747      int b=lpx_get_row_type(lp, i);
748      switch (b) {
749      case LPX_FR:
750        return -INF;
751      case LPX_LO:
752        return lpx_get_row_lb(lp, i);
753      case LPX_UP:
754        return -INF;
755      case LPX_DB:
756      case LPX_FX:
757        return lpx_get_row_lb(lp, i);
758      default: ;
759        //FIXME error
760        return 0.0;
761      }
762    }
763    virtual void _setRowUpperBound(int i, double up) {
764      if (up==-INF) {
765        //FIXME error
766      }
767      int b=lpx_get_row_type(lp, i);
768      double lo=lpx_get_row_lb(lp, i);
769      if (up==INF) {
770        switch (b) {
771        case LPX_FR:
772        case LPX_LO:
773          break;
774        case LPX_UP:
775          lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
776          break;
777        case LPX_DB:
778        case LPX_FX:
779          lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
780          break;
781        default: ;
782          //FIXME error
783        }
784      } else {
785        switch (b) {
786        case LPX_FR:
787          lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
788        case LPX_LO:
789          if (lo==up)
790            lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
791          else
792            lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
793          break;
794        case LPX_UP:
795          lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
796          break;
797        case LPX_DB:
798        case LPX_FX:
799          if (lo==up)
800            lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
801          else
802            lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
803          break;
804        default: ;
805          //FIXME error
806        }
807      }
808    }
809    virtual double _getRowUpperBound(int i) {
810      int b=lpx_get_row_type(lp, i);
811      switch (b) {
812      case LPX_FR:
813      case LPX_LO:
814        return INF;
815      case LPX_UP:
816      case LPX_DB:
817      case LPX_FX:
818        return lpx_get_row_ub(lp, i);
819      default: ;
820        //FIXME error
821        return 0.0;
822      }
823    }
824    /// \e
825    virtual double _getObjCoef(int i) {
826      return lpx_get_obj_coef(lp, i);
827    }
828    /// \e
829    virtual void _setObjCoef(int i, double obj_coef) {
830      lpx_set_obj_coef(lp, i, obj_coef);
831    }
832  public:
833    /// \e
834    void solveSimplex() { lpx_simplex(lp); }
835    /// \e
836    void solvePrimalSimplex() { lpx_simplex(lp); }
837    /// \e
838    void solveDualSimplex() { lpx_simplex(lp); }
839    /// \e
840  protected:
841    virtual double _getPrimal(int i) {
842      return lpx_get_col_prim(lp, i);
843    }
844  public:
845    /// \e
846    double getObjVal() { return lpx_get_obj_val(lp); }
847    /// \e
848    int rowNum() const { return lpx_get_num_rows(lp); }
849    /// \e
850    int colNum() const { return lpx_get_num_cols(lp); }
851    /// \e
852    int warmUp() { return lpx_warm_up(lp); }
853    /// \e
854    void printWarmUpStatus(int i) {
855      switch (i) {
856      case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
857      case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;   
858      case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
859      case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
860      }
861    }
862    /// \e
863    int getPrimalStatus() { return lpx_get_prim_stat(lp); }
864    /// \e
865    void printPrimalStatus(int i) {
866      switch (i) {
867      case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
868      case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;     
869      case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
870      case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
871      }
872    }
873    /// \e
874    int getDualStatus() { return lpx_get_dual_stat(lp); }
875    /// \e
876    void printDualStatus(int i) {
877      switch (i) {
878      case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
879      case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;     
880      case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
881      case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
882      }
883    }
884    /// Returns the status of the slack variable assigned to row \c row_it.
885    int getRowStat(const RowIt& row_it) {
886      return lpx_get_row_stat(lp, row_iter_map[row_it]);
887    }
888    /// \e
889    void printRowStatus(int i) {
890      switch (i) {
891      case LPX_BS: cout << "LPX_BS" << endl; break;
892      case LPX_NL: cout << "LPX_NL" << endl; break;     
893      case LPX_NU: cout << "LPX_NU" << endl; break;
894      case LPX_NF: cout << "LPX_NF" << endl; break;
895      case LPX_NS: cout << "LPX_NS" << endl; break;
896      }
897    }
898    /// Returns the status of the variable assigned to column \c col_it.
899    int getColStat(const ColIt& col_it) {
900      return lpx_get_col_stat(lp, col_iter_map[col_it]);
901    }
902    /// \e
903    void printColStatus(int i) {
904      switch (i) {
905      case LPX_BS: cout << "LPX_BS" << endl; break;
906      case LPX_NL: cout << "LPX_NL" << endl; break;     
907      case LPX_NU: cout << "LPX_NU" << endl; break;
908      case LPX_NF: cout << "LPX_NF" << endl; break;
909      case LPX_NS: cout << "LPX_NS" << endl; break;
910      }
911    }
912  };
913 
914  /// @}
915
916} //namespace lemon
917
918#endif //LEMON_LP_SOLVER_WRAPPER_H
Note: See TracBrowser for help on using the repository browser.