src/work/marci/lp/lp_solver_base.h
changeset 1144 1cfabf245433
parent 1143 4fb22cfa5759
child 1152 1765ff9fefa1
equal deleted inserted replaced
3:83ba47e3d0bf 4:5c774b4e1fcd
   191     //UNCATEGORIZED
   191     //UNCATEGORIZED
   192 
   192 
   193     /// \e
   193     /// \e
   194     typedef _Value Value;
   194     typedef _Value Value;
   195     /// \e
   195     /// \e
   196     typedef IterablePartition<int>::ClassIt RowIt;
   196     typedef IterablePartition<int>::ClassIt Row;
   197     /// \e
   197     /// \e
   198     typedef IterablePartition<int>::ClassIt ColIt;
   198     typedef IterablePartition<int>::ClassIt Col;
   199   public:
   199   public:
   200     /// \e
   200     /// \e
   201     IterablePartition<int> row_iter_map;
   201     IterablePartition<int> row_iter_map;
   202     /// \e
   202     /// \e
   203     IterablePartition<int> col_iter_map;
   203     IterablePartition<int> col_iter_map;
   204     /// \e
   204     /// \e
   205     std::vector<RowIt> int_row_map;
   205     std::vector<Row> int_row_map;
   206     /// \e
   206     /// \e
   207     std::vector<ColIt> int_col_map;
   207     std::vector<Col> int_col_map;
   208     /// \e
   208     /// \e
   209     const int VALID_CLASS;
   209     const int VALID_CLASS;
   210     /// \e
   210     /// \e
   211     const int INVALID_CLASS;
   211     const int INVALID_CLASS;
   212     /// \e 
   212     /// \e 
   269     virtual void printPrimalStatus(int i) = 0;
   269     virtual void printPrimalStatus(int i) = 0;
   270     /// \e
   270     /// \e
   271     virtual int getDualStatus() = 0;
   271     virtual int getDualStatus() = 0;
   272     /// \e
   272     /// \e
   273     virtual void printDualStatus(int i) = 0;
   273     virtual void printDualStatus(int i) = 0;
   274     /// Returns the status of the slack variable assigned to row \c row_it.
   274     /// Returns the status of the slack variable assigned to row \c row.
   275     virtual int getRowStat(const RowIt& row_it) = 0;
   275     virtual int getRowStat(const Row& row) = 0;
   276     /// \e
   276     /// \e
   277     virtual void printRowStatus(int i) = 0;
   277     virtual void printRowStatus(int i) = 0;
   278     /// Returns the status of the variable assigned to column \c col_it.
   278     /// Returns the status of the variable assigned to column \c col.
   279     virtual int getColStat(const ColIt& col_it) = 0;
   279     virtual int getColStat(const Col& col) = 0;
   280     /// \e
   280     /// \e
   281     virtual void printColStatus(int i) = 0;
   281     virtual void printColStatus(int i) = 0;
   282 
   282 
   283     //@}
   283     //@}
   284 
   284 
   373   public:
   373   public:
   374 
   374 
   375     //MATRIX MANIPULATING FUNCTIONS
   375     //MATRIX MANIPULATING FUNCTIONS
   376 
   376 
   377     /// \e
   377     /// \e
   378     ColIt addCol() {
   378     Col addCol() {
   379       int i=_addCol();  
   379       int i=_addCol();  
   380       ColIt col_it;
   380       Col col;
   381       col_iter_map.first(col_it, INVALID_CLASS);
   381       col_iter_map.first(col, INVALID_CLASS);
   382       if (col_iter_map.valid(col_it)) { //van hasznalhato hely
   382       if (col_iter_map.valid(col)) { //van hasznalhato hely
   383 	col_iter_map.set(col_it, INVALID_CLASS, VALID_CLASS);
   383 	col_iter_map.set(col, INVALID_CLASS, VALID_CLASS);
   384 	col_iter_map[col_it]=i;
   384 	col_iter_map[col]=i;
   385       } else { //a cucc vegere kell inzertalni mert nincs szabad hely
   385       } else { //a cucc vegere kell inzertalni mert nincs szabad hely
   386 	col_it=col_iter_map.push_back(i, VALID_CLASS);
   386 	col=col_iter_map.push_back(i, VALID_CLASS);
   387       }
   387       }
   388       int_col_map.push_back(col_it);
   388       int_col_map.push_back(col);
   389       return col_it;
   389       return col;
   390     }
   390     }
   391     /// \e
   391     /// \e
   392     RowIt addRow() {
   392     Row addRow() {
   393       int i=_addRow();
   393       int i=_addRow();
   394       RowIt row_it;
   394       Row row;
   395       row_iter_map.first(row_it, INVALID_CLASS);
   395       row_iter_map.first(row, INVALID_CLASS);
   396       if (row_iter_map.valid(row_it)) { //van hasznalhato hely
   396       if (row_iter_map.valid(row)) { //van hasznalhato hely
   397 	row_iter_map.set(row_it, INVALID_CLASS, VALID_CLASS);
   397 	row_iter_map.set(row, INVALID_CLASS, VALID_CLASS);
   398 	row_iter_map[row_it]=i;
   398 	row_iter_map[row]=i;
   399       } else { //a cucc vegere kell inzertalni mert nincs szabad hely
   399       } else { //a cucc vegere kell inzertalni mert nincs szabad hely
   400 	row_it=row_iter_map.push_back(i, VALID_CLASS);
   400 	row=row_iter_map.push_back(i, VALID_CLASS);
   401       }
   401       }
   402       int_row_map.push_back(row_it);
   402       int_row_map.push_back(row);
   403       return row_it;
   403       return row;
   404     }
   404     }
   405     /// \e
   405     /// \e
   406     void eraseCol(const ColIt& col_it) {
   406     void eraseCol(const Col& col) {
   407       col_iter_map.set(col_it, VALID_CLASS, INVALID_CLASS);
   407       col_iter_map.set(col, VALID_CLASS, INVALID_CLASS);
   408       int cols[2];
   408       int cols[2];
   409       cols[1]=col_iter_map[col_it];
   409       cols[1]=col_iter_map[col];
   410       _eraseCol(cols[1]);
   410       _eraseCol(cols[1]);
   411       col_iter_map[col_it]=0; //glpk specifikus, de kell ez??
   411       col_iter_map[col]=0; //glpk specifikus, de kell ez??
   412       ColIt it;
   412       Col it;
   413       for (col_iter_map.first(it, VALID_CLASS); 
   413       for (col_iter_map.first(it, VALID_CLASS); 
   414 	   col_iter_map.valid(it); col_iter_map.next(it)) {
   414 	   col_iter_map.valid(it); col_iter_map.next(it)) {
   415 	if (col_iter_map[it]>cols[1]) --col_iter_map[it];
   415 	if (col_iter_map[it]>cols[1]) --col_iter_map[it];
   416       }
   416       }
   417       int_col_map.erase(int_col_map.begin()+cols[1]);
   417       int_col_map.erase(int_col_map.begin()+cols[1]);
   418     }
   418     }
   419     /// \e
   419     /// \e
   420     void eraseRow(const RowIt& row_it) {
   420     void eraseRow(const Row& row) {
   421       row_iter_map.set(row_it, VALID_CLASS, INVALID_CLASS);
   421       row_iter_map.set(row, VALID_CLASS, INVALID_CLASS);
   422       int rows[2];
   422       int rows[2];
   423       rows[1]=row_iter_map[row_it];
   423       rows[1]=row_iter_map[row];
   424       _eraseRow(rows[1]);
   424       _eraseRow(rows[1]);
   425       row_iter_map[row_it]=0; //glpk specifikus, de kell ez??
   425       row_iter_map[row]=0; //glpk specifikus, de kell ez??
   426       RowIt it;
   426       Row it;
   427       for (row_iter_map.first(it, VALID_CLASS); 
   427       for (row_iter_map.first(it, VALID_CLASS); 
   428 	   row_iter_map.valid(it); row_iter_map.next(it)) {
   428 	   row_iter_map.valid(it); row_iter_map.next(it)) {
   429 	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
   429 	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
   430       }
   430       }
   431       int_row_map.erase(int_row_map.begin()+rows[1]);
   431       int_row_map.erase(int_row_map.begin()+rows[1]);
   432     }
   432     }
   433     /// \e
   433     /// \e
   434     template <typename Begin, typename End>
   434     void setColLowerBound(Col col, _Value lo) {
   435     void setRowCoeffs(RowIt row_it, Begin begin, End end) {
   435       _setColLowerBound(col_iter_map[col], lo);
   436       std::vector<std::pair<int, double> > coeffs;
   436     }
   437       for ( ; begin!=end; ++begin) {
   437     /// \e
   438 	coeffs.push_back(std::
   438     _Value getColLowerBound(Col col) {
   439 			 make_pair(col_iter_map[begin->first], begin->second));
   439       return _getColLowerBound(col_iter_map[col]);
   440       }
   440     }
   441       _setRowCoeffs(row_iter_map[row_it], coeffs);
   441     /// \e
   442     }
   442     void setColUpperBound(Col col, _Value up) {
   443     /// \e
   443       _setColUpperBound(col_iter_map[col], up);
   444     template <typename Begin, typename End>
   444     }
   445     void setColCoeffs(ColIt col_it, Begin begin, End end) {
   445     /// \e
   446       std::vector<std::pair<int, double> > coeffs;
   446     _Value getColUpperBound(Col col) {      
   447       for ( ; begin!=end; ++begin) {
   447       return _getColUpperBound(col_iter_map[col]);
   448 	coeffs.push_back(std::
   448     }
   449 			 make_pair(row_iter_map[begin->first], begin->second));
   449     /// \e
   450       }
   450     void setRowLowerBound(Row row, _Value lo) {
   451       _setColCoeffs(col_iter_map[col_it], coeffs);
   451       _setRowLowerBound(row_iter_map[row], lo);
   452     }
   452     }
   453     /// \e
   453     /// \e
   454     void setColLowerBound(ColIt col_it, _Value lo) {
   454     _Value getRowLowerBound(Row row) {
   455       _setColLowerBound(col_iter_map[col_it], lo);
   455       return _getRowLowerBound(row_iter_map[row]);
   456     }
   456     }
   457     /// \e
   457     /// \e
   458     _Value getColLowerBound(ColIt col_it) {
   458     void setRowUpperBound(Row row, _Value up) {
   459       return _getColLowerBound(col_iter_map[col_it]);
   459       _setRowUpperBound(row_iter_map[row], up);
   460     }
   460     }
   461     /// \e
   461     /// \e
   462     void setColUpperBound(ColIt col_it, _Value up) {
   462     _Value getRowUpperBound(Row row) {      
   463       _setColUpperBound(col_iter_map[col_it], up);
   463       return _getRowUpperBound(row_iter_map[row]);
   464     }
   464     }
   465     /// \e
   465     /// \e
   466     _Value getColUpperBound(ColIt col_it) {      
   466     void setObjCoef(const Col& col, _Value obj_coef) {
   467       return _getColUpperBound(col_iter_map[col_it]);
   467       _setObjCoef(col_iter_map[col], obj_coef);
   468     }
   468     }
   469     /// \e
   469     /// \e
   470     void setRowLowerBound(RowIt row_it, _Value lo) {
   470     _Value getObjCoef(const Col& col) {
   471       _setRowLowerBound(row_iter_map[row_it], lo);
   471       return _getObjCoef(col_iter_map[col]);
   472     }
       
   473     /// \e
       
   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]);
       
   484     }
       
   485     /// \e
       
   486     void setObjCoef(const ColIt& col_it, _Value obj_coef) {
       
   487       _setObjCoef(col_iter_map[col_it], obj_coef);
       
   488     }
       
   489     /// \e
       
   490     _Value getObjCoef(const ColIt& col_it) {
       
   491       return _getObjCoef(col_iter_map[col_it]);
       
   492     }
   472     }
   493 
   473 
   494     //SOLUTION RETRIEVING FUNCTIONS
   474     //SOLUTION RETRIEVING FUNCTIONS
   495 
   475 
   496     /// \e
   476     /// \e
   497     _Value getPrimal(const ColIt& col_it) {
   477     _Value getPrimal(const Col& col) {
   498       return _getPrimal(col_iter_map[col_it]);
   478       return _getPrimal(col_iter_map[col]);
   499     }    
   479     }    
   500 
   480 
   501     //@}
   481     //@}
   502 
   482 
   503     /*! @name User friend interface
   483     /*! @name User friend interface
   506     //@{
   486     //@{
   507 
   487 
   508     //EXPRESSION TYPES
   488     //EXPRESSION TYPES
   509 
   489 
   510     /// \e
   490     /// \e
   511     typedef Expr<ColIt, _Value> Expression;
   491     typedef Expr<Col, _Value> Expression;
   512     /// \e
   492     /// \e
   513     typedef Expr<RowIt, _Value> DualExpression;
   493     typedef Expr<Row, _Value> DualExpression;
       
   494     /// \e
       
   495     typedef Constr<Col, _Value> Constraint;
   514 
   496 
   515     //MATRIX MANIPULATING FUNCTIONS
   497     //MATRIX MANIPULATING FUNCTIONS
   516 
   498 
   517     /// \e
   499     /// \e
   518     void setRowCoeffs(RowIt row_it, const Expression& expr) {
   500     void setRowCoeffs(Row row, const Expression& expr) {
   519       std::vector<std::pair<int, _Value> > row_coeffs;
   501       std::vector<std::pair<int, _Value> > row_coeffs;
   520       for(typename Expression::Data::const_iterator i=expr.data.begin(); 
   502       for(typename Expression::Data::const_iterator i=expr.data.begin(); 
   521 	  i!=expr.data.end(); ++i) {
   503 	  i!=expr.data.end(); ++i) {
   522 	row_coeffs.push_back(std::make_pair
   504 	row_coeffs.push_back(std::make_pair
   523 			     (col_iter_map[(*i).first], (*i).second));
   505 			     (col_iter_map[(*i).first], (*i).second));
   524       }
   506       }
   525       _setRowCoeffs(row_iter_map[row_it], row_coeffs);
   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;
   526     }
   522     }
   527     /// \e
   523     /// \e
   528     /// This routine modifies \c expr by only adding to it.
   524     /// This routine modifies \c expr by only adding to it.
   529     void getRowCoeffs(RowIt row_it, Expression& expr) {
   525     void getRowCoeffs(Row row, Expression& expr) {
   530       std::vector<std::pair<int, _Value> > row_coeffs;
   526       std::vector<std::pair<int, _Value> > row_coeffs;
   531       _getRowCoeffs(row_iter_map[row_it], row_coeffs);
   527       _getRowCoeffs(row_iter_map[row], row_coeffs);
   532       for(typename std::vector<std::pair<int, _Value> >::const_iterator 
   528       for(typename std::vector<std::pair<int, _Value> >::const_iterator 
   533  	    i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) {
   529  	    i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) {
   534  	expr+= (*i).second*int_col_map[(*i).first];
   530  	expr+= (*i).second*int_col_map[(*i).first];
   535       }
   531       }
   536     }
   532     }
   537     /// \e
   533     /// \e
   538     void setColCoeffs(ColIt col_it, const DualExpression& expr) {
   534     void setColCoeffs(Col col, const DualExpression& expr) {
   539       std::vector<std::pair<int, _Value> > col_coeffs;
   535       std::vector<std::pair<int, _Value> > col_coeffs;
   540       for(typename DualExpression::Data::const_iterator i=expr.data.begin(); 
   536       for(typename DualExpression::Data::const_iterator i=expr.data.begin(); 
   541 	  i!=expr.data.end(); ++i) {
   537 	  i!=expr.data.end(); ++i) {
   542 	col_coeffs.push_back(std::make_pair
   538 	col_coeffs.push_back(std::make_pair
   543 			     (row_iter_map[(*i).first], (*i).second));
   539 			     (row_iter_map[(*i).first], (*i).second));
   544       }
   540       }
   545       _setColCoeffs(col_iter_map[col_it], col_coeffs);
   541       _setColCoeffs(col_iter_map[col], col_coeffs);
   546     }
   542     }
   547     /// \e
   543     /// \e
   548     /// This routine modifies \c expr by only adding to it.
   544     /// This routine modifies \c expr by only adding to it.
   549     void getColCoeffs(ColIt col_it, DualExpression& expr) {
   545     void getColCoeffs(Col col, DualExpression& expr) {
   550       std::vector<std::pair<int, _Value> > col_coeffs;
   546       std::vector<std::pair<int, _Value> > col_coeffs;
   551       _getColCoeffs(col_iter_map[col_it], col_coeffs);
   547       _getColCoeffs(col_iter_map[col], col_coeffs);
   552       for(typename std::vector<std::pair<int, _Value> >::const_iterator 
   548       for(typename std::vector<std::pair<int, _Value> >::const_iterator 
   553  	    i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
   549  	    i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
   554  	expr+= (*i).second*int_row_map[(*i).first];
   550  	expr+= (*i).second*int_row_map[(*i).first];
   555       }
   551       }
   556     }
   552     }
   587 
   583 
   588   public:
   584   public:
   589     /// \e
   585     /// \e
   590     LPGLPK() : Parent(), 
   586     LPGLPK() : Parent(), 
   591 			lp(lpx_create_prob()) {
   587 			lp(lpx_create_prob()) {
   592       int_row_map.push_back(RowIt());
   588       int_row_map.push_back(Row());
   593       int_col_map.push_back(ColIt());
   589       int_col_map.push_back(Col());
   594       lpx_set_int_parm(lp, LPX_K_DUAL, 1);
   590       lpx_set_int_parm(lp, LPX_K_DUAL, 1);
   595     }
   591     }
   596     /// \e
   592     /// \e
   597     ~LPGLPK() {
   593     ~LPGLPK() {
   598       lpx_delete_prob(lp);
   594       lpx_delete_prob(lp);
   989       case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;	
   985       case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;	
   990       case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
   986       case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
   991       case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
   987       case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
   992       }
   988       }
   993     }
   989     }
   994     /// Returns the status of the slack variable assigned to row \c row_it.
   990     /// Returns the status of the slack variable assigned to row \c row.
   995     int getRowStat(const RowIt& row_it) { 
   991     int getRowStat(const Row& row) { 
   996       return lpx_get_row_stat(lp, row_iter_map[row_it]); 
   992       return lpx_get_row_stat(lp, row_iter_map[row]); 
   997     }
   993     }
   998     /// \e
   994     /// \e
   999     void printRowStatus(int i) {
   995     void printRowStatus(int i) {
  1000       switch (i) {
   996       switch (i) {
  1001       case LPX_BS: cout << "LPX_BS" << endl; break;
   997       case LPX_BS: cout << "LPX_BS" << endl; break;
  1003       case LPX_NU: cout << "LPX_NU" << endl; break;
   999       case LPX_NU: cout << "LPX_NU" << endl; break;
  1004       case LPX_NF: cout << "LPX_NF" << endl; break;
  1000       case LPX_NF: cout << "LPX_NF" << endl; break;
  1005       case LPX_NS: cout << "LPX_NS" << endl; break;
  1001       case LPX_NS: cout << "LPX_NS" << endl; break;
  1006       }
  1002       }
  1007     }
  1003     }
  1008     /// Returns the status of the variable assigned to column \c col_it.
  1004     /// Returns the status of the variable assigned to column \c col.
  1009     int getColStat(const ColIt& col_it) { 
  1005     int getColStat(const Col& col) { 
  1010       return lpx_get_col_stat(lp, col_iter_map[col_it]); 
  1006       return lpx_get_col_stat(lp, col_iter_map[col]); 
  1011     }
  1007     }
  1012     /// \e
  1008     /// \e
  1013     void printColStatus(int i) {
  1009     void printColStatus(int i) {
  1014       switch (i) {
  1010       switch (i) {
  1015       case LPX_BS: cout << "LPX_BS" << endl; break;
  1011       case LPX_BS: cout << "LPX_BS" << endl; break;