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 |