Modelib: Fichier source de FichierProbleme.cpp

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 }