Modelib: Fichier source de NumVarFamily.h

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

# NumVarFamily.h

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 #ifndef __FAMILY_H
    00033 #define __FAMILY_H
    00034
    00035 #include "MuteVar.h"
    00036 #include "Ensemble.h"
    00037 #include "Expr.h"
    00038
    00039 #include <string>
    00040 #include <sstream>
    00041 #include <vector>
    00042
    00043 namespace Modelib {
    00044
    00045 class Model;
    00046
    00050 template<unsigned N,typename T>
    00051 struct Nuplet
    00052 {
    00053    T tableau[N];
    00054
    00056    T & operator[] (unsigned n)
    00057    {
    00058         if(n<N)
    00059             return tableau[n];
    00060         else
    00061             throw domain_error("Nuplet::operator[] : argument is out of range");
    00062     }
    00063
    00065   T operator[] (unsigned n) const
    00066    {
    00067         if(n<N)
    00068             return tableau[n];
    00069         else
    00070             throw domain_error("Nuplet::operator[] : argument is out of range");
    00071     }
    00072
    00074     Nuplet() {}
    00075
    00077     Nuplet( const Nuplet & n) { *this = n; }
    00078
    00080     Nuplet & operator=(const Nuplet &n)
    00081     {
    00082         if( this != &n)
    00083             for(unsigned i=0; i <N;++i)
    00084                 tableau[i] = n.tableau[i];
    00085         return *this;
    00086     }
    00087
    00089     ~Nuplet() {}
    00090
    00091 };
    00092
    00099 template <unsigned N,typename T>
    00100 std::ostream & operator<< (std::ostream & flux,const Nuplet<N,T> & nuplet)
    00101 {
    00102    flux << "( ";
    00103    for( unsigned i = 0; i < N; ++i)
    00104    {
    00105        flux << nuplet.tableau[i] << " ";
    00106    }
    00107    flux << ")";
    00108    return flux;
    00109 }
    00110
    00117 template <unsigned N,typename T>
    00118 std::istream & operator>> (std::istream & flux, Nuplet<N,T> & nuplet)
    00119 {
    00120    for( unsigned i = 0; i < N; ++i)
    00121    {
    00122        flux >> nuplet.tableau[i];
    00123    }
    00124    return flux;
    00125 }
    00126
    00128 template <unsigned I, unsigned N,typename T>
    00129 struct Omega: public Propriete< Nuplet<N,T> >
    00130 {
    00131   T m;
    00133   Omega(T _m):m(_m)  {}
    00135   bool operator() (const Nuplet<N,T> & n) const
    00136   {
    00137      return( n.tableau[I] == m );
    00138   }
    00139 };
    00140
    00142
    00147 template <unsigned N, typename T>
    00148 class NumVarFamily
    00149 {
    00150    std::vector<NumVar> variables;
    00151    typedef Nuplet<N,T> Nuplet_T;
    00152    std::string GetNameNumVar(const std::string & format, const Nuplet_T & nuplet) const
    00153    {
    00154         unsigned j=0;
    00155         std::ostringstream name("");
    00156         for(unsigned i = 0; i < N; ++i)
    00157         {
    00158             while( j < format.length() &&  format[j] != '%' )
    00159             {
    00160                 name << format[j];
    00161                 ++j;
    00162             }
    00163             if( j < format.length() )
    00164               ++j;
    00165             name << nuplet.tableau[i];
    00166         }
    00167         while( j < format.length() )
    00168         {
    00169            name << format[j];
    00170            ++j;
    00171         }
    00172         return name.str();
    00173    }
    00174
    00175   public:
    00176
    00177     Ensemble< Nuplet_T > indices;
    00178
    00179
    00189     NumVarFamily(Model & m,
    00190            float lb,
    00191            float ub,
    00192            MuteVar::VarType type,
    00193            const Ensemble< Nuplet_T > & ensemble,
    00194            const string &format)
    00195     {
    00196         indices = ensemble;
    00197         for(unsigned i =0; i < ensemble.Size(); ++i)
    00198         {
    00199            std::string name =  GetNameNumVar(format,ensemble.Get(i));
    00200            variables.push_back( NumVar(m,lb,ub,type,name) );
    00201         }
    00202     }
    00203
    00208     std::vector<NumVar> GetFamilyPart( const Propriete< Nuplet<N,T> > & propriete)
    00209     {
    00210         return GetFamilyPart( indices.partie(propriete) );
    00211     }
    00212
    00217    std::vector<NumVar> GetFamilyPart( const typename Ensemble< Nuplet_T >::Partie & p)
    00218     {
    00219         std::vector<NumVar> retour;
    00220         std::list<unsigned> liste = p.GetIds();
    00221         for( std::list<unsigned>::iterator iter = liste.begin(); iter != liste.end(); ++iter )
    00222         {
    00223                 retour.push_back( variables[*iter] );
    00224         }
    00225         return retour;
    00226     }
    00227
    00232     NumVar Get(unsigned i) const { return variables[i];}
    00235     unsigned Size() const { return variables.size();}
    00236 };
    00237
    00238 /*--------------------------------------------------------------------------------------------*/
    00240 template <unsigned N, typename T>
    00241 class IntVarFamily: public NumVarFamily<N,T>
    00242 {
    00243   public:
    00244 #ifndef COMPILE_FOR_PYTHON
    00245    IntVarFamily( Model &_modele,
    00246               int _lb,
    00247               int _ub,  // ou MaxInt à voir
    00248               const Ensemble< Nuplet<N,T> > & ensemble,
    00249               const std::string & nom )
    00250    :NumVarFamily<N, T>( _modele,static_cast<float>(_lb),static_cast<float>(_ub),MuteVar::INT,ensemble,nom) {}
    00251 #else
    00252     IntVarFamily( Model &_modele,
    00253                float _lb,
    00254                float _ub,
    00255                const Ensemble< Nuplet<N,T> > & ensemble,
    00256                const std::string & nom )
    00257     :NumVarFamily<N,T>( _modele,_lb,_ub,MuteVar::INT,ensemble,nom) {}
    00258 #endif
    00259 };
    00260
    00262 template <unsigned N, typename T>
    00263 class FloatVarFamily: public NumVarFamily<N,T>
    00264 {
    00265   public:
    00266     FloatVarFamily( Model &_modele,
    00267                    float _lb,
    00268                    float _ub,
    00269                    const Ensemble< Nuplet<N,T> > & ensemble,
    00270                    const std::string & nom )
    00271     :NumVarFamily<N,T>( _modele,_lb,_ub,MuteVar::FLOAT,ensemble,nom) {}
    00272 };
    00273
    00275 template <unsigned N, typename T>
    00276 class BoolVarFamily: public NumVarFamily<N,T>
    00277 {
    00278   public:
    00279     BoolVarFamily( Model &_modele,
    00280                 const Ensemble< Nuplet<N,T> > & ensemble,
    00281                 const std::string & nom )
    00282     :NumVarFamily<N,T>( _modele,0.0f,1.0f,MuteVar::BOOL,ensemble,nom) {}
    00283 };
    00284
    00285 //Ce qui suit est normalement fortement déconseillé en C++
    00286 //Néanmoins, à cause d'un problème de typename, typedef est inutilisable
    00287 #define Couple Nuplet<2,unsigned>
    00288 #define Triplet Nuplet<3,unsigned>
    00289
    00290 #define CoupleFloatVarFamily  FloatVarFamily<2,unsigned>
    00291 #define CoupleIntVarFamily    IntVarFamily<2,unsigned>
    00292
    00293 #define TripletFloatVarFamily  FloatVarFamily<3,unsigned>
    00294 #define TripletIntVarFamily    IntVarFamily<3,unsigned>
    00295
    00296 #ifdef COMPILE_FOR_PYTHON
    00297     void export_Family();
    00298 #endif
    00299
    00300
    00301 }
    00302
    00303 #endif