Page principale | Liste des namespaces | Hiérarchie des classes | Liste alphabétique | Liste des classes | Liste des fichiers | Membres de namespace | Membres de classe | Membres de fichier

FichierLP.cpp

Aller à la documentation de ce fichier.
00001 /*
00002     Copyright (c) 2005, Quentin Lequy and Romain Gaucher
00003     All rights reserved.
00004 
00005     Redistribution and use in source and binary forms, with or 
00006     without modification, are permitted provided that the following 
00007     conditions are met:
00008 
00009         * Redistributions of source code must retain the above copyright 
00010           notice, this list of conditions and the following disclaimer.
00011 
00012         * Redistributions in binary form must reproduce the above copyright 
00013           notice, this list of conditions and the following disclaimer in the 
00014           documentation and/or other materials provided with the distribution.
00015 
00016         * Neither the name of Quentin Lequy or Romain Gaucher nor the names 
00017           of its contributors may be used to endorse or promote products 
00018           derived from this software without specific prior written permission.
00019 
00020     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00021     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00022     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
00023     ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
00024     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
00025     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
00026     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
00027     AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00028     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
00029     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 */
00031 
00032 //:~ sof
00033 #include "Config.h"
00034 #include "FichierLP.h"
00035 #include <iostream>
00036 #include <fstream>
00037 #include <sstream>
00038 #include <list>
00039 #include <string>
00040 #include <algorithm>
00041 #include <cctype>
00042 #include <map>
00043 #include <utility>
00044 #include <vector>
00045 
00046 namespace Modelib {
00047 
00048 using namespace std;
00049 
00050 
00059 ostream& operator<<(ostream &o, const string& str)
00060 {
00061     for (string::const_iterator iter=str.begin();iter!=str.end();++iter)
00062     {
00063         // on ignore les caracteres non affichables !
00064         if (*iter < 32)
00065             continue;
00066         o << *iter;
00067     }
00068     return o;
00069 }
00070 
00076 ostream& operator<<(ostream &o, const plExprNode& pl)
00077 {
00078   o << (pl.signe == MINUS ? '-' : '+') << pl.num << "*" << pl.var;
00079   return o;
00080 }
00081 
00087 ostream& operator<<(ostream &o, const plGlobalNode& pl)
00088 {
00089   if (pl.nom != "")
00090     o << pl.nom << ": ";
00091   for (list<plExprNode *>::const_iterator iter = pl.expr.begin();iter!=pl.expr.end(); ++iter)
00092   {
00093     if (iter == pl.expr.begin())
00094        o << ((*iter)->signe == MINUS ? "-" : " ") << (*iter)->num << '*' << (*iter)->var << ' ';
00095     else
00096        o << **iter;
00097   }
00098   o << "  " << comp[pl.cont.comp] << " " << pl.cont.bound;
00099   return o;
00100 }
00101 
00102 
00108 ostream& operator<<(ostream& o, const plConstraintNode& pl)
00109 {
00110   o << pl.minBound << " ";
00111   o << comp[pl.comp1] << " ";
00112   if (pl.num != "1")
00113      o << pl.num << "*";
00114   o << pl.var;
00115 
00116   if (pl.comp2 != 99)
00117      o << comp[pl.comp2] << " " << pl.maxBound;
00118 
00119   return o;
00120 }
00121 
00140 ostream& operator<<(ostream &o, const FichierProbleme& pblm)
00141 {
00142     o << "\\Sortie du fichier de probleme: " << pblm.nom << endl;
00143 
00144     // Affichage de la fonction objectif
00145     if (pblm.isMax == true)
00146        o << "Maximize" << endl;
00147     else
00148        o << "Minimize" << endl;
00149 
00150     for (list<plExprNode *>::const_iterator iter  = pblm.exprObj.begin();
00151                                             iter != pblm.exprObj.end()  ;
00152                                           ++iter)
00153       if (iter == pblm.exprObj.begin() && (*iter)->var.length())
00154          o << "\t" << ((*iter)->signe == MINUS ? "-" : " ") << (*iter)->num << "*" << (*iter)->var << ' ';
00155       else
00156          o << **iter;
00157 
00158     // Affichages des contraintes (fonctions)
00159     o << endl;
00160     o << "Subject to" << endl;
00161 
00162 
00163     for (list<plGlobalNode *>::const_iterator iter  = pblm.exprConstraint.begin();
00164                                             iter != pblm.exprConstraint.end()  ;
00165                                           ++iter)
00166          o << "\t" << **iter << endl;
00167 
00168     if (!pblm.exprBounds.empty())
00169     {
00170       o << "Bounds" << endl;
00171   
00172   
00173       for (list<plConstraintNode *>::const_iterator iter  = pblm.exprBounds.begin();
00174                                               iter != pblm.exprBounds.end()  ;
00175                                             ++iter)
00176            o << "\t" << **iter << endl;
00177     }
00178     if (!pblm.exprGeneral.empty())
00179     {
00180       o << "Generals" << endl;
00181       for (list<string>::const_iterator iter =pblm.exprGeneral.begin();
00182                                         iter!=pblm.exprGeneral.end()  ;
00183                                       ++iter)
00184            o << "\t" << *iter << endl;
00185     }
00186 
00187     if (!pblm.exprBinary.empty())
00188     {
00189       o << "Binaries" << endl;
00190       for (list<string>::const_iterator iter =pblm.exprBinary.begin();
00191                                         iter!=pblm.exprBinary.end()  ;
00192                                       ++iter)
00193            o << "\t" << *iter << endl;
00194     }
00195 
00196     o << "End";
00197     return o;
00198 }
00199 
00200 
00201 
00209 FichierLP::FichierLP()
00210 {
00211 
00212   mmap.insert(pair<string,unsigned>("maximize",MAXIMIZE));
00213   mmap.insert(pair<string,unsigned>("max",MAXIMIZE));
00214 
00215   mmap.insert(pair<string,unsigned>("minimize",MINIMIZE));
00216   mmap.insert(pair<string,unsigned>("min",MINIMIZE));
00217 
00218   mmap.insert(pair<string,unsigned>("subject to",SUBJECT));
00219   mmap.insert(pair<string,unsigned>("subject",SUBJECT));
00220   mmap.insert(pair<string,unsigned>("such that",SUBJECT));
00221   mmap.insert(pair<string,unsigned>("st",SUBJECT));
00222   mmap.insert(pair<string,unsigned>("st.",SUBJECT));
00223   mmap.insert(pair<string,unsigned>("s.t.",SUBJECT));
00224 
00225   mmap.insert(pair<string,unsigned>("bounds",BOUNDS));
00226   mmap.insert(pair<string,unsigned>("bound",BOUNDS));
00227 
00228   mmap.insert(pair<string,unsigned>("end",END));
00229 
00230   mmap.insert(pair<string,unsigned>("generals",GENERALS));
00231   mmap.insert(pair<string,unsigned>("general",GENERALS));
00232   mmap.insert(pair<string,unsigned>("gen",GENERALS));
00233   mmap.insert(pair<string,unsigned>("integers",GENERALS));
00234   mmap.insert(pair<string,unsigned>("integer",GENERALS));
00235 
00236   mmap.insert(pair<string,unsigned>("binaries",BINARIES));
00237   mmap.insert(pair<string,unsigned>("binary",BINARIES));
00238   mmap.insert(pair<string,unsigned>("bin",BINARIES));
00239 
00240   mmap.insert(pair<string,unsigned>("free",FREE));
00241 
00242   // remplir le Comp2Int
00243   for (unsigned i=0;i<6;i++)
00244       Comp2Int[comp[i]] = i;
00245 }
00246 
00251 bool FichierLP::IsComment(string& s)
00252 {
00253   // on return false si c pas un comentaire complet
00254   // et on efface tout ce qu'il y a apres
00255   string::iterator iter = s.begin();
00256   string           tmp;
00257   // si c'est une ligne complete
00258   if (*iter == '\\') {
00259      commentaires.push_back( pair<long,string>( (long)exprConstraint.size() 
00260      + ( exprObj.size()==0?0:1) ,s) );
00261      return true;
00262   }
00263   // sinon... on gicle tout ce qu'il y a apres le char
00264   for (;iter!=s.end();++iter)
00265   {
00266     if (*iter == '\\')
00267        break;
00268     tmp += *iter;
00269   }
00270   s.erase();
00271   s = tmp;
00272   return false;
00273 }
00274 
00279 string FichierLP::trim(const string& s) const
00280 {
00281   if(s.empty())
00282     return s;
00283   int b = s.find_first_not_of(" ");
00284   int e = s.find_last_not_of(" ");
00285   if(b == -1)
00286     return "";
00287   return string(s, b, e - b + 1);
00288 }
00289 
00294 string FichierLP::AvoidSpaces(const string& s) const
00295 {
00296   string t;
00297   string::const_iterator iter = s.begin();
00298   for(;iter!=s.end();++iter)
00299     if (*iter != ' ')
00300       t += *iter;
00301   return t;
00302 }
00303 
00309 bool FichierLP::IsNumber(const string& s) const
00310 {
00311   const string nums="0123456789./";
00312   string::const_iterator iter;
00313   bool pointWOSlash = false;
00314   for (iter=s.begin();iter!=s.end();++iter)
00315   {
00316     if (pointWOSlash && *iter=='.')
00317       return false;
00318     if (nums.find(*iter) != string::npos)
00319     {
00320       if (*iter == '.')  pointWOSlash=true;
00321       if (*iter == '/' ) pointWOSlash=false;
00322     }
00323     else
00324       return false;
00325   }
00326   return true;
00327 /* tests effectués là dessus
00328   cout << endl;
00329   cout << "2.000 = " << IsNumber("2.000") << endl;
00330   cout << "2.000. = " << IsNumber("2.000.") << endl;
00331   cout << "2.000/1 = " << IsNumber("2.000/1") << endl;
00332   cout << "2.000/0.00 = " << IsNumber("2.000/0.00") << endl;
00333   cout << "2.000/0.00. = " << IsNumber("2.000/0.00.") << endl;
00334   cout << endl;
00335 */
00336 }
00337 
00343 void FichierLP::Tokenize(const string& str,list<string>& tokens_plus
00344                                           ,list<string>& tokens_minus)
00345 {
00346     enum Token_Value {PLUS='+', MINUS='-'};
00347     Token_Value cur_token = PLUS;
00348     string tmp;
00349     string::size_type i=0;
00350     const string::size_type len = str.length();
00351 
00352     do
00353     {
00354       while(str[i]==' ') ++i;
00355       if (str[i] == PLUS || str[i] == MINUS)
00356       {
00357         if(tmp.length())
00358         {
00359             // on le balance dans le container de tokens
00360             switch(cur_token)
00361             {
00362               case PLUS :  tokens_plus.push_back(tmp); break;
00363               case MINUS:  tokens_minus.push_back(tmp); break;
00364               default   :                              break;
00365             }
00366             // alors on flush tmp
00367             tmp.clear();
00368             // actualisation du token
00369             cur_token = (str[i]=='+'?PLUS:MINUS);
00370         }
00371         else
00372           cur_token = (str[i]=='+'?PLUS:MINUS);
00373       }
00374       else
00375         tmp += str[i];
00376       ++i;
00377     }
00378     while (i < len);
00379     
00380     // il reste necessairement la derniere partie 
00381     switch(cur_token)
00382     {
00383       case PLUS :  tokens_plus.push_back(tmp); break;
00384       case MINUS: tokens_minus.push_back(tmp); break;
00385       default   :                              break;
00386     }
00387 }
00388 
00394 void FichierLP::GetNumVar(const string& str, string& num, string& var)
00395 {
00396   string::const_iterator iter=str.begin();
00397   unsigned i=0;
00398   if (!isdigit(*iter))
00399   {
00400     num = "1";
00401     var = str;
00402   }
00403   else
00404   {
00405     for (;iter!=str.end();++iter,++i)
00406     {
00407       if (!IsNumber(str.substr(0,i)))
00408       {
00409         num=str.substr(0,i-1);
00410         var=str.substr(i-1,str.length());
00411         break;
00412       }
00413     }
00414   }
00415 }
00416 
00417 
00418 
00419 
00423 void FichierLP::ParseObjective(const string& s)
00424 {
00425   // on va tokeniser par +/-
00426   list<string> token_plus;
00427   list<string> token_minus;
00428   list<string>::iterator iter;
00429 
00430   if (s.length() <= 1)
00431      return;
00432 
00433   Tokenize (s,token_plus,token_minus);
00434 
00435   for(iter=token_plus.begin();iter!=token_plus.end();++iter)
00436   {
00437     string var,num;
00438     GetNumVar(*iter,var,num);
00439 
00440     //cout << "PLUS: "<< var << '(' << trim(var) << ')' << '(' << var.size() << ')' << endl;
00441 
00442     auto_ptr<plExprNode> exprNode (new plExprNode (num,var,PLUS)) ;
00443     exprObj.push_back(exprNode.release());
00444   }
00445 
00446   for(iter=token_minus.begin();iter!=token_minus.end();++iter)
00447   {
00448     string var,num;
00449     GetNumVar(*iter,var,num);
00450     //cout << "PLUS: "<< var << '(' << trim(var) << ')' << '(' << var.size() << ')' << endl;
00451 
00452     auto_ptr<plExprNode> exprNode (new plExprNode (num,var,MINUS)) ;
00453     exprObj.push_back(exprNode.release());
00454   }
00455 
00456   // ca marche !
00457   //cout << "Et là ?" << endl;
00458   // afficher les données
00459   //for (list<plExprNode *>::iterator i=exprObj.begin(); i!=exprObj.end(); ++i)
00460   //    cout << **i << endl;
00461 
00462 
00463 }
00464 
00465 
00470 void FichierLP::ParseSubjects (const string& s, const string& nom)
00471 {
00472   // contraintes SubJects...
00473   // trouver le délimitage :]
00474   string::size_type place_comp=string::npos;
00475   unsigned i=0;
00476   
00477 
00478     if (s.length() <= 1)
00479      return;
00480 
00481 
00482   for (;i<6;i++)
00483   {
00484     if ((place_comp = s.find(comp[i])) != string::npos)
00485        break;
00486   }
00487 
00488   if (place_comp == string::npos)
00489   {
00490     // bah ca merde !
00491     return;
00492   }
00493 
00494   string compareTo;
00495   string second;
00496   compareTo = s.substr(place_comp+comp[i].length(),s.length());
00497   second    = s.substr(0,place_comp);
00498 
00499   //cout << i << " chaine=" << second << "| compare a=" << compareTo << " par " << comp[i] << endl;
00500 
00501   list<string> token_plus;
00502   list<string> token_minus;
00503   list<string>::iterator iter;
00504   Tokenize (second,token_plus,token_minus);
00505 
00506   // ce qu'on va pusher !
00507   //auto_ptr<plGlobalNode> tmpNode;
00508   list<plExprNode *>     tmpObj;
00509 
00510   for(iter=token_plus.begin();iter!=token_plus.end();++iter)
00511   {
00512     string var,num;
00513     GetNumVar(*iter,var,num);
00514     auto_ptr<plExprNode> exprNode (new plExprNode (num,var,PLUS)) ;
00515     tmpObj.push_back(exprNode.release());
00516   }
00517 
00518   for(iter=token_minus.begin();iter!=token_minus.end();++iter)
00519   {
00520     string var,num;
00521     GetNumVar(*iter,var,num);
00522     auto_ptr<plExprNode> exprNode (new plExprNode (num,var,MINUS)) ;
00523     tmpObj.push_back(exprNode.release());
00524   }
00525 
00526   // ca, ca nous ressort bien ce qu'on veut !
00527   // ie la liste des tokens
00528   //cout << "Ce qu'on devrait avoir..." << endl;
00529   //for (list<plExprNode *>::iterator i=tmpObj.begin(); i!=tmpObj.end(); ++i)
00530   //    cout << **i << endl;
00531 
00532   // Creation de notre ptr qui sera pushé
00533   plSimpleConstraint tmpConst(compareTo,i);
00534   auto_ptr<plGlobalNode> tmpNode (new plGlobalNode (nom,tmpObj,tmpConst));
00535 
00536   // gnourf ?
00537   //cout << "Ce qu'on a :|" << endl;
00538 
00539   // afficher les données
00540   //cout << "Choppage en manuel des 'values'" << endl;
00541   //list<plExprNode *>::const_iterator iterNode=tmpNode.get()->expr.begin();
00542 
00543   // boucle avec l'itérateur
00544   //cout << "et avec l'itérateur.. et là, c le drame" << endl;
00545   //for (iterNode=tmpNode.get()->expr.begin();iterNode!=tmpNode.get()->expr.end(); ++iterNode)
00546   //    cout << **iterNode << endl;
00547 
00548   //cout << *(tmpNode.get()) << endl;
00549 
00550   exprConstraint.push_back(tmpNode.release());
00551 }
00552 
00553 
00558 unsigned GetNbComparator(const string& _str)
00559 {
00560   unsigned nbComp=0;
00561   string::size_type pos;
00562   string sub=_str;
00563 
00564   for (unsigned j=0;j<6;)
00565   {
00566     if ((pos=sub.find(comp[j])) != string::npos)
00567     {
00568       nbComp++;
00569       sub = sub.substr(pos+comp[j].length(),sub.length());
00570     }
00571     else
00572       j++;
00573   }
00574   return nbComp;
00575 }
00576 
00577 
00585 void FichierLP::ParseBounds(const string& s)
00586 {
00587   // parser :
00588   // -Inf <= a <= bsup
00589   //         b <= bsup
00590   // binf <= c
00591   string str;
00592 
00593   if (s.length() <= 1)
00594      return;
00595 
00596 
00597   string::const_iterator iter,it2=s.begin(),next;
00598   // compter le nombre de de signes
00599   unsigned nbComp = GetNbComparator(s);
00600   // 2*nbComp+1 champs !
00601 
00602   // on ajoute des espaces pour utiliser les stringstream
00603   // iter: cour
00604   // it2 : prec
00605   next = s.begin(); ++next;
00606   for (iter=s.begin();iter!=s.end();++iter, ++next)
00607   {
00608       switch(*iter)
00609       {
00610         case '<': // Si <
00611         case '>': // ou >
00612              str.push_back(' ');   // on ajoute l'espace
00613              str.push_back(*iter); // et < ou >
00614                 
00615                 // ajouter un espace s'il n'y a pas de signe apres
00616                 if (*next != '=')
00617                    str.push_back(' ');
00618              break;
00619 
00620         case '=':
00621              if (*it2 != '<' && *it2 != '>')
00622                str.push_back(' ');
00623              str.push_back(*iter);
00624              str.push_back(' ');
00625              break;
00626 
00627         default:
00628              str.push_back(*iter);
00629              break;
00630       }
00631       it2 = iter;
00632   }
00633 
00634   string *t = 0;
00635   if (nbComp > 0)
00636   {
00637     istringstream sstring(str);
00638     t = new string[(2*nbComp+1)];
00639   
00640     for (unsigned i=0;i<(nbComp<<1) + 1;i++)
00641     {
00642         sstring >> t[i];
00643     }
00644   }
00645 
00646 
00647   // on va remplir le exprBounds
00648   // exprBounds
00649   switch (nbComp)
00650   {
00651     case 2:
00652       {
00653           // 2 comparateurs => min <= var <= max
00654           //plConstraintNode(const std::string& _var, const std::string& _num,
00655           //                   const std::string& _b1 , const std::string& _b2 ,
00656           //                   const unsigned     _c1 , const unsigned     _c2)
00657          auto_ptr<plConstraintNode> cNode (new plConstraintNode (t[2],"1",t[0],t[4],Comp2Int[t[1]],Comp2Int[t[3]]));
00658          exprBounds.push_back(cNode.release());
00659       }
00660     break;
00661 
00662     case 1:
00663       {
00664          // si t[0] est un nombre alors
00665          //   forme 0 <= var      _num _var _minbound _comp1
00666          // sinon
00667          //   autre forme         _num _var _comp1 _maxbound
00668          //cout << "t0 = " << t[0] << endl;
00669          if (IsNumber(t[0]))
00670          {
00671            auto_ptr<plConstraintNode> cNode (new plConstraintNode ("1",t[2],t[0],Comp2Int[t[1]]));
00672            exprBounds.push_back(cNode.release());
00673          }
00674          else
00675          {
00676            auto_ptr<plConstraintNode> cNode (new plConstraintNode ("1",t[0],t[2],(Comp2Int[t[1]]+2)%4));
00677            exprBounds.push_back(cNode.release());
00678          }
00679       }
00680     break;
00681     
00682     case 0:
00683      {
00684         // Le free est ici
00685         // x1 Free
00686         string tmp;
00687         istringstream sstring(str);
00688         sstring >> tmp;
00689         auto_ptr<plConstraintNode> cNode (new plConstraintNode (tmp,"1","-Inf","Inf",LOWER_THAN,LOWER_THAN));
00690         exprBounds.push_back(cNode.release());
00691      }
00692     break;
00693 
00694     default:
00695         // on levera une exception ici pke ca ne peut pas exister !
00696         // enfin, je pense sincèremetn que CPlex ne gere pas :
00697         // MIN <= x1 <= x2 <= x3 <= ... <= MAX
00698     break;
00699   }
00700   if (t)
00701     delete [] t;
00702 }
00703 
00707 void FichierLP::ParseGenerals(const string& s)
00708 {
00709      // on a une ligne x2,x3,x4...
00710      // ou  x1
00711      //     x2
00712      //     x3
00713 
00714      // 1/ on va donc se normaliser l'expression en x4 x2 etc. sur une ligne
00715      // 2/ utiliser un stringstream et pusher le tout dans la liste
00716 
00717 
00718     if (s.length() <= 1)
00719        return;
00720     
00721     
00722     // 1/ Il suffit de remplacer toutes les virgules par des espaces :]
00723     string str;
00724     string::const_iterator iter=s.begin();
00725     for (;iter!=s.end(); ++iter)
00726     {
00727       if (*iter == ',')
00728          str.push_back(' ');
00729       else
00730          str.push_back(*iter);
00731     }
00732     
00733     // 2/ istringstream est sympatique :]
00734     istringstream istring(str);
00735     string tmp;
00736     while (istring >> tmp) {
00737          exprGeneral.push_back(tmp);
00738          tmp.erase();
00739     }
00740 }
00741 
00742 
00746 void FichierLP::ParseBinaries(const string& s)
00747 {
00748      // on a une ligne x2,x3,x4...
00749      // ou  x1
00750      //     x2
00751      //     x3
00752 
00753   if (s.length() <= 1)
00754      return;
00755 
00756 
00757      // 1/ on va donc se normaliser l'expression en x4 x2 etc. sur une ligne
00758      // 2/ utiliser un stringstream et pusher le tout dans la liste
00759 
00760 
00761      // 1/ Il suffit de remplacer toutes les virgules par des espaces :]
00762      string str;
00763      string::const_iterator iter=s.begin();
00764      for (;iter!=s.end(); ++iter)
00765      {
00766         if (*iter == ',')
00767            str.push_back(' ');
00768         else
00769            str.push_back(*iter);
00770      }
00771      
00772      // 2/ istringstream est sympatique :]
00773      istringstream istring(str);
00774      string tmp;
00775      while (istring >> tmp) {
00776            exprBinary.push_back(tmp);
00777            tmp.erase();
00778      }
00779 }
00780 
00781 
00782 
00787 bool FichierLP::Open(const string& nomFile)
00788 {
00789   ifstream ifile(nomFile.c_str());
00790 
00791   string   s,tempInlineString;
00792   multimap<string,unsigned>::iterator k;
00793   unsigned oldK=42;
00794   bool continu=false,f=false;
00795   bool objectiveInline = false;
00796 
00797 
00798   if (!ifile.is_open())
00799      return false;
00800 
00801   //while (getline(ifile,s))
00802   //      cout << s << endl;
00803   //ifile.clear();
00804   // on revient au début apres avoir affiché le source lp
00805   //if (!ifile.seekg(0,ifstream::beg))
00806   //   return false;
00807 
00808   while (getline(ifile,s,'\n'))
00809   {
00810     if (!s.empty() && IsComment(s) == false)
00811     {
00812         string::size_type position = s.rfind('\r');
00813         if (position != string::npos)
00814             s.replace(position,1," ");
00815 
00817       // par la casse
00818       if (objectiveInline)
00819       {
00820         objectiveInline = false;
00821         // on traite tempInelinestring comme un ParseObjective
00822         ParseObjective(tempInlineString);
00823       }
00824 
00825       //string c=s;
00826       string c;
00827       for (string::const_iterator iter = s.begin(); iter!=s.end();++iter)
00828       {
00829         if (*iter == ' ')
00830            break;
00831         c.push_back(*iter);
00832       }
00833 
00834       transform (c.begin(),c.end(),c.begin(),::tolower);
00835       // On peut maintenant travailler sur le "string s"
00836 
00837       k = mmap.find(trim(c)); // Recherche de la value !s
00838       if (k == mmap.end())    // si value non trouvée dans la table
00839          continu = true;
00840       else                    // c'est que ce n'est pas un nouveau champ
00841           continu = false,
00842           oldK = 42;
00843 
00844       if (!continu && k->second == END)
00845       {
00846 
00847         // affichage des tous les commentaires
00848         /*for (list<string>::iterator iC =commentaires.begin();
00849                                     iC!=commentaires.end();
00850                                     ++iC)
00851             cout << "Commentaires: " << *iC << endl;
00852         */
00853 
00854          return true;
00855       }
00856 
00857       if (oldK==42 && objectiveInline==false && ((k->second == MAXIMIZE && oldK != MAXIMIZE) || (k->second == MINIMIZE && oldK != MINIMIZE)))
00858       {
00859         objectiveInline = true;
00860         tempInlineString = s.substr(8,s.length());
00861       }
00862 
00863       switch(oldK)
00864       {
00865          //
00866          // on doit gérer le multiligne
00867          // ce n'est pas encore fait pour les contraintes
00868          // ca devrait y etre bientot ...
00869          // quand tous les champs seront gérés
00870          //
00871          //                                         13/12/2004
00872          case MINIMIZE:
00873          case MAXIMIZE:
00874          {
00875            if (f==false){
00876                if (oldK==MINIMIZE) isMax=false, f=true;
00877              else                isMax=true,  f=true;
00878            }
00879            // string | list<lpExprNode *> | plSimpleConstraint
00880            size_t pos;
00881            string _nom="(null)";
00882 
00883            s = AvoidSpaces(s);
00884            // on va avancer jusqu'aux ':'
00885            if ((pos = s.find(':',0)) != string::npos)
00886            {
00887              _nom = s.substr(0,pos);
00888              nom = _nom;
00889              s.erase(0,pos+1);
00890            }
00891            ParseObjective(s);
00892              break;
00893          }
00894          case SUBJECT:
00895          {
00896            size_t pos;
00897            string nom;
00898 
00899            s = AvoidSpaces(s);
00900            if ((pos = s.find(':',0)) != string::npos) {
00901              nom = s.substr(0,pos);
00902              s.erase(0,pos+1);
00903            }
00904            ParseSubjects(s,nom);
00905              break;
00906          }
00907          case BOUNDS:
00908              ParseBounds(trim(s));
00909              break;
00910          case GENERALS:
00911              ParseGenerals(trim(s));
00912              break;
00913          case BINARIES:
00914              ParseBinaries(trim(s));
00915              break;
00916          case END:
00917            break;
00918          default:
00919            break;
00920       }
00921 
00922       if (continu == false)
00923         oldK = k->second;
00924     }
00925   }
00926 
00927   return true;
00928 }
00929 
00930 }
00931 
00932 //:~ eof

Généré le Sun Oct 2 19:13:12 2005 pour Modelib par  doxygen 1.4.4