COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/marci/lp/lp_solver_base.h @ 1112:b258584569f2

Last change on this file since 1112:b258584569f2 was 1112:b258584569f2, checked in by marci, 20 years ago

try of grouping for documentation

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