00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "GlpkSolver.h"
00032 #include "Utils.h"
00033 #include "System.h"
00034
00035 #include <vector>
00036 #include <string>
00037 #include <iostream>
00038 #include <fstream>
00039 #include <sstream>
00040 #include <stdexcept>
00041
00042 namespace Modelib {
00043
00044 using namespace std;
00045
00049 GlpkSolver::GlpkSolver()
00050 {
00051 nomSolver = "glpsol";
00052 options.push_back("--cpxlp");
00053 }
00054
00058 GlpkSolver::~GlpkSolver()
00059 {
00060
00061 }
00062
00063
00064 float GlpkSolver::Solve(Solution& sol, const string& nameFile)
00065 {
00066
00067 sol.Clear();
00068 tempName = ".tmp." + nameFile;
00069 string solName(nameFile);
00070 Utils::Replace(solName, ".lp", ".sol");
00071
00072
00073 try {
00074 CreerFichierTemporaire(nameFile);
00075 }
00076 catch(exception& e) {
00077 cout << e.what() << endl;
00078 }
00079
00080
00081 Resoudre(solName);
00082
00083 try {
00084
00085 Interprete(solName, sol);
00086 }
00087 catch (exception& e)
00088 {
00089 cout << e.what() << endl;
00090 }
00091
00092 return sol.objective.second;
00093 }
00094
00095
00099 ostream& GlpkSolver::EcrireBonneLargeur(ostream& out, const string& str)
00100 {
00101 if (str.length() < 255)
00102 out << str << endl;
00103 else
00104 {
00105 string temp;
00106 unsigned nb_chars=0;
00107 for (string::const_iterator iter=str.begin();iter!=str.end();++iter,nb_chars++)
00108 {
00109 temp.push_back(*iter);
00110 if(*iter == '+' || *iter == '-')
00111 {
00112 if(nb_chars + temp.length() < 255)
00113 {
00114 out << temp;
00115 temp.clear();
00116 }
00117 else
00118 {
00119 nb_chars = 0;
00120 out << endl << temp ;
00121 temp.clear();
00122 }
00123 }
00124 }
00125 out << temp << endl;
00126 }
00127 return out;
00128 }
00129
00130
00137 void GlpkSolver::CreerFichierTemporaire(const string& nameFile)
00138 {
00139 ofstream mod(tempName.c_str());
00140 if(!mod.is_open())
00141 throw runtime_error("(GlpkSolver::CreerFichierTemporaire) - I/O Error pour " + tempName);
00142
00143 ifstream in(nameFile.c_str());
00144 if(!in.is_open())
00145 throw runtime_error("(GlpkSolver::CreerFichierTemporaire) - I/O Error");
00146
00147 string s;
00148 while (getline(in, s))
00149 {
00150 EcrireBonneLargeur(mod, s);
00151 }
00152 }
00153
00154
00159 void GlpkSolver::Resoudre(const string& solName)
00160 {
00161 string cmd = nomSolver;
00162
00163 for (vector<string>::const_iterator iter=options.begin(); iter!=options.end(); ++iter) {
00164 cmd += " ";
00165 cmd += (*iter);
00166 }
00167
00168 cmd += " ";
00169 cmd += tempName;
00170
00171
00172 cmd += " -o ";
00173 cmd += solName;
00174
00175
00176 System::call(cmd.c_str());
00177 }
00178
00179
00186 void GlpkSolver::Interprete(const string& solName, Solution& sol)
00187 {
00188 ifstream inFile(solName.c_str());
00189 if(!inFile.is_open())
00190 throw runtime_error("(GlpkSolver::Inteprete) - I/O Error");
00191
00192 string s;
00193 bool Debut = true;
00194 bool Contraintes=false,Variables=false;
00195
00196
00197 cout << "Interpreter le fichier " << solName << endl;
00198
00199
00200 while (getline(inFile,s))
00201 {
00202
00203 if (Debut)
00204 {
00205 isSolved = true;
00206 string::size_type place;
00207 if ((place=s.find("Status:")) != string::npos)
00208 {
00209 string reste,tmp;
00210 istringstream sstr(s);
00211 sstr >> tmp >> reste;
00212 tmp.clear();
00213 while(sstr)
00214 {
00215 sstr >> tmp;
00216 reste.push_back(' ');
00217 reste += (tmp);
00218 reste.push_back(' ');
00219 tmp.clear();
00220 }
00221
00222 typeRetour = reste;
00223 if ((place=typeRetour.find("OPTIMAL")) != string::npos)
00224 isOptimal = true;
00225 }
00226 else if ((place=s.find("Objective:")) != string::npos)
00227 {
00228 string _nom;
00229 string reste[10];
00230 float _val;
00231 string c;
00232 unsigned i=1;
00233
00234
00235 istringstream sstr(s);
00236 sstr >> reste[0] >> _nom >> c >> _val;
00237 while(sstr)
00238 sstr >> reste[i++];
00239 sol.objective = make_pair(_nom, _val);
00240
00241
00242 if ((place=reste[1].find("MIN")) != string::npos)
00243 typeOperation = "Minimisation";
00244 else
00245 typeOperation = "Maximisation";
00246 Debut = false;
00247 }
00248 else
00249 continue;
00250
00251 }
00252 else if (s.find("Row ") != string::npos)
00253 {
00254
00255 getline(inFile,s);
00256 Contraintes = true;
00257 }
00258 else if (s.find("Column ") != string::npos)
00259 {
00260 Contraintes = false;
00261
00262 getline(inFile,s);
00263 Variables = true;
00264 }
00265 else if (Contraintes)
00266 {
00267
00268 istringstream sstr(s);
00269 unsigned id;
00270 string nom;
00271 string st;
00272 float var;
00273 string lB, uB, M;
00274 sstr >> id >> nom >> st >> var >> lB >> uB >> M;
00275
00276 if (nom == "")
00277 Contraintes = false;
00278
00279 sol.contraintesVAL.push_back(var);
00280 sol.contraintesNOM.push_back(nom);
00281 }
00282 else if (Variables)
00283 {
00284
00285 istringstream sstr(s);
00286 unsigned id;
00287 string nom;
00288 string st;
00289 string varstr;
00290 string lB, uB, M;
00291 sstr >> id >> nom >> st >> varstr >> lB >> uB >> M;
00292
00293 if (nom == "")
00294 Variables = false;
00295
00296 if (st != "*"
00297 && st != "NL"
00298 && st != "B"
00299 && st != "NS"
00300 && st != "NU")
00301 {
00302 varstr = st;
00303 }
00304
00305 istringstream tmp(varstr);
00306 float var;
00307 tmp >> var;
00308 sol.variablesVAL.push_back(var);
00309 sol.variablesNOM.push_back(nom);
00310 }
00311 }
00312 inFile.close();
00313 }
00314
00315
00316 }
00317