00001 #ifndef __FAMILY_H
00002 #define __FAMILY_H
00003
00004 #include "MuteVar.h"
00005 #include "Ensemble.h"
00006 #include "Expr.h"
00007
00008 #include <string>
00009 #include <sstream>
00010 #include <vector>
00011
00012 class Model;
00013
00017 template<unsigned N,typename T>
00018 struct Nuplet
00019 {
00020 T tableau[N];
00021
00023 T & operator[] (unsigned n)
00024 {
00025 if(n<N)
00026 return tableau[n];
00027 else
00028 throw domain_error("Nuplet::operator[] : argument is out of range");
00029 }
00030
00032 T operator[] (unsigned n) const
00033 {
00034 if(n<N)
00035 return tableau[n];
00036 else
00037 throw domain_error("Nuplet::operator[] : argument is out of range");
00038 }
00039
00041 Nuplet() {}
00042
00044 Nuplet( const Nuplet & n) { *this = n; }
00045
00047 Nuplet & operator=(const Nuplet &n)
00048 {
00049 if( this != &n)
00050 for(unsigned i=0; i <N;++i)
00051 tableau[i] = n.tableau[i];
00052 return *this;
00053 }
00054
00056 ~Nuplet() {}
00057
00058 };
00059
00066 template <unsigned N,typename T>
00067 std::ostream & operator<< (std::ostream & flux,const Nuplet<N,T> & nuplet)
00068 {
00069 flux << "( ";
00070 for( unsigned i = 0; i < N; ++i)
00071 {
00072 flux << nuplet.tableau[i] << " ";
00073 }
00074 flux << ")";
00075 return flux;
00076 }
00077
00084 template <unsigned N,typename T>
00085 std::istream & operator>> (std::istream & flux, Nuplet<N,T> & nuplet)
00086 {
00087 for( unsigned i = 0; i < N; ++i)
00088 {
00089 flux >> nuplet.tableau[i];
00090 }
00091 return flux;
00092 }
00093
00095 template <unsigned I, unsigned N,typename T>
00096 struct Omega: public Propriete< Nuplet<N,T> >
00097 {
00098 T m;
00100 Omega(T _m):m(_m) {}
00102 bool operator() (const Nuplet<N,T> & n) const
00103 {
00104 return( n.tableau[I] == m );
00105 }
00106 };
00107
00109
00114 template <unsigned N, typename T>
00115 class NumVarFamily
00116 {
00117 std::vector<NumVar> variables;
00118 typedef Nuplet<N,T> Nuplet_T;
00119 std::string GetNameNumVar(const std::string & format, const Nuplet_T & nuplet) const
00120 {
00121 unsigned j=0;
00122 std::ostringstream name("");
00123 for(unsigned i = 0; i < N; ++i)
00124 {
00125 while( j < format.length() && format[j] != '%' )
00126 {
00127 name << format[j];
00128 ++j;
00129 }
00130 if( j < format.length() )
00131 ++j;
00132 name << nuplet.tableau[i];
00133 }
00134 while( j < format.length() )
00135 {
00136 name << format[j];
00137 ++j;
00138 }
00139 return name.str();
00140 }
00141
00142 public:
00143
00144 Ensemble< Nuplet_T > indices;
00145
00146
00156 NumVarFamily(Model & m,
00157 float lb,
00158 float ub,
00159 MuteVar::VarType type,
00160 const Ensemble< Nuplet_T > & ensemble,
00161 const string &format)
00162 {
00163 indices = ensemble;
00164 for(unsigned i =0; i < ensemble.Size(); ++i)
00165 {
00166 std::string name = GetNameNumVar(format,ensemble.Get(i));
00167 variables.push_back( NumVar(m,lb,ub,type,name) );
00168 }
00169 }
00170
00175 std::vector<NumVar> GetFamilyPart( const Propriete< Nuplet<N,T> > & propriete)
00176 {
00177 return GetFamilyPart( indices.partie(propriete) );
00178 }
00179
00184 std::vector<NumVar> GetFamilyPart( const typename Ensemble< Nuplet_T >::Partie & p)
00185 {
00186 std::vector<NumVar> retour;
00187 std::list<unsigned> liste = p.GetIds();
00188 for( std::list<unsigned>::iterator iter = liste.begin(); iter != liste.end(); ++iter )
00189 {
00190 retour.push_back( variables[*iter] );
00191 }
00192 return retour;
00193 }
00194
00199 NumVar Get(unsigned i) const { return variables[i];}
00202 unsigned Size() const { return variables.size();}
00203 };
00204
00205
00207 template <unsigned N, typename T>
00208 class IntVarFamily: public NumVarFamily<N,T>
00209 {
00210 public:
00211 #ifndef COMPILE_FOR_PYTHON
00212 IntVarFamily( Model &_modele,
00213 int _lb,
00214 int _ub,
00215 const Ensemble< Nuplet<N,T> > & ensemble,
00216 const std::string & nom )
00217 :NumVarFamily<N, T>( _modele,static_cast<float>(_lb),static_cast<float>(_ub),MuteVar::INT,ensemble,nom) {}
00218 #else
00219 IntVarFamily( Model &_modele,
00220 float _lb,
00221 float _ub,
00222 const Ensemble< Nuplet<N,T> > & ensemble,
00223 const std::string & nom )
00224 :NumVarFamily<N,T>( _modele,_lb,_ub,MuteVar::INT,ensemble,nom) {}
00225 #endif
00226 };
00227
00229 template <unsigned N, typename T>
00230 class FloatVarFamily: public NumVarFamily<N,T>
00231 {
00232 public:
00233 FloatVarFamily( Model &_modele,
00234 float _lb,
00235 float _ub,
00236 const Ensemble< Nuplet<N,T> > & ensemble,
00237 const std::string & nom )
00238 :NumVarFamily<N,T>( _modele,_lb,_ub,MuteVar::FLOAT,ensemble,nom) {}
00239 };
00240
00242 template <unsigned N, typename T>
00243 class BoolVarFamily: public NumVarFamily<N,T>
00244 {
00245 public:
00246 BoolVarFamily( Model &_modele,
00247 const Ensemble< Nuplet<N,T> > & ensemble,
00248 const std::string & nom )
00249 :NumVarFamily<N,T>( _modele,0.0f,1.0f,MuteVar::BOOL,ensemble,nom) {}
00250 };
00251
00252
00253
00254 #define Couple Nuplet<2,unsigned>
00255 #define Triplet Nuplet<3,unsigned>
00256
00257 #define CoupleFloatVarFamily FloatVarFamily<2,unsigned>
00258 #define CoupleIntVarFamily IntVarFamily<2,unsigned>
00259
00260 #define TripletFloatVarFamily FloatVarFamily<3,unsigned>
00261 #define TripletIntVarFamily IntVarFamily<3,unsigned>
00262
00263 #ifdef COMPILE_FOR_PYTHON
00264 void export_Family();
00265 #endif
00266
00267
00268 #endif