00001 /* 00002 * Copyright 2007 Martin von Gagern 00003 * 00004 * 00005 * This file is part of bande. 00006 * 00007 * bande is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 3 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * bande is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 00022 /** 00023 * @file 00024 * Interface of class bande::LinearProgram. 00025 */ 00026 00027 namespace bande { 00028 00029 /** 00030 * Encapsulation of a linear program. 00031 * 00032 * In the current implementation, this class encapsulates an LP 00033 * solver through the OsiSolverInterface. It extends that interface 00034 * by methods to access the row and column names and by registering 00035 * modifications with an UndoManager. 00036 */ 00037 class LinearProgram { 00038 00039 public: 00040 LinearProgram(); 00041 virtual ~LinearProgram(); 00042 00043 void readMps(const char* fileName); 00044 void randomizeObjective(); 00045 void setColLower(UndoManager& um, int col, double val); 00046 void setColUpper(UndoManager& um, int col, double val); 00047 bool solve(); 00048 void dumpSolution(std::ostream& out = std::cerr) const; 00049 00050 /** 00051 * Get the number of rows. 00052 * Each row represents zero to two inequalities, depending on the 00053 * row bounds. 00054 * @return the number of rows in the problem. 00055 */ 00056 int getNumRows() const { return rows; } 00057 00058 /** 00059 * Get the number of columns. 00060 * Each column corresponds to one variable of the solution. 00061 * @return the number of columns in the problem. 00062 */ 00063 int getNumCols() const { return cols; } 00064 00065 /** 00066 * Get one variable of the solution. 00067 * @param index the index of the variable. 00068 * @return the value of that variable in the current solution. 00069 */ 00070 double getColSolution(int index) const { return solution[index]; } 00071 00072 /** 00073 * Get the current lower bound of a column. 00074 * @param col the index of the column. 00075 * @return the current lower bound of that column. 00076 */ 00077 double getColLower(int col) const { return solver->getColLower()[col]; } 00078 00079 /** 00080 * Get the current upper bound of a column. 00081 * @param col the index of the column. 00082 * @return the current upper bound of that column. 00083 */ 00084 double getColUpper(int col) const { return solver->getColUpper()[col]; } 00085 00086 /** 00087 * Get the current lower bound of a row. 00088 * @param row the intex of the row. 00089 * @return the current lower bound of that row. 00090 */ 00091 double getRowLower(int row) const { return solver->getRowLower()[row]; } 00092 00093 /** 00094 * Get the current upper bound of a row. 00095 * @param row the index of the row. 00096 * @return the current upper bound of that row. 00097 */ 00098 double getRowUpper(int row) const { return solver->getRowUpper()[row]; } 00099 00100 /** 00101 * Get the name of a column. 00102 * This is also the name of the associated variable. 00103 * @param col the index of the column. 00104 * @return the name of that column. 00105 */ 00106 std::string getColName(int col) const { return colNames[col]; } 00107 00108 /** 00109 * Get the name of a row. 00110 * @param row the index of the row. 00111 * @return the name of that row. 00112 */ 00113 std::string getRowName(int row) const { return rowNames[row]; } 00114 00115 /** 00116 * Access to the wrapped solver interface. 00117 * 00118 * It is suggested that the returned object be used for read-only 00119 * access, although this is not strictly required, as many methods 00120 * of this wrapper simply call corresponding methods of the 00121 * wrapped interface and thus will reflect changes. Notable 00122 * Exceptions to this rules are the size of the matrix or the 00123 * vector of solutions. 00124 * 00125 * The returned pointer is the one used by this class, so it must 00126 * not be deleted by the caller of this method. 00127 * 00128 * @return a pointer to the solver interface wrapped by 00129 * this object. 00130 */ 00131 OsiSolverInterface* getSolver() { return solver; } 00132 00133 protected: 00134 00135 /** 00136 * The wrapped solver interface. 00137 */ 00138 OsiSolverInterface* solver; 00139 00140 /** 00141 * Number of rows. 00142 */ 00143 int rows; 00144 00145 /** 00146 * Number of columns. 00147 */ 00148 int cols; 00149 00150 /** 00151 * Column names. 00152 */ 00153 std::vector<std::string> colNames; 00154 00155 /** 00156 * Row names. 00157 */ 00158 std::vector<std::string> rowNames; 00159 00160 /** 00161 * Flag indicating a valid solution. 00162 */ 00163 bool hasSolution; 00164 00165 /** 00166 * Solution values. 00167 */ 00168 const double *solution; 00169 }; 00170 00171 00172 /** 00173 * Undo information for a column bound change. 00174 * This template is parametrized by a pointer to a method of 00175 * OsiSolverInterface that will accept a column index and a double 00176 * value. When instantiating this template, this parameter should be 00177 * the function to be used to undo the associated modification. 00178 * 00179 * @param f a pointer to member to the function used to undo the 00180 * change associated with this object. 00181 */ 00182 template<void (OsiSolverInterface::*f)(int, double)> 00183 class UndoColAction : public UndoBase { 00184 public: 00185 00186 /** 00187 * Constructs an undo information set. 00188 * @param solver the solver object that will be modified. 00189 * @param col the column index of the column to be modified. 00190 * @param val the old value of the property, to be restired when 00191 * undoing the modification. 00192 */ 00193 UndoColAction(OsiSolverInterface* solver, int col, double val) 00194 : solver(solver), col(col), val(val) { } 00195 00196 /** 00197 * Undo the operation as recorded. 00198 * This calls the method @e f on @e solver with the arguments 00199 * @e col and @e val, as they were supplied to the constructor. 00200 */ 00201 void undo() { (solver->*f)(col, val); } 00202 00203 protected: 00204 00205 /** 00206 * The solver object that was be modified. 00207 */ 00208 OsiSolverInterface* solver; 00209 00210 /** 00211 * The index of the column that was modified. 00212 */ 00213 int col; 00214 00215 /** 00216 * The old value that shall be restored. 00217 */ 00218 double val; 00219 00220 }; 00221 00222 }
1.6.0