COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/marci/lp/lp_solver_base.h @ 1144:1cfabf245433

Last change on this file since 1144:1cfabf245433 was 1144:1cfabf245433, checked in by marci, 15 years ago

trying to add constraints of kind 1 <= x[2]+x[3] <= 4

File size: 27.0 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 kellenene uj iterable structure bele, mert ez nem az igazi
175    \todo A[x,y]-t cserel. Jobboldal, baloldal csere.
176    \todo LEKERDEZESEK!!!
177    \todo DOKSI!!!! Doxygen group!!!
178    The aim of this class is to give a general surface to different
179    solvers, i.e. it makes possible to write algorithms using LP's,
180    in which the solver can be changed to an other one easily.
181    \nosubgrouping
182  */
183  template <typename _Value>
184  class LPSolverBase {
185   
186    /*! @name Uncategorized functions and types (public members)
187    */
188    //@{
189  public:
190
191    //UNCATEGORIZED
192
193    /// \e
194    typedef _Value Value;
195    /// \e
196    typedef IterablePartition<int>::ClassIt Row;
197    /// \e
198    typedef IterablePartition<int>::ClassIt Col;
199  public:
200    /// \e
201    IterablePartition<int> row_iter_map;
202    /// \e
203    IterablePartition<int> col_iter_map;
204    /// \e
205    std::vector<Row> int_row_map;
206    /// \e
207    std::vector<Col> int_col_map;
208    /// \e
209    const int VALID_CLASS;
210    /// \e
211    const int INVALID_CLASS;
212    /// \e
213    static const _Value INF;
214  public:
215    /// \e
216    LPSolverBase() : row_iter_map(2),
217                     col_iter_map(2),
218                     VALID_CLASS(0), INVALID_CLASS(1) { }
219    /// \e
220    virtual ~LPSolverBase() { }
221    //@}
222
223    /*! @name Medium level interface (public members)
224      These functions appear in the low level and also in the high level
225      interfaces thus these each of these functions have to be implemented
226      only once in the different interfaces.
227      This means that these functions have to be reimplemented for all of the
228      different lp solvers. These are basic functions, and have the same
229      parameter lists in the low and high level interfaces.
230    */
231    //@{
232  public:
233
234    //UNCATEGORIZED FUNCTIONS
235
236    /// \e
237    virtual void setMinimize() = 0;
238    /// \e
239    virtual void setMaximize() = 0;
240
241    //SOLVER FUNCTIONS
242
243    /// \e
244    virtual void solveSimplex() = 0;
245    /// \e
246    virtual void solvePrimalSimplex() = 0;
247    /// \e
248    virtual void solveDualSimplex() = 0;
249    /// \e
250
251    //SOLUTION RETRIEVING
252
253    /// \e
254    virtual _Value getObjVal() = 0;
255
256    //OTHER FUNCTIONS
257
258    /// \e
259    virtual int rowNum() const = 0;
260    /// \e
261    virtual int colNum() const = 0;
262    /// \e
263    virtual int warmUp() = 0;
264    /// \e
265    virtual void printWarmUpStatus(int i) = 0;
266    /// \e
267    virtual int getPrimalStatus() = 0;
268    /// \e
269    virtual void printPrimalStatus(int i) = 0;
270    /// \e
271    virtual int getDualStatus() = 0;
272    /// \e
273    virtual void printDualStatus(int i) = 0;
274    /// Returns the status of the slack variable assigned to row \c row.
275    virtual int getRowStat(const Row& row) = 0;
276    /// \e
277    virtual void printRowStatus(int i) = 0;
278    /// Returns the status of the variable assigned to column \c col.
279    virtual int getColStat(const Col& col) = 0;
280    /// \e
281    virtual void printColStatus(int i) = 0;
282
283    //@}
284
285    /*! @name Low level interface (protected members)
286      Problem manipulating functions in the low level interface
287    */
288    //@{
289  protected:
290
291    //MATRIX MANIPULATING FUNCTIONS
292
293    /// \e
294    virtual int _addCol() = 0;
295    /// \e
296    virtual int _addRow() = 0;
297    /// \e
298    virtual void _eraseCol(int i) = 0;
299    /// \e
300    virtual void _eraseRow(int i) = 0;
301    /// \e
302    virtual void _setRowCoeffs(int i,
303                               const std::vector<std::pair<int, _Value> >& coeffs) = 0;
304    /// \e
305    /// This routine modifies \c coeffs only by the \c push_back method.
306    virtual void _getRowCoeffs(int i,
307                               std::vector<std::pair<int, _Value> >& coeffs) = 0;
308    virtual void _setColCoeffs(int i,
309                               const std::vector<std::pair<int, _Value> >& coeffs) = 0;
310    /// \e
311    /// This routine modifies \c coeffs only by the \c push_back method.
312    virtual void _getColCoeffs(int i,
313                               std::vector<std::pair<int, _Value> >& coeffs) = 0;
314  public:
315    /// \e
316    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
317  protected:
318    /// \e
319    /// The lower bound of a variable (column) have to be given by an
320    /// extended number of type _Value, i.e. a finite number of type
321    /// _Value or -INF.
322    virtual void _setColLowerBound(int i, _Value value) = 0;
323    /// \e
324    /// The lower bound of a variable (column) is an
325    /// extended number of type _Value, i.e. a finite number of type
326    /// _Value or -INF.
327    virtual _Value _getColLowerBound(int i) = 0;
328    /// \e
329    /// The upper bound of a variable (column) have to be given by an
330    /// extended number of type _Value, i.e. a finite number of type
331    /// _Value or INF.
332    virtual void _setColUpperBound(int i, _Value value) = 0;
333    /// \e
334    /// The upper bound of a variable (column) is an
335    /// extended number of type _Value, i.e. a finite number of type
336    /// _Value or INF.
337    virtual _Value _getColUpperBound(int i) = 0;
338    /// \e
339    /// The lower bound of a linear expression (row) have to be given by an
340    /// extended number of type _Value, i.e. a finite number of type
341    /// _Value or -INF.
342    virtual void _setRowLowerBound(int i, _Value value) = 0;
343    /// \e
344    /// The lower bound of a linear expression (row) is an
345    /// extended number of type _Value, i.e. a finite number of type
346    /// _Value or -INF.
347    virtual _Value _getRowLowerBound(int i) = 0;
348    /// \e
349    /// The upper bound of a linear expression (row) have to be given by an
350    /// extended number of type _Value, i.e. a finite number of type
351    /// _Value or INF.
352    virtual void _setRowUpperBound(int i, _Value value) = 0;
353    /// \e
354    /// The upper bound of a linear expression (row) is an
355    /// extended number of type _Value, i.e. a finite number of type
356    /// _Value or INF.
357    virtual _Value _getRowUpperBound(int i) = 0;
358    /// \e
359    virtual void _setObjCoef(int i, _Value obj_coef) = 0;
360    /// \e
361    virtual _Value _getObjCoef(int i) = 0;
362   
363    //SOLUTION RETRIEVING
364
365    /// \e
366    virtual _Value _getPrimal(int i) = 0;
367    //@}
368   
369    /*! @name High level interface (public members)
370      Problem manipulating functions in the high level interface
371    */
372    //@{
373  public:
374
375    //MATRIX MANIPULATING FUNCTIONS
376
377    /// \e
378    Col addCol() {
379      int i=_addCol(); 
380      Col col;
381      col_iter_map.first(col, INVALID_CLASS);
382      if (col_iter_map.valid(col)) { //van hasznalhato hely
383        col_iter_map.set(col, INVALID_CLASS, VALID_CLASS);
384        col_iter_map[col]=i;
385      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
386        col=col_iter_map.push_back(i, VALID_CLASS);
387      }
388      int_col_map.push_back(col);
389      return col;
390    }
391    /// \e
392    Row addRow() {
393      int i=_addRow();
394      Row row;
395      row_iter_map.first(row, INVALID_CLASS);
396      if (row_iter_map.valid(row)) { //van hasznalhato hely
397        row_iter_map.set(row, INVALID_CLASS, VALID_CLASS);
398        row_iter_map[row]=i;
399      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
400        row=row_iter_map.push_back(i, VALID_CLASS);
401      }
402      int_row_map.push_back(row);
403      return row;
404    }
405    /// \e
406    void eraseCol(const Col& col) {
407      col_iter_map.set(col, VALID_CLASS, INVALID_CLASS);
408      int cols[2];
409      cols[1]=col_iter_map[col];
410      _eraseCol(cols[1]);
411      col_iter_map[col]=0; //glpk specifikus, de kell ez??
412      Col it;
413      for (col_iter_map.first(it, VALID_CLASS);
414           col_iter_map.valid(it); col_iter_map.next(it)) {
415        if (col_iter_map[it]>cols[1]) --col_iter_map[it];
416      }
417      int_col_map.erase(int_col_map.begin()+cols[1]);
418    }
419    /// \e
420    void eraseRow(const Row& row) {
421      row_iter_map.set(row, VALID_CLASS, INVALID_CLASS);
422      int rows[2];
423      rows[1]=row_iter_map[row];
424      _eraseRow(rows[1]);
425      row_iter_map[row]=0; //glpk specifikus, de kell ez??
426      Row it;
427      for (row_iter_map.first(it, VALID_CLASS);
428           row_iter_map.valid(it); row_iter_map.next(it)) {
429        if (row_iter_map[it]>rows[1]) --row_iter_map[it];
430      }
431      int_row_map.erase(int_row_map.begin()+rows[1]);
432    }
433    /// \e
434    void setColLowerBound(Col col, _Value lo) {
435      _setColLowerBound(col_iter_map[col], lo);
436    }
437    /// \e
438    _Value getColLowerBound(Col col) {
439      return _getColLowerBound(col_iter_map[col]);
440    }
441    /// \e
442    void setColUpperBound(Col col, _Value up) {
443      _setColUpperBound(col_iter_map[col], up);
444    }
445    /// \e
446    _Value getColUpperBound(Col col) {     
447      return _getColUpperBound(col_iter_map[col]);
448    }
449    /// \e
450    void setRowLowerBound(Row row, _Value lo) {
451      _setRowLowerBound(row_iter_map[row], lo);
452    }
453    /// \e
454    _Value getRowLowerBound(Row row) {
455      return _getRowLowerBound(row_iter_map[row]);
456    }
457    /// \e
458    void setRowUpperBound(Row row, _Value up) {
459      _setRowUpperBound(row_iter_map[row], up);
460    }
461    /// \e
462    _Value getRowUpperBound(Row row) {     
463      return _getRowUpperBound(row_iter_map[row]);
464    }
465    /// \e
466    void setObjCoef(const Col& col, _Value obj_coef) {
467      _setObjCoef(col_iter_map[col], obj_coef);
468    }
469    /// \e
470    _Value getObjCoef(const Col& col) {
471      return _getObjCoef(col_iter_map[col]);
472    }
473
474    //SOLUTION RETRIEVING FUNCTIONS
475
476    /// \e
477    _Value getPrimal(const Col& col) {
478      return _getPrimal(col_iter_map[col]);
479    }   
480
481    //@}
482
483    /*! @name User friend interface
484      Problem manipulating functions in the user friend interface
485    */
486    //@{
487
488    //EXPRESSION TYPES
489
490    /// \e
491    typedef Expr<Col, _Value> Expression;
492    /// \e
493    typedef Expr<Row, _Value> DualExpression;
494    /// \e
495    typedef Constr<Col, _Value> Constraint;
496
497    //MATRIX MANIPULATING FUNCTIONS
498
499    /// \e
500    void setRowCoeffs(Row row, const Expression& expr) {
501      std::vector<std::pair<int, _Value> > row_coeffs;
502      for(typename Expression::Data::const_iterator i=expr.data.begin();
503          i!=expr.data.end(); ++i) {
504        row_coeffs.push_back(std::make_pair
505                             (col_iter_map[(*i).first], (*i).second));
506      }
507      _setRowCoeffs(row_iter_map[row], row_coeffs);
508    }
509    /// \e
510    void setRow(Row row, const Constraint& constr) {
511      setRowCoeffs(row, constr.expr);
512      setRowLowerBound(row, constr.lo);
513      setRowUpperBound(row, constr.up);
514    }
515    /// \e
516    Row addRow(const Constraint& constr) {
517      Row row=addRow();
518      setRowCoeffs(row, constr.expr);
519      setRowLowerBound(row, constr.lo);
520      setRowUpperBound(row, constr.up);
521      return row;
522    }
523    /// \e
524    /// This routine modifies \c expr by only adding to it.
525    void getRowCoeffs(Row row, Expression& expr) {
526      std::vector<std::pair<int, _Value> > row_coeffs;
527      _getRowCoeffs(row_iter_map[row], row_coeffs);
528      for(typename std::vector<std::pair<int, _Value> >::const_iterator
529            i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) {
530        expr+= (*i).second*int_col_map[(*i).first];
531      }
532    }
533    /// \e
534    void setColCoeffs(Col col, const DualExpression& expr) {
535      std::vector<std::pair<int, _Value> > col_coeffs;
536      for(typename DualExpression::Data::const_iterator i=expr.data.begin();
537          i!=expr.data.end(); ++i) {
538        col_coeffs.push_back(std::make_pair
539                             (row_iter_map[(*i).first], (*i).second));
540      }
541      _setColCoeffs(col_iter_map[col], col_coeffs);
542    }
543    /// \e
544    /// This routine modifies \c expr by only adding to it.
545    void getColCoeffs(Col col, DualExpression& expr) {
546      std::vector<std::pair<int, _Value> > col_coeffs;
547      _getColCoeffs(col_iter_map[col], col_coeffs);
548      for(typename std::vector<std::pair<int, _Value> >::const_iterator
549            i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
550        expr+= (*i).second*int_row_map[(*i).first];
551      }
552    }
553    /// \e
554    /// \bug ez igy nem jo
555    void setObjCoeffs(const Expression& expr) {
556      for(typename Expression::Data::const_iterator i=expr.data.begin();
557          i!=expr.data.end(); ++i) {
558        setObjCoef((*i).first, (*i).second);
559      }
560    }
561    /// \e
562    /// This routine modifies \c expr by only adding to it.
563    void getObjCoeffs(Expression& expr) {
564      /// FIXME not yet implemented
565    }
566    //@}
567  };
568 
569  template <typename _Value>
570  const _Value LPSolverBase<_Value>::INF=std::numeric_limits<_Value>::infinity();
571
572
573  /// \brief Wrapper for GLPK solver
574  ///
575  /// This class implements a lemon wrapper for GLPK.
576  class LPGLPK : public LPSolverBase<double> {
577  public:
578    typedef LPSolverBase<double> Parent;
579
580  public:
581    /// \e
582    LPX* lp;
583
584  public:
585    /// \e
586    LPGLPK() : Parent(),
587                        lp(lpx_create_prob()) {
588      int_row_map.push_back(Row());
589      int_col_map.push_back(Col());
590      lpx_set_int_parm(lp, LPX_K_DUAL, 1);
591    }
592    /// \e
593    ~LPGLPK() {
594      lpx_delete_prob(lp);
595    }
596
597    //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
598
599    /// \e
600    void setMinimize() {
601      lpx_set_obj_dir(lp, LPX_MIN);
602    }
603    /// \e
604    void setMaximize() {
605      lpx_set_obj_dir(lp, LPX_MAX);
606    }
607
608    //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS
609
610  protected:
611    /// \e
612    int _addCol() {
613      int i=lpx_add_cols(lp, 1);
614      _setColLowerBound(i, -INF);
615      _setColUpperBound(i, INF);
616      return i;
617    }
618    /// \e
619    int _addRow() {
620      int i=lpx_add_rows(lp, 1);
621      return i;
622    }
623    /// \e
624    virtual void _setRowCoeffs(int i,
625                               const std::vector<std::pair<int, double> >& coeffs) {
626      int mem_length=1+colNum();
627      int* indices = new int[mem_length];
628      double* doubles = new double[mem_length];
629      int length=0;
630      for (std::vector<std::pair<int, double> >::
631             const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
632        ++length;
633        indices[length]=it->first;
634        doubles[length]=it->second;
635      }
636      lpx_set_mat_row(lp, i, length, indices, doubles);
637      delete [] indices;
638      delete [] doubles;
639    }
640    /// \e
641    virtual void _getRowCoeffs(int i,
642                               std::vector<std::pair<int, double> >& coeffs) {
643      int mem_length=1+colNum();
644      int* indices = new int[mem_length];
645      double* doubles = new double[mem_length];
646      int length=lpx_get_mat_row(lp, i, indices, doubles);
647      for (int i=1; i<=length; ++i) {
648        coeffs.push_back(std::make_pair(indices[i], doubles[i]));
649      }
650      delete [] indices;
651      delete [] doubles;
652    }
653    /// \e
654    virtual void _setColCoeffs(int i,
655                               const std::vector<std::pair<int, double> >& coeffs) {
656      int mem_length=1+rowNum();
657      int* indices = new int[mem_length];
658      double* doubles = new double[mem_length];
659      int length=0;
660      for (std::vector<std::pair<int, double> >::
661             const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
662        ++length;
663        indices[length]=it->first;
664        doubles[length]=it->second;
665      }
666      lpx_set_mat_col(lp, i, length, indices, doubles);
667      delete [] indices;
668      delete [] doubles;
669    }
670    /// \e
671    virtual void _getColCoeffs(int i,
672                               std::vector<std::pair<int, double> >& coeffs) {
673      int mem_length=1+rowNum();
674      int* indices = new int[mem_length];
675      double* doubles = new double[mem_length];
676      int length=lpx_get_mat_col(lp, i, indices, doubles);
677      for (int i=1; i<=length; ++i) {
678        coeffs.push_back(std::make_pair(indices[i], doubles[i]));
679      }
680      delete [] indices;
681      delete [] doubles;
682    }
683    /// \e
684    virtual void _eraseCol(int i) {
685      int cols[2];
686      cols[1]=i;
687      lpx_del_cols(lp, 1, cols);
688    }
689    virtual void _eraseRow(int i) {
690      int rows[2];
691      rows[1]=i;
692      lpx_del_rows(lp, 1, rows);
693    }
694    virtual void _setColLowerBound(int i, double lo) {
695      if (lo==INF) {
696        //FIXME error
697      }
698      int b=lpx_get_col_type(lp, i);
699      double up=lpx_get_col_ub(lp, i); 
700      if (lo==-INF) {
701        switch (b) {
702        case LPX_FR:
703        case LPX_LO:
704          lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
705          break;
706        case LPX_UP:
707          break;
708        case LPX_DB:
709        case LPX_FX:
710          lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
711          break;
712        default: ;
713          //FIXME error
714        }
715      } else {
716        switch (b) {
717        case LPX_FR:
718        case LPX_LO:
719          lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
720          break;
721        case LPX_UP:     
722        case LPX_DB:
723        case LPX_FX:
724          if (lo==up)
725            lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
726          else
727            lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
728          break;
729        default: ;
730          //FIXME error
731        }
732      }
733    }
734    virtual double _getColLowerBound(int i) {
735      int b=lpx_get_col_type(lp, i);
736      switch (b) {
737      case LPX_FR:
738        return -INF;
739      case LPX_LO:
740        return lpx_get_col_lb(lp, i);
741      case LPX_UP:
742        return -INF;
743      case LPX_DB:
744      case LPX_FX:
745        return lpx_get_col_lb(lp, i);
746      default: ;
747        //FIXME error
748        return 0.0;
749      }
750    }
751    virtual void _setColUpperBound(int i, double up) {
752      if (up==-INF) {
753        //FIXME error
754      }
755      int b=lpx_get_col_type(lp, i);
756      double lo=lpx_get_col_lb(lp, i);
757      if (up==INF) {
758        switch (b) {
759        case LPX_FR:
760        case LPX_LO:
761          break;
762        case LPX_UP:
763          lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
764          break;
765        case LPX_DB:
766        case LPX_FX:
767          lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
768          break;
769        default: ;
770          //FIXME error
771        }
772      } else {
773        switch (b) {
774        case LPX_FR:
775          lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
776        case LPX_LO:
777          if (lo==up)
778            lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
779          else
780            lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
781          break;
782        case LPX_UP:
783          lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
784          break;
785        case LPX_DB:
786        case LPX_FX:
787          if (lo==up)
788            lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
789          else
790            lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
791          break;
792        default: ;
793          //FIXME error
794        }
795      }
796    }
797    virtual double _getColUpperBound(int i) {
798      int b=lpx_get_col_type(lp, i);
799      switch (b) {
800      case LPX_FR:
801      case LPX_LO:
802        return INF;
803      case LPX_UP:
804      case LPX_DB:
805      case LPX_FX:
806        return lpx_get_col_ub(lp, i);
807      default: ;
808        //FIXME error
809        return 0.0;
810      }
811    }
812    virtual void _setRowLowerBound(int i, double lo) {
813      if (lo==INF) {
814        //FIXME error
815      }
816      int b=lpx_get_row_type(lp, i);
817      double up=lpx_get_row_ub(lp, i); 
818      if (lo==-INF) {
819        switch (b) {
820        case LPX_FR:
821        case LPX_LO:
822          lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
823          break;
824        case LPX_UP:
825          break;
826        case LPX_DB:
827        case LPX_FX:
828          lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
829          break;
830        default: ;
831          //FIXME error
832        }
833      } else {
834        switch (b) {
835        case LPX_FR:
836        case LPX_LO:
837          lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
838          break;
839        case LPX_UP:     
840        case LPX_DB:
841        case LPX_FX:
842          if (lo==up)
843            lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
844          else
845            lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
846          break;
847        default: ;
848          //FIXME error
849        }
850      }
851    }
852    virtual double _getRowLowerBound(int i) {
853      int b=lpx_get_row_type(lp, i);
854      switch (b) {
855      case LPX_FR:
856        return -INF;
857      case LPX_LO:
858        return lpx_get_row_lb(lp, i);
859      case LPX_UP:
860        return -INF;
861      case LPX_DB:
862      case LPX_FX:
863        return lpx_get_row_lb(lp, i);
864      default: ;
865        //FIXME error
866        return 0.0;
867      }
868    }
869    virtual void _setRowUpperBound(int i, double up) {
870      if (up==-INF) {
871        //FIXME error
872      }
873      int b=lpx_get_row_type(lp, i);
874      double lo=lpx_get_row_lb(lp, i);
875      if (up==INF) {
876        switch (b) {
877        case LPX_FR:
878        case LPX_LO:
879          break;
880        case LPX_UP:
881          lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
882          break;
883        case LPX_DB:
884        case LPX_FX:
885          lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
886          break;
887        default: ;
888          //FIXME error
889        }
890      } else {
891        switch (b) {
892        case LPX_FR:
893          lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
894        case LPX_LO:
895          if (lo==up)
896            lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
897          else
898            lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
899          break;
900        case LPX_UP:
901          lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
902          break;
903        case LPX_DB:
904        case LPX_FX:
905          if (lo==up)
906            lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
907          else
908            lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
909          break;
910        default: ;
911          //FIXME error
912        }
913      }
914    }
915    virtual double _getRowUpperBound(int i) {
916      int b=lpx_get_row_type(lp, i);
917      switch (b) {
918      case LPX_FR:
919      case LPX_LO:
920        return INF;
921      case LPX_UP:
922      case LPX_DB:
923      case LPX_FX:
924        return lpx_get_row_ub(lp, i);
925      default: ;
926        //FIXME error
927        return 0.0;
928      }
929    }
930    /// \e
931    virtual double _getObjCoef(int i) {
932      return lpx_get_obj_coef(lp, i);
933    }
934    /// \e
935    virtual void _setObjCoef(int i, double obj_coef) {
936      lpx_set_obj_coef(lp, i, obj_coef);
937    }
938  public:
939    /// \e
940    void solveSimplex() { lpx_simplex(lp); }
941    /// \e
942    void solvePrimalSimplex() { lpx_simplex(lp); }
943    /// \e
944    void solveDualSimplex() { lpx_simplex(lp); }
945    /// \e
946  protected:
947    virtual double _getPrimal(int i) {
948      return lpx_get_col_prim(lp, i);
949    }
950  public:
951    /// \e
952    double getObjVal() { return lpx_get_obj_val(lp); }
953    /// \e
954    int rowNum() const { return lpx_get_num_rows(lp); }
955    /// \e
956    int colNum() const { return lpx_get_num_cols(lp); }
957    /// \e
958    int warmUp() { return lpx_warm_up(lp); }
959    /// \e
960    void printWarmUpStatus(int i) {
961      switch (i) {
962      case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
963      case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;   
964      case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
965      case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
966      }
967    }
968    /// \e
969    int getPrimalStatus() { return lpx_get_prim_stat(lp); }
970    /// \e
971    void printPrimalStatus(int i) {
972      switch (i) {
973      case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
974      case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;     
975      case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
976      case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
977      }
978    }
979    /// \e
980    int getDualStatus() { return lpx_get_dual_stat(lp); }
981    /// \e
982    void printDualStatus(int i) {
983      switch (i) {
984      case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
985      case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;     
986      case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
987      case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
988      }
989    }
990    /// Returns the status of the slack variable assigned to row \c row.
991    int getRowStat(const Row& row) {
992      return lpx_get_row_stat(lp, row_iter_map[row]);
993    }
994    /// \e
995    void printRowStatus(int i) {
996      switch (i) {
997      case LPX_BS: cout << "LPX_BS" << endl; break;
998      case LPX_NL: cout << "LPX_NL" << endl; break;     
999      case LPX_NU: cout << "LPX_NU" << endl; break;
1000      case LPX_NF: cout << "LPX_NF" << endl; break;
1001      case LPX_NS: cout << "LPX_NS" << endl; break;
1002      }
1003    }
1004    /// Returns the status of the variable assigned to column \c col.
1005    int getColStat(const Col& col) {
1006      return lpx_get_col_stat(lp, col_iter_map[col]);
1007    }
1008    /// \e
1009    void printColStatus(int i) {
1010      switch (i) {
1011      case LPX_BS: cout << "LPX_BS" << endl; break;
1012      case LPX_NL: cout << "LPX_NL" << endl; break;     
1013      case LPX_NU: cout << "LPX_NU" << endl; break;
1014      case LPX_NF: cout << "LPX_NF" << endl; break;
1015      case LPX_NS: cout << "LPX_NS" << endl; break;
1016      }
1017    }
1018  };
1019 
1020  /// @}
1021
1022} //namespace lemon
1023
1024#endif //LEMON_LP_SOLVER_WRAPPER_H
Note: See TracBrowser for help on using the repository browser.