lpsolver.h
Go to the documentation of this file.
00001 /*************************************************************************** 00002 file : $URL: https://frepple.svn.sourceforge.net/svnroot/frepple/tags/0.9.1/modules/lp_solver/lpsolver.h $ 00003 version : $LastChangedRevision: 1656 $ $LastChangedBy: jdetaeye $ 00004 date : $LastChangedDate: 2012-03-27 19:05:34 +0200 (Tue, 27 Mar 2012) $ 00005 ***************************************************************************/ 00006 00007 /*************************************************************************** 00008 * * 00009 * Copyright (C) 2007 by Johan De Taeye, frePPLe bvba * 00010 * * 00011 * This library is free software; you can redistribute it and/or modify it * 00012 * under the terms of the GNU Lesser General Public License as published * 00013 * by the Free Software Foundation; either version 2.1 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * 00019 * General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * 00024 * USA * 00025 * * 00026 ***************************************************************************/ 00027 00028 /** @file lpsolver.h 00029 * @brief Header file for the module lp_solver. 00030 * 00031 * @namespace module_lp_solver 00032 * @brief A solver module based on a linear programming algorithm. 00033 * 00034 * The solver is intended primarly for prototyping purposes. Cleaner and 00035 * more performant alternatives are recommended for real production use. 00036 * 00037 * The module uses the "Gnu Linear Programming Kit" library (aka GLPK) to 00038 * solve the LP model.<br> 00039 * The solver works as follows: 00040 * - The solver expects a <b>model file</b> and a <b>data file</b> as input.<br> 00041 * The model file represents the mathematical representation of the 00042 * problem to solve.<br> 00043 * The data file holds the data to be loaded into the problem. If no 00044 * data file is specified, the data section in the model file is used 00045 * instead.<br> 00046 * The user is responsible for creating these files. See the unit test 00047 * lp_solver1 for an example. 00048 * - The solver solves for a number of objectives in sequence.<br> 00049 * After solving an objective's optimal value, the solver freezes the 00050 * value as a constraint and start for the next objective. Subsequent 00051 * objectives can thus never yield a solution that is suboptimal for the 00052 * previous objectives. 00053 * - After solving for all objectives the solution is written to a solution 00054 * file.<br> 00055 * The user is responsible for all processing of this solution file. 00056 * 00057 * The XML schema extension enabled by this module is (see mod_lpsolver.xsd): 00058 * <PRE> 00059 * <xsd:complexType name="solver_lp"> 00060 * <xsd:complexContent> 00061 * <xsd:extension base="solver"> 00062 * <xsd:choice minOccurs="0" maxOccurs="unbounded"> 00063 * <xsd:element name="loglevel" type="loglevel" /> 00064 * <xsd:element name="minimum" type="xsd:boolean" /> 00065 * <xsd:element name="modelfile" type="xsd:normalizedString" /> 00066 * <xsd:element name="datafile" type="xsd:normalizedString" /> 00067 * <xsd:element name="solutionfile" type="xsd:normalizedString" /> 00068 * <xsd:element name="objective" type="xsd:normalizedString" /> 00069 * </xsd:choice> 00070 * <xsd:attribute name="loglevel" type="loglevel" /> 00071 * <xsd:attribute name="minimum" type="xsd:boolean" /> 00072 * <xsd:attribute name="modelfile" type="xsd:normalizedString" /> 00073 * <xsd:attribute name="datafile" type="xsd:normalizedString" /> 00074 * <xsd:attribute name="solutionfile" type="xsd:normalizedString" /> 00075 * <xsd:attribute name="objective" type="xsd:normalizedString" /> 00076 * </xsd:extension> 00077 * </xsd:complexContent> 00078 * </xsd:complexType> 00079 * </PRE> 00080 */ 00081 00082 #include "frepple.h" 00083 using namespace frepple; 00084 00085 extern "C" 00086 { 00087 #if defined HAVE_GLPK_H || !defined HAVE_GLPK_GLPK_H 00088 #include "glpk.h" 00089 #else 00090 #ifdef HAVE_GLPK_GLPK_H 00091 #include "glpk/glpk.h" 00092 #endif 00093 #endif 00094 } 00095 00096 namespace module_lp_solver 00097 { 00098 00099 /** Initialization routine for the library. */ 00100 MODULE_EXPORT const char* initialize(const Environment::ParameterList& z); 00101 00102 /** @brief This class is a prototype of an Linear Programming (LP) Solver for 00103 * the planning problem or a subset of it. 00104 * 00105 * The solver is intended primarly for prototyping purposes. Cleaner and 00106 * more performant alternatives are recommended for real production use. 00107 */ 00108 class LPSolver : public Solver 00109 { 00110 public: 00111 /** This method creates a new column in the model for every demand. It's 00112 * value represents the planned quantity of that demand. 00113 * @exception DataException Generated when no calendar has been specified. 00114 */ 00115 void solve(void* = NULL); 00116 00117 /** Return the name of the GNU MathProg model file. */ 00118 string getModelFile() const {return modelfilename;} 00119 00120 /** Update the name of the GNU MathProg model file. */ 00121 void setModelFile(const string& c) {modelfilename = c;} 00122 00123 /** Return the name of the GNU MathProg data file. */ 00124 string getDataFile() const {return datafilename;} 00125 00126 /** Update the name of the GNU MathProg data file. */ 00127 void setDataFile(const string& c) {datafilename = c;} 00128 00129 /** Return the name of the solution file. */ 00130 string getSolutionFile() const {return solutionfilename;} 00131 00132 /** Update the name of the solution file. <br> 00133 * After running the solver the solution is written to this flat file. 00134 */ 00135 void setSolutionFile(const string& c) {solutionfilename = c;} 00136 00137 /** Returns true when the solver needs to minimize the objective(s).<br> 00138 * Returns false when the solver needs to maximize the objective(s). 00139 */ 00140 bool getMinimum() const {return minimum;} 00141 00142 /** Update the solver direction: minimization or maximization. */ 00143 void setMinimum(bool m) {minimum = m;} 00144 00145 /** Append a new objective to the list. */ 00146 void addObjective(const string& c) {objectives.push_back(c);} 00147 00148 /** Return a reference to the list of objectives. */ 00149 const list<string>& getObjectives() const {return objectives;} 00150 00151 virtual void writeElement(XMLOutput*, const Keyword&, mode=DEFAULT) const; 00152 void endElement(XMLInput& pIn, const Attribute& pAttr, const DataElement& pElement); 00153 virtual PyObject* getattro(const Attribute&); 00154 virtual int setattro(const Attribute&, const PythonObject&); 00155 static int initialize(); 00156 00157 /** Constructor. */ 00158 LPSolver(const string& n) : Solver(n), minimum(true) {initType(metadata);} 00159 00160 /** Destructor. */ 00161 ~LPSolver() {}; 00162 00163 virtual const MetaClass& getType() const {return *metadata;} 00164 static const MetaClass *metadata; 00165 virtual size_t getSize() const {return sizeof(LPSolver);} 00166 00167 private: 00168 /** This is an auxilary function. GLPK requires names to contain only 00169 * "graphic" characters. A space isn't one of those. Since our model 00170 * can contain HasHierarchy names with a space, we call this function to 00171 * replace the spaces with underscores.<br> 00172 * Note however that we can't garantuee that the updated strings are 00173 * all unique after the replacement! 00174 */ 00175 static string replaceSpaces(const string&); 00176 00177 /** This object is the interface with the GLPK structures. */ 00178 LPX* lp; 00179 00180 /** Storing simplex configuration paramters. */ 00181 glp_smcp parameters; 00182 00183 /** A list of model columns to use as objectives. */ 00184 list<string> objectives; 00185 00186 /** Direction of the solver: minimization or maximization. */ 00187 bool minimum; 00188 00189 /** Name of the model file.<br> 00190 * This field is required.*/ 00191 string modelfilename; 00192 00193 /** Name of the data file.<br> 00194 * If the field is left empty, the data section in the model file is 00195 * used instead. 00196 */ 00197 string datafilename; 00198 00199 /** Name of the solution file.<br> 00200 * If the field is left empty, the solution is not exported. 00201 */ 00202 string solutionfilename; 00203 00204 /** A hook to intercept the terminal output of the solver library, and 00205 * redirect it into the frePPLe log file. 00206 */ 00207 static int solveroutputredirect(void* info, const char* msg) 00208 { 00209 logger << msg; 00210 logger.flush(); 00211 return 1; 00212 } 00213 00214 /** Solve for a goal in a hierarchical sequence. */ 00215 void solveObjective(const string&); 00216 }; 00217 00218 } // End namespace