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

FichierProbleme.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 #include "FichierProbleme.h"
00033 #include "Model.h"
00034 
00035 #include <ctime>
00036 
00037 namespace Modelib {
00038 
00039 
00040 using namespace std;
00041 
00047 bool FichierProbleme::operator>> (Model & m)
00048 {
00049   map<string,NumVar> table;
00050   //table permettant de faire correspondre un nom de variable "texte" 
00051   //du fichier probleme à une variable du modele
00052   map<string,NumVar>::iterator cour;
00053   //itérateur sur cette table
00054 
00055   list<plExprNode *>::iterator obj =  exprObj.begin();
00056   //itérateur permettant de parcourir la fonction objectif "texte"
00057   list<plGlobalNode *>::iterator cons = exprConstraint.begin();
00058   //itérateur permettant de parcourir les contraintes "texte"
00059   list<string>::iterator gen = exprGeneral.begin();
00060   //itérateur permettant de parcourir les variables entieres "texte"
00061   list<string>::iterator bin = exprBinary.begin();
00062   //itérateur permettant de parcourir les variables boolennes "texte"
00063   list<plConstraintNode *>::iterator bou =  exprBounds.begin();
00064   //itérateur permettant de parcourir les bornes "texte"
00065 
00066   cerr << "FichierProbleme : Loading" << endl;
00067   cerr << "Generals";
00068   //Pour chaque nom de variable dans Generals
00069   for( ; gen != exprGeneral.end(); ++gen )
00070   {
00071     cour = table.find( *gen );
00072     //on regarde si la variable existe
00073     if( cour != table.end() )
00074     {
00075        cour->second.SetType(MuteVar::INT);
00076        //on change son type si elle existe déjà
00077     }
00078     else
00079     {
00080         NumVar x(m,0,Infinity,MuteVar::INT,*gen);
00081         table[*gen] = x;
00082         //sinon on la crée et on la répertorie
00083     }
00084    }
00085   cerr << "[OK]" << endl;
00086 
00087   cerr << "Booleans";
00088   //Pour chaque nom de variable dans Booleans
00089   for( ; bin != exprBinary.end(); ++bin )
00090   {
00091     cour = table.find( *bin );
00092     //on regarde si la variable existe
00093     if( cour != table.end() )
00094     {
00095        cour->second.SetType(MuteVar::BOOL);
00096        //on change son type si elle existe déjà
00097        cour->second.SetLowerBound(0);
00098        cour->second.SetUpperBound(1);
00099        //On change ses bornes
00100    }
00101     else
00102     {
00103         NumVar x(m,0,1,MuteVar::BOOL,*bin);
00104         table[*bin] = x;
00105         //sinon on la crée et on la répertorie
00106     }
00107   }
00108   cerr << "[OK]" << endl;
00109   
00110   cerr << "Objectif";
00111   Expr tmp; 
00112   //Expression temporaire qui va servir à construire la contrainte
00113   //Pour toutes les groupes coefficient * variable de la fonction objectif
00114   for( ; obj != exprObj.end(); ++obj )
00115   {
00116     cour = table.find((*obj)->var);
00117     //on regarde si la variable existe
00118     float coef = atof( (*obj)->num.data() );
00119     //on convertit le coefficient "texte" en float
00120     coef = ((*obj)->signe?coef:-coef);
00121     //on change son signe au cas ou il y ait "-" devant
00122     if( cour != table.end() )
00123     {
00124         tmp.ASS(coef,cour->second);
00125         //On ajoute le tout à l'expression temporaire si elle existe
00126     }
00127     else
00128     {
00129         NumVar x(m,0,Infinity,MuteVar::FLOAT,(*obj)->var);
00130         table[(*obj)->var] = x;
00131         //sinon on la crée et on la répertorie
00132         tmp.ASS(coef,x);
00133         //et on ajoute le tout à l'expression temporaire si elle existe
00134     }
00135   }
00136   
00137   //si la fonction est une maximisation
00138   if(isMax == true)
00139      m.Maximize( tmp, nom );
00140      //on définit cette fonction pour une maximisation
00141   else
00142      m.Minimize( tmp, nom );
00143      //on définit cette fonction pour une minimisation
00144 
00145   cerr << "[OK]" << endl;
00146 
00147   cerr << "Constraints";
00148 
00149   //Pour toutes les contraintes
00150   for( ; cons != exprConstraint.end(); ++cons )
00151   {
00152     tmp = Expr();
00153     //On réintialise l'expression temporaire
00154     //Pour toutes les groupes coefficient * variable de la contrainte
00155     for( obj = (*cons)->expr.begin(); obj != (*cons)->expr.end(); ++obj )
00156     {
00157         cour = table.find((*obj)->var);
00158         //on regarde si la variable existe
00159         float coef = atof( (*obj)->num.data() );
00160         //on convertit le coefficient "texte" en float
00161         coef = ((*obj)->signe?coef:-coef);
00162         //on change son signe au cas ou il y ait "-" devant
00163         if( cour != table.end()  )
00164         {
00165               tmp.ASS(coef,(cour->second));
00166               //On ajoute le tout à l'expression temporaire si elle existe
00167         }
00168         else
00169         {
00170             NumVar x(m,0,Infinity,MuteVar::FLOAT,(*obj)->var);
00171             table[(*obj)->var] = x;
00172             //sinon on la crée et on la répertorie
00173             tmp.ASS(coef,x);
00174             //et on ajoute le tout à l'expression temporaire si elle existe
00175         }
00176     }
00177 
00178     float coef = atof( (*cons)->cont.bound.data() );
00179     //on extrait le second membre de contrainte "texte"
00180 
00181     //suivant son type on l'ajoute au modele avec le bon operateur
00182     switch((*cons)->cont.comp)
00183     {
00184         case 0:
00185             m.Add( tmp <= coef, (*cons)->nom );
00186         break;
00187         case 1:
00188             m.Add( tmp < coef, (*cons)->nom);
00189         break;
00190         case 2:
00191             m.Add( tmp >= coef,(*cons)->nom );
00192         break;
00193         case 3:
00194             m.Add( tmp > coef, (*cons)->nom);
00195         break;
00196         case 4:
00197             m.Add( tmp != coef,(*cons)->nom );
00198         break;
00199         case 5:
00200             m.Add( tmp == coef, (*cons)->nom);
00201         break;
00202         default:
00203             cerr << endl <<"Warning in FichierProbleme::>> : undefined constraint type" << endl;
00204         break;
00205     }
00206   }
00207   cerr << "[OK]" << endl;
00208 
00209   cerr << "Bounds";
00210   //Pour chaque borne
00211   for( ; bou != exprBounds.end(); ++bou )
00212   {
00213     cour = table.find( (*bou)->var );
00214     //on regarde si la variable existe
00215     if( cour == table.end() )
00216     {
00217         NumVar x(m,0,Infinity,MuteVar::FLOAT,(*bou)->var);
00218         table[(*bou)->var] = x;
00219         //sinon on la crée et on la répertorie
00220         tmp = x;
00221         //on la considere comme une expression
00222     }
00223     else
00224        tmp = cour->second;
00225        //on la considere comme une expression
00226 
00227      float lB=0,uB=0;
00228     
00229      //si la borne inférieur est l'infini
00230      if( (*bou)->minBound == "-inf" || (*bou)->minBound == "-Inf")
00231         lB = -Infinity;
00232         //on la definit avec l'infini du modele
00233      else
00234         lB = atof( (*bou)->minBound.data() );
00235         //si on extrait sa valeur de sa représentation texte
00236     
00237      //si la borne supérieur est l'infini
00238      if( (*bou)->maxBound == "+inf" || (*bou)->maxBound == "Inf")
00239         uB = Infinity;
00240         //on la definit avec l'infini du modele
00241      else
00242         uB = atof( (*bou)->maxBound.data() );
00243         //si on extrait sa valeur de sa représentation texte
00244     
00245      ConstraintBuilder constraint;
00246      //on declare un constructeur de contrainte
00247     
00248      //on regarde le type de borne à gauche et on crée la bornes en conséquence
00249      switch( (*bou)->comp1 )
00250      {
00251           case 0:
00252               constraint = lB <=  tmp;
00253           break;
00254           case 1:
00255               constraint = lB <  tmp;
00256           break;
00257           case 2:
00258               constraint =  lB >= tmp ;
00259           break;
00260           case 3:
00261               constraint = lB > tmp;
00262           break;
00263           case 4:
00264               constraint = lB !=  tmp;
00265           break;
00266           case 5:
00267               constraint = lB ==  tmp;
00268           break;
00269           default:
00270               cerr << endl << "Warning in FichierProbleme::>> : undefined bounds type" << endl;
00271           break;
00272      }
00273     
00274      //on regarde le type de borne à droite et on crée la bornes en conséquence
00275      switch( (*bou)->comp2 )
00276      {
00277           case 0:
00278               constraint <= uB ;
00279           break;
00280           case 1:
00281               constraint < uB ;
00282           break;
00283           case 2:
00284               constraint >= uB ;
00285           break;
00286           case 3:
00287               constraint > uB ;
00288           break;
00289            case 4:
00290               constraint != uB ;
00291           break;
00292           case 5:
00293              constraint == uB ;
00294           break;
00295           case 99:
00296     
00297           break;
00298           default:
00299               cerr << endl << "Warning in FichierProbleme::>> : undefined bounds type" << endl;
00300           break;
00301     }
00302     
00303      m.Add( constraint );
00304      //On l'ajoute au modele
00305   }
00306   cerr << "[OK]" << endl;
00307   cerr << "Comments";
00308   
00309   list<pair<long,string> >::iterator comment =  commentaires.begin();
00310   for( ; comment != commentaires.end(); ++comment )
00311   {
00312 
00313     if( comment->first == 0 )
00314     {
00315       string name = m.GetProblemName();
00316       if( name.size() == 0 )
00317       {
00318         comment->second.erase( comment->second.begin() );
00319         m.SetProblemName( comment->second );
00320       }
00321       else
00322       {
00323         m.SetProblemName( name + "\n" + comment->second );
00324       }
00325     }
00326     else
00327     {
00328       string tmp = m.GetComment( comment->first );
00329       if( tmp.size() == 0 )
00330         {
00331             m.SetComment( comment->first, comment->second );
00332         }
00333         else
00334         {
00335             m.SetComment( comment->first, tmp + "\n" + comment->second );
00336         }
00337     }
00338   }
00339 
00340   cerr << "[OK]" << endl;
00341   cerr << "Loading Complete";
00342 
00343   return true;
00344 }
00345 
00346 }

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