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