lemon/lp_utils.h
changeset 2363 2aabce558574
parent 2316 c0fae4bbaa5c
child 2364 3a5e67bd42d2
equal deleted inserted replaced
0:08439fb2c27c 1:426bd5f5a470
    20 #define LEMON_LP_UTILS_H
    20 #define LEMON_LP_UTILS_H
    21 
    21 
    22 #include <lemon/lp_base.h>
    22 #include <lemon/lp_base.h>
    23 
    23 
    24 #include <lemon/lemon_reader.h>
    24 #include <lemon/lemon_reader.h>
       
    25 #include <lemon/lemon_writer.h>
    25 
    26 
    26 namespace lemon {
    27 namespace lemon {
    27 
    28 
    28   class LpReader : public LemonReader::SectionReader {
    29   class LpReader : public LemonReader::SectionReader {
    29     typedef LemonReader::SectionReader Parent;
    30     typedef LemonReader::SectionReader Parent;
   317     /// \brief Reader function of the section.
   318     /// \brief Reader function of the section.
   318     ///
   319     ///
   319     /// It reads the content of the section.
   320     /// It reads the content of the section.
   320     virtual void read(std::istream& is) {
   321     virtual void read(std::istream& is) {
   321       std::string line;
   322       std::string line;
   322       std::map<std::string, LpSolverBase::Col> vars;
       
   323       while (getline(is, line)) {
   323       while (getline(is, line)) {
   324         std::istringstream ls(line);
   324         std::istringstream ls(line);
   325         std::string sense;
   325         std::string sense;
   326         ls >> sense;
   326         ls >> sense;
   327         if (sense == "min" || sense == "max") {
   327         if (sense == "min" || sense == "max") {
   357     LpSolverBase& lp;
   357     LpSolverBase& lp;
   358     std::string name;
   358     std::string name;
   359     ColMap cols;
   359     ColMap cols;
   360   };
   360   };
   361 
   361 
       
   362 
       
   363 //   class LpWriter : public LemonWriter::SectionWriter {
       
   364 //     typedef LemonWriter::SectionWriter Parent;
       
   365 //   public:
       
   366 
       
   367 
       
   368 //     /// \brief Constructor.
       
   369 //     ///
       
   370 //     /// Constructor for LpWriter. It creates the LpWriter and attach
       
   371 //     /// it into the given LemonWriter. The lp writer will add
       
   372 //     /// variables, constraints and objective function to the
       
   373 //     /// given lp solver.
       
   374 //     LpWriter(LemonWriter& _writer, LpSolverBase& _lp, 
       
   375 //              const std::string& _name = std::string())
       
   376 //       : Parent(_writer), lp(_lp), name(_name) {} 
       
   377 
       
   378 
       
   379 //     /// \brief Destructor.
       
   380 //     ///
       
   381 //     /// Destructor for NodeSetWriter.
       
   382 //     virtual ~LpWriter() {}
       
   383 
       
   384 //   private:
       
   385 //     LpWriter(const LpWriter&);
       
   386 //     void operator=(const LpWriter&);
       
   387   
       
   388 //   protected:
       
   389 
       
   390 //     /// \brief Gives back true when the SectionWriter can process 
       
   391 //     /// the section with the given header line.
       
   392 //     ///
       
   393 //     /// It gives back the header line of the \c \@lp section.
       
   394 //     virtual std::string header() {
       
   395 //       std::ostringstream ls(line);
       
   396 //       ls << "@lp " << name;
       
   397 //       return ls.str();
       
   398 //     }
       
   399 
       
   400 //   private:
       
   401 
       
   402 //     std::ostream& writeConstraint(std::ostream& is, LpSolverBase::Constr& c) {
       
   403 //       char x;
       
   404 
       
   405       
       
   406 //       LpSolverBase::Expr e1, e2;
       
   407 //       Relation op1;
       
   408 //       is >> std::ws;
       
   409 //       writexpression(is, e1);
       
   410 //       is >> std::ws;
       
   411 //       writeRelation(is, op1);
       
   412 //       is >> std::ws;
       
   413 //       writexpression(is, e2);
       
   414 //       if (!is.get(x)) {
       
   415 //         if (op1 == LE) {
       
   416 //           c = e1 <= e2;
       
   417 //         } else if (op1 == GE) {
       
   418 //           c = e1 >= e2;
       
   419 //         } else {
       
   420 //           c = e1 == e2;
       
   421 //         }
       
   422 //       } else {
       
   423 //         is.putback(x);
       
   424 //         LpSolverBase::Expr e3;
       
   425 //         Relation op2;
       
   426 //         writeRelation(is, op2);
       
   427 //         is >> std::ws;
       
   428 //         writexpression(is, e3);
       
   429 //         if (!e1.empty() || !e3.empty()) {
       
   430 //           throw DataFormatError("Wrong range format");
       
   431 //         }
       
   432 //         if (op2 != op1 || op1 == EQ) {
       
   433 //           throw DataFormatError("Wrong range format");
       
   434 //         }
       
   435 //         if (op1 == LE) {
       
   436 //           c = e1.constComp() <= e2 <= e3.constComp();
       
   437 //         } else {
       
   438 //           c = e1.constComp() >= e2 >= e3.constComp();
       
   439 //         }
       
   440 //       }
       
   441 //     }
       
   442 
       
   443 //     std::ostream& writexpression(std::ostream& is, LpSolverBase::Expr& e) {
       
   444 //       LpSolverBase::Col c;
       
   445 //       double d;
       
   446 //       char x;
       
   447 //       writelement(is, c, d);
       
   448 //       if (c != INVALID) {
       
   449 //         e += d * c;
       
   450 //       } else {
       
   451 //         e += d;
       
   452 //       }
       
   453 //       is >> std::ws;
       
   454 //       while (is.get(x) && (x == '+' || x == '-')) {
       
   455 //         is >> std::ws;
       
   456 //         writelement(is, c, d);
       
   457 //         if (c != INVALID) {
       
   458 //           e += (x == '+' ? d : -d) * c;
       
   459 //         } else {
       
   460 //           e += (x == '+' ? d : -d);
       
   461 //         }
       
   462 //         is >> std::ws;
       
   463 //       }
       
   464 //       if (!is) {
       
   465 //         is.clear();
       
   466 //       } else {
       
   467 //         is.putback(x);
       
   468 //       }
       
   469 //       return is;
       
   470 //     }
       
   471 
       
   472 //     std::ostream& writelement(std::ostream& is, 
       
   473 //                               LpSolverBase::Col& c, double& d) { 
       
   474 //       d = 1.0;
       
   475 //       c = INVALID;
       
   476 //       char x, y;
       
   477 //       if (!is.get(x)) throw DataFormatError("Cannot find lp element");
       
   478 //       if (x == '+' || x == '-') {
       
   479 //         is >> std::ws;
       
   480 //         d *= x == '-' ? -1 : 1;
       
   481 //         while (is.get(x) && (x == '+' || x == '-')) {
       
   482 //           d *= x == '-' ? -1 : 1;
       
   483 //           is >> std::ws;
       
   484 //         }
       
   485 //         if (!is) throw DataFormatError("Cannot find lp element");
       
   486 //       }
       
   487 //       if (numFirstChar(x)) {
       
   488 //         is.putback(x);
       
   489 //         double e;
       
   490 //         writeNum(is, e);
       
   491 //         d *= e;
       
   492 //       } else if (varFirstChar(x)) {
       
   493 //         is.putback(x);
       
   494 //         LpSolverBase::Col f;
       
   495 //         writeCol(is, f);
       
   496 //         c = f;
       
   497 //       } else {
       
   498 //         throw DataFormatError("Invalid expression format");          
       
   499 //       }
       
   500 //       is >> std::ws;
       
   501 //       while (is.get(y) && (y == '*' || y == '/')) {
       
   502 //         is >> std::ws;
       
   503 //         if (!is.get(x)) throw DataFormatError("Cannot find lp element");
       
   504 //         if (x == '+' || x == '-') {
       
   505 //           is >> std::ws;
       
   506 //           d *= x == '-' ? -1 : 1;
       
   507 //           while (is.get(x) && (x == '+' || x == '-')) {
       
   508 //             d *= x == '-' ? -1 : 1;
       
   509 //             is >> std::ws;
       
   510 //           }
       
   511 //           if (!is) throw DataFormatError("Cannot find lp element");
       
   512 //         }
       
   513 //         if (numFirstChar(x)) {
       
   514 //           is.putback(x);
       
   515 //           double e;
       
   516 //           writeNum(is, e);
       
   517 //           if (y == '*') {
       
   518 //             d *= e;
       
   519 //           } else {
       
   520 //             d /= e;
       
   521 //           }
       
   522 //         } else if (varFirstChar(x)) {
       
   523 //           is.putback(x);
       
   524 //           LpSolverBase::Col f;
       
   525 //           writeCol(is, f);
       
   526 //           if (y == '*') {
       
   527 //             if (c == INVALID) {
       
   528 //               c = f;
       
   529 //             } else {
       
   530 //               throw DataFormatError("Quadratic element in expression");
       
   531 //             }
       
   532 //           } else {
       
   533 //             throw DataFormatError("Division by variable");
       
   534 //           }
       
   535 //         } else {
       
   536 //           throw DataFormatError("Invalid expression format");          
       
   537 //         }
       
   538 //         is >> std::ws;
       
   539 //       }
       
   540 //       if (!is) {
       
   541 //         is.clear();
       
   542 //       } else {
       
   543 //         is.putback(y);
       
   544 //       }
       
   545 //       return is;
       
   546 //     }
       
   547 
       
   548 //     std::ostream& writeCol(std::ostream& is, LpSolverBase::Col& c) {
       
   549 //       char x;
       
   550 //       std::string var;
       
   551 //       while (is.get(x) && varChar(x)) {
       
   552 //         var += x;
       
   553 //       }
       
   554 //       if (!is) {
       
   555 //         is.clear();
       
   556 //       } else {
       
   557 //         is.putback(x);
       
   558 //       }
       
   559 //       ColMap::const_iterator it = cols.find(var);
       
   560 //       if (cols.find(var) != cols.end()) {
       
   561 //         c = it->second;
       
   562 //       } else {
       
   563 //         c = lp.addCol();
       
   564 //         cols.insert(std::make_pair(var, c));
       
   565 //         lp.colName(c, var);
       
   566 //       }
       
   567 //       return is;
       
   568 //     }
       
   569 
       
   570 //     std::ostream& writeNum(std::ostream& is, double& d) {
       
   571 //       is >> d;
       
   572 //       if (!is) throw DataFormatError("Wrong number format");
       
   573 //       return is;
       
   574 //     }
       
   575 
       
   576 //     std::ostream& writeRelation(std::ostream& is, Relation& op) {
       
   577 //       char x, y;
       
   578 //       if (!is.get(x) || !(x == '<' || x == '=' || x == '>')) {
       
   579 //         throw DataFormatError("Wrong relation operator");
       
   580 //       }
       
   581 //       if (!is.get(y) || y != '=') {
       
   582 //         throw DataFormatError("Wrong relation operator");
       
   583 //       }
       
   584 //       switch (x) {
       
   585 //       case '<': op = LE; 
       
   586 //         break;
       
   587 //       case '=': op = EQ; 
       
   588 //         break;
       
   589 //       case '>': op = GE; 
       
   590 //         break;
       
   591 //       }
       
   592 //       return is;
       
   593 //     }
       
   594 
       
   595 //     static bool relationFirstChar(char c) {
       
   596 //       return c == '<' || c == '=' || c == '>';
       
   597 //     }
       
   598 
       
   599 //     static bool varFirstChar(char c) {
       
   600 //       return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
       
   601 //     }
       
   602 
       
   603 //     static bool numFirstChar(char c) {
       
   604 //       return (c >= '0' && c <= '9') || c == '.';
       
   605 //     }
       
   606 
       
   607 //     static bool varChar(char c) {
       
   608 //       return (c >= '0' && c <= '9') || 
       
   609 //         (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
       
   610 //     }
       
   611 
       
   612 
       
   613 //     void addConstraint(const LpSolverBase::Constr& constr) {
       
   614 //       if (constr.expr().size() != 1) {
       
   615 //         lp.addRow(constr);
       
   616 //       } else {
       
   617 //         Lp::Expr e = constr.expr();
       
   618 //         LpSolverBase::Col col = e.begin()->first;
       
   619 //         double coeff = e.begin()->second;
       
   620 //         double lb = LpSolverBase::NaN;
       
   621 //         double ub = LpSolverBase::NaN;
       
   622 //         if (coeff > 0) {
       
   623 //           if (constr.upperBounded()) {
       
   624 //             lb = (constr.lowerBound() - e.constComp()) / coeff;
       
   625 //           }
       
   626 //           if (constr.lowerBounded()) {
       
   627 //             ub = (constr.upperBound() - e.constComp()) / coeff;
       
   628 //           }
       
   629 //         } else if (coeff < 0) {
       
   630 //           if (constr.upperBounded()) {
       
   631 //             lb = (constr.upperBound() - e.constComp()) / coeff;
       
   632 //           }
       
   633 //           if (constr.lowerBounded()) {
       
   634 //             ub = (constr.lowerBound() - e.constComp()) / coeff;
       
   635 //           }
       
   636 //         } else {
       
   637 //           lb = -LpSolverBase::INF;
       
   638 //           ub = LpSolverBase::INF;
       
   639 //         }
       
   640 //         lp.colLowerBound(col, lb);
       
   641 //         lp.colUpperBound(col, ub);
       
   642 //       }
       
   643 //     }
       
   644     
       
   645 //   protected:
       
   646 
       
   647 //     /// \brief Writer function of the section.
       
   648 //     ///
       
   649 //     /// It writes the content of the section.
       
   650 //     virtual void write(std::ostream& is) {
       
   651 //       std::string line;
       
   652 //       std::map<std::string, LpSolverBase::Col> vars;
       
   653 //       while (getline(is, line)) {
       
   654 //         std::istringstream ls(line);
       
   655 //         std::string sense;
       
   656 //         ls >> sense;
       
   657 //         if (sense == "min" || sense == "max") {
       
   658 //           LpSolverBase::Expr expr;
       
   659 //           ls >> std::ws;
       
   660 //           writeExpression(ls, expr);
       
   661 //           lp.setObj(expr);
       
   662 //           if (sense == "min") {
       
   663 //             lp.min();
       
   664 //           } else {
       
   665 //             lp.max();
       
   666 //           }
       
   667 //         } else {
       
   668 //           ls.str(line);
       
   669 //           LpSolverBase::Constr constr;
       
   670 //           ls >> std::ws;
       
   671 //           writeConstraint(ls, constr);
       
   672 //           addConstraint(constr);
       
   673 //         }        
       
   674 //       }
       
   675 //     }
       
   676       
       
   677 //     virtual void missing() {
       
   678 //       ErrorMessage msg;
       
   679 //       msg << "Lp section not found in file: @lp " << name;
       
   680 //       throw IoParameterError(msg.message());
       
   681 //     }
       
   682 
       
   683 //   private:
       
   684 
       
   685 //     typedef std::map<std::string, LpSolverBase::Col> ColMap;
       
   686       
       
   687 //     LpSolverBase& lp;
       
   688 //     std::string name;
       
   689 //     ColMap cols;
       
   690 //   };
       
   691 
   362 }
   692 }
   363 
   693 
   364 #endif
   694 #endif