lemon/lp_utils.h
changeset 2363 2aabce558574
parent 2316 c0fae4bbaa5c
child 2364 3a5e67bd42d2
     1.1 --- a/lemon/lp_utils.h	Thu Feb 15 13:06:23 2007 +0000
     1.2 +++ b/lemon/lp_utils.h	Thu Feb 15 14:22:08 2007 +0000
     1.3 @@ -22,6 +22,7 @@
     1.4  #include <lemon/lp_base.h>
     1.5  
     1.6  #include <lemon/lemon_reader.h>
     1.7 +#include <lemon/lemon_writer.h>
     1.8  
     1.9  namespace lemon {
    1.10  
    1.11 @@ -319,7 +320,6 @@
    1.12      /// It reads the content of the section.
    1.13      virtual void read(std::istream& is) {
    1.14        std::string line;
    1.15 -      std::map<std::string, LpSolverBase::Col> vars;
    1.16        while (getline(is, line)) {
    1.17          std::istringstream ls(line);
    1.18          std::string sense;
    1.19 @@ -359,6 +359,336 @@
    1.20      ColMap cols;
    1.21    };
    1.22  
    1.23 +
    1.24 +//   class LpWriter : public LemonWriter::SectionWriter {
    1.25 +//     typedef LemonWriter::SectionWriter Parent;
    1.26 +//   public:
    1.27 +
    1.28 +
    1.29 +//     /// \brief Constructor.
    1.30 +//     ///
    1.31 +//     /// Constructor for LpWriter. It creates the LpWriter and attach
    1.32 +//     /// it into the given LemonWriter. The lp writer will add
    1.33 +//     /// variables, constraints and objective function to the
    1.34 +//     /// given lp solver.
    1.35 +//     LpWriter(LemonWriter& _writer, LpSolverBase& _lp, 
    1.36 +//              const std::string& _name = std::string())
    1.37 +//       : Parent(_writer), lp(_lp), name(_name) {} 
    1.38 +
    1.39 +
    1.40 +//     /// \brief Destructor.
    1.41 +//     ///
    1.42 +//     /// Destructor for NodeSetWriter.
    1.43 +//     virtual ~LpWriter() {}
    1.44 +
    1.45 +//   private:
    1.46 +//     LpWriter(const LpWriter&);
    1.47 +//     void operator=(const LpWriter&);
    1.48 +  
    1.49 +//   protected:
    1.50 +
    1.51 +//     /// \brief Gives back true when the SectionWriter can process 
    1.52 +//     /// the section with the given header line.
    1.53 +//     ///
    1.54 +//     /// It gives back the header line of the \c \@lp section.
    1.55 +//     virtual std::string header() {
    1.56 +//       std::ostringstream ls(line);
    1.57 +//       ls << "@lp " << name;
    1.58 +//       return ls.str();
    1.59 +//     }
    1.60 +
    1.61 +//   private:
    1.62 +
    1.63 +//     std::ostream& writeConstraint(std::ostream& is, LpSolverBase::Constr& c) {
    1.64 +//       char x;
    1.65 +
    1.66 +      
    1.67 +//       LpSolverBase::Expr e1, e2;
    1.68 +//       Relation op1;
    1.69 +//       is >> std::ws;
    1.70 +//       writexpression(is, e1);
    1.71 +//       is >> std::ws;
    1.72 +//       writeRelation(is, op1);
    1.73 +//       is >> std::ws;
    1.74 +//       writexpression(is, e2);
    1.75 +//       if (!is.get(x)) {
    1.76 +//         if (op1 == LE) {
    1.77 +//           c = e1 <= e2;
    1.78 +//         } else if (op1 == GE) {
    1.79 +//           c = e1 >= e2;
    1.80 +//         } else {
    1.81 +//           c = e1 == e2;
    1.82 +//         }
    1.83 +//       } else {
    1.84 +//         is.putback(x);
    1.85 +//         LpSolverBase::Expr e3;
    1.86 +//         Relation op2;
    1.87 +//         writeRelation(is, op2);
    1.88 +//         is >> std::ws;
    1.89 +//         writexpression(is, e3);
    1.90 +//         if (!e1.empty() || !e3.empty()) {
    1.91 +//           throw DataFormatError("Wrong range format");
    1.92 +//         }
    1.93 +//         if (op2 != op1 || op1 == EQ) {
    1.94 +//           throw DataFormatError("Wrong range format");
    1.95 +//         }
    1.96 +//         if (op1 == LE) {
    1.97 +//           c = e1.constComp() <= e2 <= e3.constComp();
    1.98 +//         } else {
    1.99 +//           c = e1.constComp() >= e2 >= e3.constComp();
   1.100 +//         }
   1.101 +//       }
   1.102 +//     }
   1.103 +
   1.104 +//     std::ostream& writexpression(std::ostream& is, LpSolverBase::Expr& e) {
   1.105 +//       LpSolverBase::Col c;
   1.106 +//       double d;
   1.107 +//       char x;
   1.108 +//       writelement(is, c, d);
   1.109 +//       if (c != INVALID) {
   1.110 +//         e += d * c;
   1.111 +//       } else {
   1.112 +//         e += d;
   1.113 +//       }
   1.114 +//       is >> std::ws;
   1.115 +//       while (is.get(x) && (x == '+' || x == '-')) {
   1.116 +//         is >> std::ws;
   1.117 +//         writelement(is, c, d);
   1.118 +//         if (c != INVALID) {
   1.119 +//           e += (x == '+' ? d : -d) * c;
   1.120 +//         } else {
   1.121 +//           e += (x == '+' ? d : -d);
   1.122 +//         }
   1.123 +//         is >> std::ws;
   1.124 +//       }
   1.125 +//       if (!is) {
   1.126 +//         is.clear();
   1.127 +//       } else {
   1.128 +//         is.putback(x);
   1.129 +//       }
   1.130 +//       return is;
   1.131 +//     }
   1.132 +
   1.133 +//     std::ostream& writelement(std::ostream& is, 
   1.134 +//                               LpSolverBase::Col& c, double& d) { 
   1.135 +//       d = 1.0;
   1.136 +//       c = INVALID;
   1.137 +//       char x, y;
   1.138 +//       if (!is.get(x)) throw DataFormatError("Cannot find lp element");
   1.139 +//       if (x == '+' || x == '-') {
   1.140 +//         is >> std::ws;
   1.141 +//         d *= x == '-' ? -1 : 1;
   1.142 +//         while (is.get(x) && (x == '+' || x == '-')) {
   1.143 +//           d *= x == '-' ? -1 : 1;
   1.144 +//           is >> std::ws;
   1.145 +//         }
   1.146 +//         if (!is) throw DataFormatError("Cannot find lp element");
   1.147 +//       }
   1.148 +//       if (numFirstChar(x)) {
   1.149 +//         is.putback(x);
   1.150 +//         double e;
   1.151 +//         writeNum(is, e);
   1.152 +//         d *= e;
   1.153 +//       } else if (varFirstChar(x)) {
   1.154 +//         is.putback(x);
   1.155 +//         LpSolverBase::Col f;
   1.156 +//         writeCol(is, f);
   1.157 +//         c = f;
   1.158 +//       } else {
   1.159 +//         throw DataFormatError("Invalid expression format");          
   1.160 +//       }
   1.161 +//       is >> std::ws;
   1.162 +//       while (is.get(y) && (y == '*' || y == '/')) {
   1.163 +//         is >> std::ws;
   1.164 +//         if (!is.get(x)) throw DataFormatError("Cannot find lp element");
   1.165 +//         if (x == '+' || x == '-') {
   1.166 +//           is >> std::ws;
   1.167 +//           d *= x == '-' ? -1 : 1;
   1.168 +//           while (is.get(x) && (x == '+' || x == '-')) {
   1.169 +//             d *= x == '-' ? -1 : 1;
   1.170 +//             is >> std::ws;
   1.171 +//           }
   1.172 +//           if (!is) throw DataFormatError("Cannot find lp element");
   1.173 +//         }
   1.174 +//         if (numFirstChar(x)) {
   1.175 +//           is.putback(x);
   1.176 +//           double e;
   1.177 +//           writeNum(is, e);
   1.178 +//           if (y == '*') {
   1.179 +//             d *= e;
   1.180 +//           } else {
   1.181 +//             d /= e;
   1.182 +//           }
   1.183 +//         } else if (varFirstChar(x)) {
   1.184 +//           is.putback(x);
   1.185 +//           LpSolverBase::Col f;
   1.186 +//           writeCol(is, f);
   1.187 +//           if (y == '*') {
   1.188 +//             if (c == INVALID) {
   1.189 +//               c = f;
   1.190 +//             } else {
   1.191 +//               throw DataFormatError("Quadratic element in expression");
   1.192 +//             }
   1.193 +//           } else {
   1.194 +//             throw DataFormatError("Division by variable");
   1.195 +//           }
   1.196 +//         } else {
   1.197 +//           throw DataFormatError("Invalid expression format");          
   1.198 +//         }
   1.199 +//         is >> std::ws;
   1.200 +//       }
   1.201 +//       if (!is) {
   1.202 +//         is.clear();
   1.203 +//       } else {
   1.204 +//         is.putback(y);
   1.205 +//       }
   1.206 +//       return is;
   1.207 +//     }
   1.208 +
   1.209 +//     std::ostream& writeCol(std::ostream& is, LpSolverBase::Col& c) {
   1.210 +//       char x;
   1.211 +//       std::string var;
   1.212 +//       while (is.get(x) && varChar(x)) {
   1.213 +//         var += x;
   1.214 +//       }
   1.215 +//       if (!is) {
   1.216 +//         is.clear();
   1.217 +//       } else {
   1.218 +//         is.putback(x);
   1.219 +//       }
   1.220 +//       ColMap::const_iterator it = cols.find(var);
   1.221 +//       if (cols.find(var) != cols.end()) {
   1.222 +//         c = it->second;
   1.223 +//       } else {
   1.224 +//         c = lp.addCol();
   1.225 +//         cols.insert(std::make_pair(var, c));
   1.226 +//         lp.colName(c, var);
   1.227 +//       }
   1.228 +//       return is;
   1.229 +//     }
   1.230 +
   1.231 +//     std::ostream& writeNum(std::ostream& is, double& d) {
   1.232 +//       is >> d;
   1.233 +//       if (!is) throw DataFormatError("Wrong number format");
   1.234 +//       return is;
   1.235 +//     }
   1.236 +
   1.237 +//     std::ostream& writeRelation(std::ostream& is, Relation& op) {
   1.238 +//       char x, y;
   1.239 +//       if (!is.get(x) || !(x == '<' || x == '=' || x == '>')) {
   1.240 +//         throw DataFormatError("Wrong relation operator");
   1.241 +//       }
   1.242 +//       if (!is.get(y) || y != '=') {
   1.243 +//         throw DataFormatError("Wrong relation operator");
   1.244 +//       }
   1.245 +//       switch (x) {
   1.246 +//       case '<': op = LE; 
   1.247 +//         break;
   1.248 +//       case '=': op = EQ; 
   1.249 +//         break;
   1.250 +//       case '>': op = GE; 
   1.251 +//         break;
   1.252 +//       }
   1.253 +//       return is;
   1.254 +//     }
   1.255 +
   1.256 +//     static bool relationFirstChar(char c) {
   1.257 +//       return c == '<' || c == '=' || c == '>';
   1.258 +//     }
   1.259 +
   1.260 +//     static bool varFirstChar(char c) {
   1.261 +//       return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
   1.262 +//     }
   1.263 +
   1.264 +//     static bool numFirstChar(char c) {
   1.265 +//       return (c >= '0' && c <= '9') || c == '.';
   1.266 +//     }
   1.267 +
   1.268 +//     static bool varChar(char c) {
   1.269 +//       return (c >= '0' && c <= '9') || 
   1.270 +//         (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
   1.271 +//     }
   1.272 +
   1.273 +
   1.274 +//     void addConstraint(const LpSolverBase::Constr& constr) {
   1.275 +//       if (constr.expr().size() != 1) {
   1.276 +//         lp.addRow(constr);
   1.277 +//       } else {
   1.278 +//         Lp::Expr e = constr.expr();
   1.279 +//         LpSolverBase::Col col = e.begin()->first;
   1.280 +//         double coeff = e.begin()->second;
   1.281 +//         double lb = LpSolverBase::NaN;
   1.282 +//         double ub = LpSolverBase::NaN;
   1.283 +//         if (coeff > 0) {
   1.284 +//           if (constr.upperBounded()) {
   1.285 +//             lb = (constr.lowerBound() - e.constComp()) / coeff;
   1.286 +//           }
   1.287 +//           if (constr.lowerBounded()) {
   1.288 +//             ub = (constr.upperBound() - e.constComp()) / coeff;
   1.289 +//           }
   1.290 +//         } else if (coeff < 0) {
   1.291 +//           if (constr.upperBounded()) {
   1.292 +//             lb = (constr.upperBound() - e.constComp()) / coeff;
   1.293 +//           }
   1.294 +//           if (constr.lowerBounded()) {
   1.295 +//             ub = (constr.lowerBound() - e.constComp()) / coeff;
   1.296 +//           }
   1.297 +//         } else {
   1.298 +//           lb = -LpSolverBase::INF;
   1.299 +//           ub = LpSolverBase::INF;
   1.300 +//         }
   1.301 +//         lp.colLowerBound(col, lb);
   1.302 +//         lp.colUpperBound(col, ub);
   1.303 +//       }
   1.304 +//     }
   1.305 +    
   1.306 +//   protected:
   1.307 +
   1.308 +//     /// \brief Writer function of the section.
   1.309 +//     ///
   1.310 +//     /// It writes the content of the section.
   1.311 +//     virtual void write(std::ostream& is) {
   1.312 +//       std::string line;
   1.313 +//       std::map<std::string, LpSolverBase::Col> vars;
   1.314 +//       while (getline(is, line)) {
   1.315 +//         std::istringstream ls(line);
   1.316 +//         std::string sense;
   1.317 +//         ls >> sense;
   1.318 +//         if (sense == "min" || sense == "max") {
   1.319 +//           LpSolverBase::Expr expr;
   1.320 +//           ls >> std::ws;
   1.321 +//           writeExpression(ls, expr);
   1.322 +//           lp.setObj(expr);
   1.323 +//           if (sense == "min") {
   1.324 +//             lp.min();
   1.325 +//           } else {
   1.326 +//             lp.max();
   1.327 +//           }
   1.328 +//         } else {
   1.329 +//           ls.str(line);
   1.330 +//           LpSolverBase::Constr constr;
   1.331 +//           ls >> std::ws;
   1.332 +//           writeConstraint(ls, constr);
   1.333 +//           addConstraint(constr);
   1.334 +//         }        
   1.335 +//       }
   1.336 +//     }
   1.337 +      
   1.338 +//     virtual void missing() {
   1.339 +//       ErrorMessage msg;
   1.340 +//       msg << "Lp section not found in file: @lp " << name;
   1.341 +//       throw IoParameterError(msg.message());
   1.342 +//     }
   1.343 +
   1.344 +//   private:
   1.345 +
   1.346 +//     typedef std::map<std::string, LpSolverBase::Col> ColMap;
   1.347 +      
   1.348 +//     LpSolverBase& lp;
   1.349 +//     std::string name;
   1.350 +//     ColMap cols;
   1.351 +//   };
   1.352 +
   1.353  }
   1.354  
   1.355  #endif