COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/marci/lp/lp_solver_base.h @ 1143:4fb22cfa5759

Last change on this file since 1143:4fb22cfa5759 was 1143:4fb22cfa5759, checked in by marci, 16 years ago

The pair of setSomeThing function is getSomeThing.

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