319 virtual void _eraseCol(int i) = 0; |
316 virtual void _eraseCol(int i) = 0; |
320 /// \e |
317 /// \e |
321 virtual void _eraseRow(int i) = 0; |
318 virtual void _eraseRow(int i) = 0; |
322 /// \e |
319 /// \e |
323 virtual void _setRowCoeffs(int i, |
320 virtual void _setRowCoeffs(int i, |
324 const std::vector<std::pair<int, _Value> >& coeffs) = 0; |
321 const std::vector<std::pair<int, Value> >& coeffs) = 0; |
325 /// \e |
322 /// \e |
326 /// This routine modifies \c coeffs only by the \c push_back method. |
323 /// This routine modifies \c coeffs only by the \c push_back method. |
327 virtual void _getRowCoeffs(int i, |
324 virtual void _getRowCoeffs(int i, |
328 std::vector<std::pair<int, _Value> >& coeffs) = 0; |
325 std::vector<std::pair<int, Value> >& coeffs) = 0; |
329 /// \e |
326 /// \e |
330 virtual void _setColCoeffs(int i, |
327 virtual void _setColCoeffs(int i, |
331 const std::vector<std::pair<int, _Value> >& coeffs) = 0; |
328 const std::vector<std::pair<int, Value> >& coeffs) = 0; |
332 /// \e |
329 /// \e |
333 /// This routine modifies \c coeffs only by the \c push_back method. |
330 /// This routine modifies \c coeffs only by the \c push_back method. |
334 virtual void _getColCoeffs(int i, |
331 virtual void _getColCoeffs(int i, |
335 std::vector<std::pair<int, _Value> >& coeffs) = 0; |
332 std::vector<std::pair<int, Value> >& coeffs) = 0; |
336 /// \e |
333 /// \e |
337 virtual void _setCoeff(int col, int row, _Value value) = 0; |
334 virtual void _setCoeff(int col, int row, Value value) = 0; |
338 /// \e |
335 /// \e |
339 virtual _Value _getCoeff(int col, int row) = 0; |
336 virtual Value _getCoeff(int col, int row) = 0; |
340 // public: |
337 // public: |
341 // /// \e |
338 // /// \e |
342 // enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED }; |
339 // enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED }; |
343 protected: |
340 protected: |
344 /// \e |
341 /// \e |
345 /// The lower bound of a variable (column) have to be given by an |
342 /// The lower bound of a variable (column) have to be given by an |
346 /// extended number of type _Value, i.e. a finite number of type |
343 /// extended number of type Value, i.e. a finite number of type |
347 /// _Value or -INF. |
344 /// Value or -INF. |
348 virtual void _setColLowerBound(int i, _Value value) = 0; |
345 virtual void _setColLowerBound(int i, Value value) = 0; |
349 /// \e |
346 /// \e |
350 /// The lower bound of a variable (column) is an |
347 /// The lower bound of a variable (column) is an |
351 /// extended number of type _Value, i.e. a finite number of type |
348 /// extended number of type Value, i.e. a finite number of type |
352 /// _Value or -INF. |
349 /// Value or -INF. |
353 virtual _Value _getColLowerBound(int i) = 0; |
350 virtual Value _getColLowerBound(int i) = 0; |
354 /// \e |
351 /// \e |
355 /// The upper bound of a variable (column) have to be given by an |
352 /// The upper bound of a variable (column) have to be given by an |
356 /// extended number of type _Value, i.e. a finite number of type |
353 /// extended number of type Value, i.e. a finite number of type |
357 /// _Value or INF. |
354 /// Value or INF. |
358 virtual void _setColUpperBound(int i, _Value value) = 0; |
355 virtual void _setColUpperBound(int i, Value value) = 0; |
359 /// \e |
356 /// \e |
360 /// The upper bound of a variable (column) is an |
357 /// The upper bound of a variable (column) is an |
361 /// extended number of type _Value, i.e. a finite number of type |
358 /// extended number of type Value, i.e. a finite number of type |
362 /// _Value or INF. |
359 /// Value or INF. |
363 virtual _Value _getColUpperBound(int i) = 0; |
360 virtual Value _getColUpperBound(int i) = 0; |
364 /// \e |
361 /// \e |
365 /// The lower bound of a linear expression (row) have to be given by an |
362 /// The lower bound of a linear expression (row) have to be given by an |
366 /// extended number of type _Value, i.e. a finite number of type |
363 /// extended number of type Value, i.e. a finite number of type |
367 /// _Value or -INF. |
364 /// Value or -INF. |
368 virtual void _setRowLowerBound(int i, _Value value) = 0; |
365 virtual void _setRowLowerBound(int i, Value value) = 0; |
369 /// \e |
366 /// \e |
370 /// The lower bound of a linear expression (row) is an |
367 /// The lower bound of a linear expression (row) is an |
371 /// extended number of type _Value, i.e. a finite number of type |
368 /// extended number of type Value, i.e. a finite number of type |
372 /// _Value or -INF. |
369 /// Value or -INF. |
373 virtual _Value _getRowLowerBound(int i) = 0; |
370 virtual Value _getRowLowerBound(int i) = 0; |
374 /// \e |
371 /// \e |
375 /// The upper bound of a linear expression (row) have to be given by an |
372 /// The upper bound of a linear expression (row) have to be given by an |
376 /// extended number of type _Value, i.e. a finite number of type |
373 /// extended number of type Value, i.e. a finite number of type |
377 /// _Value or INF. |
374 /// Value or INF. |
378 virtual void _setRowUpperBound(int i, _Value value) = 0; |
375 virtual void _setRowUpperBound(int i, Value value) = 0; |
379 /// \e |
376 /// \e |
380 /// The upper bound of a linear expression (row) is an |
377 /// The upper bound of a linear expression (row) is an |
381 /// extended number of type _Value, i.e. a finite number of type |
378 /// extended number of type Value, i.e. a finite number of type |
382 /// _Value or INF. |
379 /// Value or INF. |
383 virtual _Value _getRowUpperBound(int i) = 0; |
380 virtual Value _getRowUpperBound(int i) = 0; |
384 /// \e |
381 /// \e |
385 virtual void _setObjCoeff(int i, _Value obj_coef) = 0; |
382 virtual void _setObjCoeff(int i, Value obj_coef) = 0; |
386 /// \e |
383 /// \e |
387 virtual _Value _getObjCoeff(int i) = 0; |
384 virtual Value _getObjCoeff(int i) = 0; |
388 |
385 |
389 //SOLUTION RETRIEVING |
386 //SOLUTION RETRIEVING |
390 |
387 |
391 /// \e |
388 /// \e |
392 virtual _Value _getPrimal(int i) = 0; |
389 virtual Value _getPrimal(int i) = 0; |
393 //@} |
390 //@} |
394 |
391 |
395 /*! @name High level interface (public members) |
392 /*! @name High level interface (public members) |
396 Problem manipulating functions in the high level interface |
393 Problem manipulating functions in the high level interface |
397 */ |
394 */ |
455 if (row_iter_map[it]>rows[1]) --row_iter_map[it]; |
452 if (row_iter_map[it]>rows[1]) --row_iter_map[it]; |
456 } |
453 } |
457 int_row_map.erase(int_row_map.begin()+rows[1]); |
454 int_row_map.erase(int_row_map.begin()+rows[1]); |
458 } |
455 } |
459 /// \e |
456 /// \e |
460 void setCoeff(Col col, Row row, _Value value) { |
457 void setCoeff(Col col, Row row, Value value) { |
461 _setCoeff(col_iter_map[col], row_iter_map[row], value); |
458 _setCoeff(col_iter_map[col], row_iter_map[row], value); |
462 } |
459 } |
463 /// \e |
460 /// \e |
464 _Value getCoeff(Col col, Row row) { |
461 Value getCoeff(Col col, Row row) { |
465 return _getCoeff(col_iter_map[col], row_iter_map[row], value); |
462 return _getCoeff(col_iter_map[col], row_iter_map[row], value); |
466 } |
463 } |
467 /// \e |
464 /// \e |
468 void setColLowerBound(Col col, _Value lo) { |
465 void setColLowerBound(Col col, Value lo) { |
469 _setColLowerBound(col_iter_map[col], lo); |
466 _setColLowerBound(col_iter_map[col], lo); |
470 } |
467 } |
471 /// \e |
468 /// \e |
472 _Value getColLowerBound(Col col) { |
469 Value getColLowerBound(Col col) { |
473 return _getColLowerBound(col_iter_map[col]); |
470 return _getColLowerBound(col_iter_map[col]); |
474 } |
471 } |
475 /// \e |
472 /// \e |
476 void setColUpperBound(Col col, _Value up) { |
473 void setColUpperBound(Col col, Value up) { |
477 _setColUpperBound(col_iter_map[col], up); |
474 _setColUpperBound(col_iter_map[col], up); |
478 } |
475 } |
479 /// \e |
476 /// \e |
480 _Value getColUpperBound(Col col) { |
477 Value getColUpperBound(Col col) { |
481 return _getColUpperBound(col_iter_map[col]); |
478 return _getColUpperBound(col_iter_map[col]); |
482 } |
479 } |
483 /// \e |
480 /// \e |
484 void setRowLowerBound(Row row, _Value lo) { |
481 void setRowLowerBound(Row row, Value lo) { |
485 _setRowLowerBound(row_iter_map[row], lo); |
482 _setRowLowerBound(row_iter_map[row], lo); |
486 } |
483 } |
487 /// \e |
484 /// \e |
488 _Value getRowLowerBound(Row row) { |
485 Value getRowLowerBound(Row row) { |
489 return _getRowLowerBound(row_iter_map[row]); |
486 return _getRowLowerBound(row_iter_map[row]); |
490 } |
487 } |
491 /// \e |
488 /// \e |
492 void setRowUpperBound(Row row, _Value up) { |
489 void setRowUpperBound(Row row, Value up) { |
493 _setRowUpperBound(row_iter_map[row], up); |
490 _setRowUpperBound(row_iter_map[row], up); |
494 } |
491 } |
495 /// \e |
492 /// \e |
496 _Value getRowUpperBound(Row row) { |
493 Value getRowUpperBound(Row row) { |
497 return _getRowUpperBound(row_iter_map[row]); |
494 return _getRowUpperBound(row_iter_map[row]); |
498 } |
495 } |
499 /// \e |
496 /// \e |
500 void setObjCoeff(const Col& col, _Value obj_coef) { |
497 void setObjCoeff(const Col& col, Value obj_coef) { |
501 _setObjCoeff(col_iter_map[col], obj_coef); |
498 _setObjCoeff(col_iter_map[col], obj_coef); |
502 } |
499 } |
503 /// \e |
500 /// \e |
504 _Value getObjCoeff(const Col& col) { |
501 Value getObjCoeff(const Col& col) { |
505 return _getObjCoeff(col_iter_map[col]); |
502 return _getObjCoeff(col_iter_map[col]); |
506 } |
503 } |
507 |
504 |
508 //SOLUTION RETRIEVING FUNCTIONS |
505 //SOLUTION RETRIEVING FUNCTIONS |
509 |
506 |
510 /// \e |
507 /// \e |
511 _Value getPrimal(const Col& col) { |
508 Value getPrimal(const Col& col) { |
512 return _getPrimal(col_iter_map[col]); |
509 return _getPrimal(col_iter_map[col]); |
513 } |
510 } |
514 |
511 |
515 //@} |
512 //@} |
516 |
513 |
555 return row; |
552 return row; |
556 } |
553 } |
557 /// \e |
554 /// \e |
558 /// This routine modifies \c expr by only adding to it. |
555 /// This routine modifies \c expr by only adding to it. |
559 void getRowCoeffs(Row row, Expression& expr) { |
556 void getRowCoeffs(Row row, Expression& expr) { |
560 std::vector<std::pair<int, _Value> > row_coeffs; |
557 std::vector<std::pair<int, Value> > row_coeffs; |
561 _getRowCoeffs(row_iter_map[row], row_coeffs); |
558 _getRowCoeffs(row_iter_map[row], row_coeffs); |
562 for(typename std::vector<std::pair<int, _Value> >::const_iterator |
559 for(typename std::vector<std::pair<int, Value> >::const_iterator |
563 i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) { |
560 i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) { |
564 expr+= (*i).second*int_col_map[(*i).first]; |
561 expr+= (*i).second*int_col_map[(*i).first]; |
565 } |
562 } |
566 } |
563 } |
567 /// \e |
564 /// \e |
568 void setColCoeffs(Col col, const DualExpression& expr) { |
565 void setColCoeffs(Col col, const DualExpression& expr) { |
569 std::vector<std::pair<int, _Value> > col_coeffs; |
566 std::vector<std::pair<int, Value> > col_coeffs; |
570 for(typename DualExpression::Data::const_iterator i=expr.data.begin(); |
567 for(typename DualExpression::Data::const_iterator i=expr.data.begin(); |
571 i!=expr.data.end(); ++i) { |
568 i!=expr.data.end(); ++i) { |
572 col_coeffs.push_back(std::make_pair |
569 col_coeffs.push_back(std::make_pair |
573 (row_iter_map[(*i).first], (*i).second)); |
570 (row_iter_map[(*i).first], (*i).second)); |
574 } |
571 } |
575 _setColCoeffs(col_iter_map[col], col_coeffs); |
572 _setColCoeffs(col_iter_map[col], col_coeffs); |
576 } |
573 } |
577 /// \e |
574 /// \e |
578 /// This routine modifies \c expr by only adding to it. |
575 /// This routine modifies \c expr by only adding to it. |
579 void getColCoeffs(Col col, DualExpression& expr) { |
576 void getColCoeffs(Col col, DualExpression& expr) { |
580 std::vector<std::pair<int, _Value> > col_coeffs; |
577 std::vector<std::pair<int, Value> > col_coeffs; |
581 _getColCoeffs(col_iter_map[col], col_coeffs); |
578 _getColCoeffs(col_iter_map[col], col_coeffs); |
582 for(typename std::vector<std::pair<int, _Value> >::const_iterator |
579 for(typename std::vector<std::pair<int, Value> >::const_iterator |
583 i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) { |
580 i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) { |
584 expr+= (*i).second*int_row_map[(*i).first]; |
581 expr+= (*i).second*int_row_map[(*i).first]; |
585 } |
582 } |
586 } |
583 } |
587 /// \e |
584 /// \e |
618 /// \e |
615 /// \e |
619 virtual void _setColCont(int i) = 0; |
616 virtual void _setColCont(int i) = 0; |
620 /// \e |
617 /// \e |
621 virtual void _setColInt(int i) = 0; |
618 virtual void _setColInt(int i) = 0; |
622 /// \e |
619 /// \e |
623 virtual _Value _getMIPPrimal(int i) = 0; |
620 virtual Value _getMIPPrimal(int i) = 0; |
624 public: |
621 public: |
625 /// \e |
622 /// \e |
626 void setColCont(Col col) { |
623 void setColCont(Col col) { |
627 _setColCont(col_iter_map[col]); |
624 _setColCont(col_iter_map[col]); |
628 } |
625 } |
629 /// \e |
626 /// \e |
630 void setColInt(Col col) { |
627 void setColInt(Col col) { |
631 _setColInt(col_iter_map[col]); |
628 _setColInt(col_iter_map[col]); |
632 } |
629 } |
633 /// \e |
630 /// \e |
634 _Value getMIPPrimal(Col col) { |
631 Value getMIPPrimal(Col col) { |
635 return _getMIPPrimal(col_iter_map[col]); |
632 return _getMIPPrimal(col_iter_map[col]); |
636 } |
633 } |
637 //@} |
634 //@} |
638 }; |
635 }; |
639 |
|
640 template <typename _Value> |
|
641 const _Value LPSolverBase<_Value>::INF=std::numeric_limits<_Value>::infinity(); |
|
642 |
|
643 |
|
644 /// \brief Wrapper for GLPK solver |
|
645 /// |
|
646 /// This class implements a lemon wrapper for GLPK. |
|
647 class LPGLPK : public LPSolverBase<double> { |
|
648 public: |
|
649 typedef LPSolverBase<double> Parent; |
|
650 |
|
651 public: |
|
652 /// \e |
|
653 LPX* lp; |
|
654 |
|
655 public: |
|
656 /// \e |
|
657 LPGLPK() : Parent(), |
|
658 lp(lpx_create_prob()) { |
|
659 int_row_map.push_back(Row()); |
|
660 int_col_map.push_back(Col()); |
|
661 lpx_set_int_parm(lp, LPX_K_DUAL, 1); |
|
662 } |
|
663 /// \e |
|
664 ~LPGLPK() { |
|
665 lpx_delete_prob(lp); |
|
666 } |
|
667 |
|
668 //MATRIX INDEPEDENT MANIPULATING FUNCTIONS |
|
669 |
|
670 /// \e |
|
671 void setMinimize() { |
|
672 lpx_set_obj_dir(lp, LPX_MIN); |
|
673 } |
|
674 /// \e |
|
675 void setMaximize() { |
|
676 lpx_set_obj_dir(lp, LPX_MAX); |
|
677 } |
|
678 |
|
679 //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS |
|
680 |
|
681 protected: |
|
682 /// \e |
|
683 int _addCol() { |
|
684 int i=lpx_add_cols(lp, 1); |
|
685 _setColLowerBound(i, -INF); |
|
686 _setColUpperBound(i, INF); |
|
687 return i; |
|
688 } |
|
689 /// \e |
|
690 int _addRow() { |
|
691 int i=lpx_add_rows(lp, 1); |
|
692 return i; |
|
693 } |
|
694 /// \e |
|
695 virtual void _setRowCoeffs(int i, |
|
696 const std::vector<std::pair<int, double> >& coeffs) { |
|
697 int mem_length=1+colNum(); |
|
698 int* indices = new int[mem_length]; |
|
699 double* doubles = new double[mem_length]; |
|
700 int length=0; |
|
701 for (std::vector<std::pair<int, double> >:: |
|
702 const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) { |
|
703 ++length; |
|
704 indices[length]=it->first; |
|
705 doubles[length]=it->second; |
|
706 } |
|
707 lpx_set_mat_row(lp, i, length, indices, doubles); |
|
708 delete [] indices; |
|
709 delete [] doubles; |
|
710 } |
|
711 /// \e |
|
712 virtual void _getRowCoeffs(int i, |
|
713 std::vector<std::pair<int, double> >& coeffs) { |
|
714 int mem_length=1+colNum(); |
|
715 int* indices = new int[mem_length]; |
|
716 double* doubles = new double[mem_length]; |
|
717 int length=lpx_get_mat_row(lp, i, indices, doubles); |
|
718 for (int i=1; i<=length; ++i) { |
|
719 coeffs.push_back(std::make_pair(indices[i], doubles[i])); |
|
720 } |
|
721 delete [] indices; |
|
722 delete [] doubles; |
|
723 } |
|
724 /// \e |
|
725 virtual void _setColCoeffs(int i, |
|
726 const std::vector<std::pair<int, double> >& coeffs) { |
|
727 int mem_length=1+rowNum(); |
|
728 int* indices = new int[mem_length]; |
|
729 double* doubles = new double[mem_length]; |
|
730 int length=0; |
|
731 for (std::vector<std::pair<int, double> >:: |
|
732 const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) { |
|
733 ++length; |
|
734 indices[length]=it->first; |
|
735 doubles[length]=it->second; |
|
736 } |
|
737 lpx_set_mat_col(lp, i, length, indices, doubles); |
|
738 delete [] indices; |
|
739 delete [] doubles; |
|
740 } |
|
741 /// \e |
|
742 virtual void _getColCoeffs(int i, |
|
743 std::vector<std::pair<int, double> >& coeffs) { |
|
744 int mem_length=1+rowNum(); |
|
745 int* indices = new int[mem_length]; |
|
746 double* doubles = new double[mem_length]; |
|
747 int length=lpx_get_mat_col(lp, i, indices, doubles); |
|
748 for (int i=1; i<=length; ++i) { |
|
749 coeffs.push_back(std::make_pair(indices[i], doubles[i])); |
|
750 } |
|
751 delete [] indices; |
|
752 delete [] doubles; |
|
753 } |
|
754 /// \e |
|
755 virtual void _eraseCol(int i) { |
|
756 int cols[2]; |
|
757 cols[1]=i; |
|
758 lpx_del_cols(lp, 1, cols); |
|
759 } |
|
760 virtual void _eraseRow(int i) { |
|
761 int rows[2]; |
|
762 rows[1]=i; |
|
763 lpx_del_rows(lp, 1, rows); |
|
764 } |
|
765 void _setCoeff(int col, int row, double value) { |
|
766 /// FIXME not yet implemented |
|
767 } |
|
768 double _getCoeff(int col, int row) { |
|
769 /// FIXME not yet implemented |
|
770 return 0.0; |
|
771 } |
|
772 virtual void _setColLowerBound(int i, double lo) { |
|
773 if (lo==INF) { |
|
774 //FIXME error |
|
775 } |
|
776 int b=lpx_get_col_type(lp, i); |
|
777 double up=lpx_get_col_ub(lp, i); |
|
778 if (lo==-INF) { |
|
779 switch (b) { |
|
780 case LPX_FR: |
|
781 case LPX_LO: |
|
782 lpx_set_col_bnds(lp, i, LPX_FR, lo, up); |
|
783 break; |
|
784 case LPX_UP: |
|
785 break; |
|
786 case LPX_DB: |
|
787 case LPX_FX: |
|
788 lpx_set_col_bnds(lp, i, LPX_UP, lo, up); |
|
789 break; |
|
790 default: ; |
|
791 //FIXME error |
|
792 } |
|
793 } else { |
|
794 switch (b) { |
|
795 case LPX_FR: |
|
796 case LPX_LO: |
|
797 lpx_set_col_bnds(lp, i, LPX_LO, lo, up); |
|
798 break; |
|
799 case LPX_UP: |
|
800 case LPX_DB: |
|
801 case LPX_FX: |
|
802 if (lo==up) |
|
803 lpx_set_col_bnds(lp, i, LPX_FX, lo, up); |
|
804 else |
|
805 lpx_set_col_bnds(lp, i, LPX_DB, lo, up); |
|
806 break; |
|
807 default: ; |
|
808 //FIXME error |
|
809 } |
|
810 } |
|
811 } |
|
812 virtual double _getColLowerBound(int i) { |
|
813 int b=lpx_get_col_type(lp, i); |
|
814 switch (b) { |
|
815 case LPX_FR: |
|
816 return -INF; |
|
817 case LPX_LO: |
|
818 return lpx_get_col_lb(lp, i); |
|
819 case LPX_UP: |
|
820 return -INF; |
|
821 case LPX_DB: |
|
822 case LPX_FX: |
|
823 return lpx_get_col_lb(lp, i); |
|
824 default: ; |
|
825 //FIXME error |
|
826 return 0.0; |
|
827 } |
|
828 } |
|
829 virtual void _setColUpperBound(int i, double up) { |
|
830 if (up==-INF) { |
|
831 //FIXME error |
|
832 } |
|
833 int b=lpx_get_col_type(lp, i); |
|
834 double lo=lpx_get_col_lb(lp, i); |
|
835 if (up==INF) { |
|
836 switch (b) { |
|
837 case LPX_FR: |
|
838 case LPX_LO: |
|
839 break; |
|
840 case LPX_UP: |
|
841 lpx_set_col_bnds(lp, i, LPX_FR, lo, up); |
|
842 break; |
|
843 case LPX_DB: |
|
844 case LPX_FX: |
|
845 lpx_set_col_bnds(lp, i, LPX_LO, lo, up); |
|
846 break; |
|
847 default: ; |
|
848 //FIXME error |
|
849 } |
|
850 } else { |
|
851 switch (b) { |
|
852 case LPX_FR: |
|
853 lpx_set_col_bnds(lp, i, LPX_UP, lo, up); |
|
854 case LPX_LO: |
|
855 if (lo==up) |
|
856 lpx_set_col_bnds(lp, i, LPX_FX, lo, up); |
|
857 else |
|
858 lpx_set_col_bnds(lp, i, LPX_DB, lo, up); |
|
859 break; |
|
860 case LPX_UP: |
|
861 lpx_set_col_bnds(lp, i, LPX_UP, lo, up); |
|
862 break; |
|
863 case LPX_DB: |
|
864 case LPX_FX: |
|
865 if (lo==up) |
|
866 lpx_set_col_bnds(lp, i, LPX_FX, lo, up); |
|
867 else |
|
868 lpx_set_col_bnds(lp, i, LPX_DB, lo, up); |
|
869 break; |
|
870 default: ; |
|
871 //FIXME error |
|
872 } |
|
873 } |
|
874 } |
|
875 virtual double _getColUpperBound(int i) { |
|
876 int b=lpx_get_col_type(lp, i); |
|
877 switch (b) { |
|
878 case LPX_FR: |
|
879 case LPX_LO: |
|
880 return INF; |
|
881 case LPX_UP: |
|
882 case LPX_DB: |
|
883 case LPX_FX: |
|
884 return lpx_get_col_ub(lp, i); |
|
885 default: ; |
|
886 //FIXME error |
|
887 return 0.0; |
|
888 } |
|
889 } |
|
890 virtual void _setRowLowerBound(int i, double lo) { |
|
891 if (lo==INF) { |
|
892 //FIXME error |
|
893 } |
|
894 int b=lpx_get_row_type(lp, i); |
|
895 double up=lpx_get_row_ub(lp, i); |
|
896 if (lo==-INF) { |
|
897 switch (b) { |
|
898 case LPX_FR: |
|
899 case LPX_LO: |
|
900 lpx_set_row_bnds(lp, i, LPX_FR, lo, up); |
|
901 break; |
|
902 case LPX_UP: |
|
903 break; |
|
904 case LPX_DB: |
|
905 case LPX_FX: |
|
906 lpx_set_row_bnds(lp, i, LPX_UP, lo, up); |
|
907 break; |
|
908 default: ; |
|
909 //FIXME error |
|
910 } |
|
911 } else { |
|
912 switch (b) { |
|
913 case LPX_FR: |
|
914 case LPX_LO: |
|
915 lpx_set_row_bnds(lp, i, LPX_LO, lo, up); |
|
916 break; |
|
917 case LPX_UP: |
|
918 case LPX_DB: |
|
919 case LPX_FX: |
|
920 if (lo==up) |
|
921 lpx_set_row_bnds(lp, i, LPX_FX, lo, up); |
|
922 else |
|
923 lpx_set_row_bnds(lp, i, LPX_DB, lo, up); |
|
924 break; |
|
925 default: ; |
|
926 //FIXME error |
|
927 } |
|
928 } |
|
929 } |
|
930 virtual double _getRowLowerBound(int i) { |
|
931 int b=lpx_get_row_type(lp, i); |
|
932 switch (b) { |
|
933 case LPX_FR: |
|
934 return -INF; |
|
935 case LPX_LO: |
|
936 return lpx_get_row_lb(lp, i); |
|
937 case LPX_UP: |
|
938 return -INF; |
|
939 case LPX_DB: |
|
940 case LPX_FX: |
|
941 return lpx_get_row_lb(lp, i); |
|
942 default: ; |
|
943 //FIXME error |
|
944 return 0.0; |
|
945 } |
|
946 } |
|
947 virtual void _setRowUpperBound(int i, double up) { |
|
948 if (up==-INF) { |
|
949 //FIXME error |
|
950 } |
|
951 int b=lpx_get_row_type(lp, i); |
|
952 double lo=lpx_get_row_lb(lp, i); |
|
953 if (up==INF) { |
|
954 switch (b) { |
|
955 case LPX_FR: |
|
956 case LPX_LO: |
|
957 break; |
|
958 case LPX_UP: |
|
959 lpx_set_row_bnds(lp, i, LPX_FR, lo, up); |
|
960 break; |
|
961 case LPX_DB: |
|
962 case LPX_FX: |
|
963 lpx_set_row_bnds(lp, i, LPX_LO, lo, up); |
|
964 break; |
|
965 default: ; |
|
966 //FIXME error |
|
967 } |
|
968 } else { |
|
969 switch (b) { |
|
970 case LPX_FR: |
|
971 lpx_set_row_bnds(lp, i, LPX_UP, lo, up); |
|
972 case LPX_LO: |
|
973 if (lo==up) |
|
974 lpx_set_row_bnds(lp, i, LPX_FX, lo, up); |
|
975 else |
|
976 lpx_set_row_bnds(lp, i, LPX_DB, lo, up); |
|
977 break; |
|
978 case LPX_UP: |
|
979 lpx_set_row_bnds(lp, i, LPX_UP, lo, up); |
|
980 break; |
|
981 case LPX_DB: |
|
982 case LPX_FX: |
|
983 if (lo==up) |
|
984 lpx_set_row_bnds(lp, i, LPX_FX, lo, up); |
|
985 else |
|
986 lpx_set_row_bnds(lp, i, LPX_DB, lo, up); |
|
987 break; |
|
988 default: ; |
|
989 //FIXME error |
|
990 } |
|
991 } |
|
992 } |
|
993 virtual double _getRowUpperBound(int i) { |
|
994 int b=lpx_get_row_type(lp, i); |
|
995 switch (b) { |
|
996 case LPX_FR: |
|
997 case LPX_LO: |
|
998 return INF; |
|
999 case LPX_UP: |
|
1000 case LPX_DB: |
|
1001 case LPX_FX: |
|
1002 return lpx_get_row_ub(lp, i); |
|
1003 default: ; |
|
1004 //FIXME error |
|
1005 return 0.0; |
|
1006 } |
|
1007 } |
|
1008 /// \e |
|
1009 virtual double _getObjCoeff(int i) { |
|
1010 return lpx_get_obj_coef(lp, i); |
|
1011 } |
|
1012 /// \e |
|
1013 virtual void _setObjCoeff(int i, double obj_coef) { |
|
1014 lpx_set_obj_coef(lp, i, obj_coef); |
|
1015 } |
|
1016 public: |
|
1017 /// \e |
|
1018 void solveSimplex() { lpx_simplex(lp); } |
|
1019 /// \e |
|
1020 void solvePrimalSimplex() { lpx_simplex(lp); } |
|
1021 /// \e |
|
1022 void solveDualSimplex() { lpx_simplex(lp); } |
|
1023 protected: |
|
1024 virtual double _getPrimal(int i) { |
|
1025 return lpx_get_col_prim(lp, i); |
|
1026 } |
|
1027 public: |
|
1028 /// \e |
|
1029 double getObjVal() { return lpx_get_obj_val(lp); } |
|
1030 /// \e |
|
1031 int rowNum() const { return lpx_get_num_rows(lp); } |
|
1032 /// \e |
|
1033 int colNum() const { return lpx_get_num_cols(lp); } |
|
1034 /// \e |
|
1035 int warmUp() { return lpx_warm_up(lp); } |
|
1036 /// \e |
|
1037 void printWarmUpStatus(int i) { |
|
1038 switch (i) { |
|
1039 case LPX_E_OK: cout << "LPX_E_OK" << endl; break; |
|
1040 case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break; |
|
1041 case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break; |
|
1042 case LPX_E_SING: cout << "LPX_E_SING" << endl; break; |
|
1043 } |
|
1044 } |
|
1045 /// \e |
|
1046 int getPrimalStatus() { return lpx_get_prim_stat(lp); } |
|
1047 /// \e |
|
1048 void printPrimalStatus(int i) { |
|
1049 switch (i) { |
|
1050 case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break; |
|
1051 case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break; |
|
1052 case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break; |
|
1053 case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break; |
|
1054 } |
|
1055 } |
|
1056 /// \e |
|
1057 int getDualStatus() { return lpx_get_dual_stat(lp); } |
|
1058 /// \e |
|
1059 void printDualStatus(int i) { |
|
1060 switch (i) { |
|
1061 case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break; |
|
1062 case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break; |
|
1063 case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break; |
|
1064 case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break; |
|
1065 } |
|
1066 } |
|
1067 /// Returns the status of the slack variable assigned to row \c row. |
|
1068 int getRowStat(const Row& row) { |
|
1069 return lpx_get_row_stat(lp, row_iter_map[row]); |
|
1070 } |
|
1071 /// \e |
|
1072 void printRowStatus(int i) { |
|
1073 switch (i) { |
|
1074 case LPX_BS: cout << "LPX_BS" << endl; break; |
|
1075 case LPX_NL: cout << "LPX_NL" << endl; break; |
|
1076 case LPX_NU: cout << "LPX_NU" << endl; break; |
|
1077 case LPX_NF: cout << "LPX_NF" << endl; break; |
|
1078 case LPX_NS: cout << "LPX_NS" << endl; break; |
|
1079 } |
|
1080 } |
|
1081 /// Returns the status of the variable assigned to column \c col. |
|
1082 int getColStat(const Col& col) { |
|
1083 return lpx_get_col_stat(lp, col_iter_map[col]); |
|
1084 } |
|
1085 /// \e |
|
1086 void printColStatus(int i) { |
|
1087 switch (i) { |
|
1088 case LPX_BS: cout << "LPX_BS" << endl; break; |
|
1089 case LPX_NL: cout << "LPX_NL" << endl; break; |
|
1090 case LPX_NU: cout << "LPX_NU" << endl; break; |
|
1091 case LPX_NF: cout << "LPX_NF" << endl; break; |
|
1092 case LPX_NS: cout << "LPX_NS" << endl; break; |
|
1093 } |
|
1094 } |
|
1095 |
|
1096 // MIP |
|
1097 /// \e |
|
1098 void solveBandB() { lpx_integer(lp); } |
|
1099 /// \e |
|
1100 void setLP() { lpx_set_class(lp, LPX_LP); } |
|
1101 /// \e |
|
1102 void setMIP() { lpx_set_class(lp, LPX_MIP); } |
|
1103 protected: |
|
1104 /// \e |
|
1105 void _setColCont(int i) { lpx_set_col_kind(lp, i, LPX_CV); } |
|
1106 /// \e |
|
1107 void _setColInt(int i) { lpx_set_col_kind(lp, i, LPX_IV); } |
|
1108 /// \e |
|
1109 double _getMIPPrimal(int i) { return lpx_mip_col_val(lp, i); } |
|
1110 }; |
|
1111 |
|
1112 /// @} |
|
1113 |
636 |
1114 } //namespace lemon |
637 } //namespace lemon |
1115 |
638 |
1116 #endif //LEMON_LP_SOLVER_BASE_H |
639 #endif //LEMON_LP_SOLVER_BASE_H |