00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "nel/ai/fuzzy/fuzzyvar.h"
00027 #include "nel/ai/script/compilateur.h"
00028 #include "nel/ai/script/constraint.h"
00029 #include "nel/ai/script/type_def.h"
00030 #include "nel/ai/agent/agent.h"
00031 #include "nel/ai/agent/agent_digital.h"
00032 #include "nel/ai/fuzzy/fuzzycond.h"
00033
00034 namespace NLAIFUZZY
00035 {
00036 using namespace NLAIAGENT;
00037
00038 CFuzzyVar::CFuzzyVar(const NLAIAGENT::IVarName &name, double min, double max, NLAIAGENT::IObjetOp *value) : IBaseVar(name)
00039 {
00040 if ( value )
00041 _Value = ((NLAIAGENT::INombre<double> *)value)->getValue();
00042 else
00043 _Value = 0;
00044
00045 _Min = min;
00046 _Max = max;
00047 }
00048
00049 CFuzzyVar::CFuzzyVar(const NLAIAGENT::IVarName &name, double min, double max, double value) : IBaseVar(name)
00050 {
00051 _Value = value;
00052 _Min = min;
00053 _Max = max;
00054 }
00055
00056 CFuzzyVar::CFuzzyVar(const CFuzzyVar &cp) : IBaseVar( cp )
00057 {
00058 _Value = cp._Value;
00059 _Min = cp._Min;
00060 _Max = cp._Max;
00061 }
00062
00063 CFuzzyVar::~CFuzzyVar()
00064 {
00065
00066 std::vector<IFuzzySet *>::const_iterator it_fs = _sets.begin();
00067 while ( it_fs != _sets.end() )
00068 {
00069 ( *it_fs )->release();
00070 it_fs++;
00071 }
00072
00073 std::vector<CFuzzyFact *>::const_iterator it_f = _facts.begin();
00074 while ( it_f != _facts.end() )
00075 {
00076 ( *it_f )->release();
00077 it_f++;
00078 }
00079
00080 std::vector<NLAIAGENT::CStringVarName *>::const_iterator it_q = _qual.begin();
00081 while ( it_q != _qual.end() )
00082 {
00083 ( *it_q )->release();
00084 it_q++;
00085 }
00086 }
00087
00088 void CFuzzyVar::addSet(IFuzzySet *my_set, char *set_name)
00089 {
00090 _sets.push_back(my_set);
00091 my_set->incRef();
00092 NLAIAGENT::CStringVarName *qual = new NLAIAGENT::CStringVarName( set_name );
00093 _qual.push_back( qual );
00094 }
00095
00096 std::list<CFuzzyFact *> *CFuzzyVar::fuzzify(double val)
00097 {
00098 std::list<CFuzzyFact *> *result = new std::list<CFuzzyFact *>;
00099 for ( sint32 i = 0; i < (sint32) _sets.size(); i++ )
00100 {
00101 if ( _sets[i]->isIn( val ) )
00102 {
00103 result->push_back( new CFuzzyFact( _sets[i], _sets[i]->membership(val) ) );
00104 }
00105 }
00106 return result;
00107 }
00108
00109 double CFuzzyVar::unfuzify()
00110 {
00111 double total_membership = 0.0;
00112 double set_membership;
00113 double set_center;
00114
00115 _Value = 0.0;
00116 for( sint32 i = 0; i < (sint32) _sets.size() ; i++ )
00117 {
00118 set_membership = _sets[i]->agregate();
00119 if ( set_membership )
00120 {
00121 set_center = _sets[i]->center();
00122 _Value = _Value + set_membership * set_center;
00123 total_membership = total_membership + set_membership;
00124 }
00125 }
00126
00127 if ( total_membership > 0 )
00128 _Value = _Value / total_membership;
00129 else
00130 _Value = 0;
00131
00132 return _Value;
00133 }
00134
00135 void CFuzzyVar::addFact(CFuzzyFact *f)
00136 {
00137 _facts.push_back(f);
00138 }
00139
00140 IFuzzySet *CFuzzyVar::getSet(char *name)
00141 {
00142 std::vector<IFuzzySet *>::iterator it_set = _sets.begin();
00143 while ( it_set != _sets.end() )
00144 {
00145 if ( !strcmp( (*it_set) ->getName(), name) )
00146 return *it_set;
00147 it_set++;
00148 }
00149 return NULL;
00150 }
00151
00152 void CFuzzyVar::addFact(char *set_name, double membership)
00153 {
00154 IFuzzySet *set = getSet( set_name );
00155 if ( set )
00156 _facts.push_back( new CFuzzyFact(set, membership) );
00157 }
00158
00159 void CFuzzyVar::setValue(NLAIAGENT::IObjetOp *obj)
00160 {
00161 _Value = ((NLAIAGENT::INombre<double> *)obj)->getValue();
00162 }
00163
00164 void CFuzzyVar::setValue(float value)
00165 {
00166 _Value = value;
00167 }
00168
00169 NLAIAGENT::IObjetOp *CFuzzyVar::getValue() const
00170 {
00171 return new NLAIAGENT::DigitalType( (float) _Value );
00172 }
00173
00174 const NLAIC::IBasicType *CFuzzyVar::clone() const
00175 {
00176 CFuzzyVar *clone = new CFuzzyVar(*this);
00177 return clone;
00178 }
00179
00180 const NLAIC::IBasicType *CFuzzyVar::newInstance() const
00181 {
00182 NLAIAGENT::CStringVarName x("Inst");
00183 CFuzzyVar *instance = new CFuzzyVar(x,0,0);
00184 return instance;
00185 }
00186
00187 void CFuzzyVar::save(NLMISC::IStream &os)
00188 {
00189 IObjectIA::save(os);
00190 os.serial( (double &) _Value );
00191 os.serial( (double &) _Min );
00192 os.serial( (double &) _Max );
00193 sint32 size = _sets.size();
00194 os.serial( size );
00195 for (sint32 i = 0; i < size; i++ )
00196 {
00197 _sets[i]->save(os);
00198 }
00199 }
00200
00201 void CFuzzyVar::load(NLMISC::IStream &is)
00202 {
00203 IObjectIA::load( is );
00204
00205 is.serial( _Value );
00206 is.serial( _Min );
00207 is.serial( _Max );
00208
00209 sint32 nb_sets;
00210 is.serial( nb_sets );
00211 for (sint32 i = 0; i < nb_sets; i++ )
00212 {
00213 NLAIC::CIdentTypeAlloc id;
00214 is.serial( id );
00215 IFuzzySet *tmp_val = (IFuzzySet *) id.allocClass();
00216 tmp_val->load( is );
00217 _sets.push_back( tmp_val );
00218 }
00219 }
00220
00221 void CFuzzyVar::getDebugString(std::string &txt) const
00222 {
00223 txt += NLAIC::stringGetBuild("CFuzzyVar<%s> = %f\n", getName().getString(), _Value);
00224 for(sint32 i = 0; i < (sint32) _sets.size(); i++)
00225 {
00226 if ( _sets[i]->isIn( _Value ) )
00227 {
00228 std::string buf;
00229 _sets[i]->getDebugString(buf);
00230 txt += NLAIC::stringGetBuild(" %s %f\n", buf.c_str(), _sets[i]->membership( _Value ) );
00231 }
00232 }
00233 }
00234
00235 bool CFuzzyVar::isEqual(const CFuzzyVar &a) const
00236 {
00237 return _Value == a._Value;
00238 }
00239
00240 bool CFuzzyVar::isEqual(const NLAIAGENT::IBasicObjectIA &a) const
00241 {
00242 return _Value == ((CFuzzyVar &)a)._Value;
00243 }
00244
00245 bool CFuzzyVar::isTrue() const
00246 {
00247 return false;
00248 }
00249
00250 const NLAIC::CIdentType &CFuzzyVar::getType() const
00251 {
00252 return IdFuzzyVar;
00253 }
00254
00255 bool CFuzzyVar::operator==(NLAILOGIC::IBaseVar *var)
00256 {
00257 return false;
00258 }
00259
00260 bool CFuzzyVar::unify(NLAILOGIC::IBaseVar *, bool assign)
00261 {
00262 return false;
00263 }
00264
00265 bool CFuzzyVar::unify(NLAIAGENT::IObjetOp *, bool assign)
00266 {
00267 return false;
00268 }
00269
00270 NLAIAGENT::IObjetOp *CFuzzyVar::operator == (NLAIAGENT::IObjetOp &a) const
00271 {
00272 return NULL;
00273 }
00274
00275 const NLAIAGENT::IObjectIA::CProcessResult &CFuzzyVar::run()
00276 {
00277 return IObjectIA::ProcessRun;
00278 }
00279
00280 bool CFuzzyVar::isIn(IFuzzySet *my_set)
00281 {
00282 return my_set->isIn(_Value);
00283 }
00284
00285 float CFuzzyVar::membership(IFuzzySet *my_set)
00286 {
00287 return (float) my_set->membership( _Value);
00288 }
00289
00290 CSimpleFuzzyCond *CFuzzyVar::getCond(char *name)
00291 {
00292 IFuzzySet *my_set = getSet( name );
00293 if ( my_set )
00294 {
00295 return new CSimpleFuzzyCond( this, my_set );
00296 }
00297 else
00298 return NULL;
00299 }
00300
00301 sint32 CFuzzyVar::getMethodIndexSize() const
00302 {
00303 return IObjetOp::getMethodIndexSize() + 2;
00304 }
00305
00306
00307 IObjectIA::CProcessResult CFuzzyVar::runMethodeMember(sint32 id, IObjectIA *params)
00308 {
00309 if ( id <= IBaseVar::getMethodIndexSize() )
00310 return IBaseVar::runMethodeMember(id, params);
00311
00312 IObjectIA::CProcessResult r;
00313
00314 std::string buf;
00315 NLAIAGENT::IObjetOp *x= NULL;
00316 if ( ( (NLAIAGENT::IBaseGroupType *) params)->size() )
00317 {
00318 ( ((NLAIAGENT::IBaseGroupType *)params))->popFront();
00319
00320 #ifdef NL_DEBUG
00321 x->getDebugString(buf);
00322 #endif
00323 }
00324 #ifdef NL_DEBUG
00325 getDebugString(buf);
00326 #endif
00327
00328 sint32 base = IBaseVar::getMethodIndexSize();
00329 sint32 op_add_subset = base+1;
00330 sint32 op_unfuzify = base+2;
00331
00332 if ( id == op_add_subset )
00333 {
00334 addSet( (IFuzzySet *) x, ((IFuzzySet *)x)->getName());
00335 r.ResultState = NLAIAGENT::processIdle;
00336 r.Result = NULL;
00337 }
00338
00339
00340 if ( id == op_unfuzify )
00341 {
00342 unfuzify();
00343 IObjectIA::CProcessResult r;
00344 r.ResultState = NLAIAGENT::processIdle;
00345 r.Result = new NLAIAGENT::DigitalType( (float) _Value);
00346 }
00347
00348
00349 return r;
00350 }
00351
00352 IObjectIA::CProcessResult CFuzzyVar::runMethodeMember(sint32 inheritance, sint32 id, IObjectIA *params)
00353 {
00354 return runMethodeMember(id,params);
00355 }
00356
00357
00358 void CFuzzyVar::init(IObjectIA *p)
00359 {
00360 NLAIAGENT::IBaseGroupType *params = ((NLAIAGENT::IBaseGroupType *)p);
00361
00362 if ( params->size() < 2 )
00363 {
00364
00365 }
00366
00367
00368 IObjectIA * arg = (IObjectIA *) params->popFront();
00369 strcpy(_Name, ((NLAIAGENT::IVarName *) arg)->getString() );
00370
00371
00372 while ( params->size() )
00373 {
00374 IFuzzySet *set = (IFuzzySet *) params->getFront()->clone();
00375 addSet( set, set->getName() );
00376 params->popFront();
00377 }
00378 }
00379
00380
00381 tQueue CFuzzyVar::isMember(const NLAIAGENT::IVarName *className,const NLAIAGENT::IVarName *name,const IObjectIA ¶m) const
00382 {
00383 tQueue result;
00384
00385 result = IBaseVar::isMember(className, name, param);
00386
00387 if ( result.size() )
00388 return result;
00389
00390 if(className != NULL)
00391 {
00392 if ( *name == CStringVarName( _ADDSUBSET_ ) )
00393 {
00394 IObjectIA *op_type = (IObjectIA *) new NLAISCRIPT::COperandVoid();
00395 result.push( NLAIAGENT::CIdMethod(1 + IObjetOp::getMethodIndexSize(), 0.0,NULL, op_type ) );
00396 }
00397 if ( *name == CStringVarName(_UNFUZIFY_) )
00398 {
00399 IObjectIA *op_type = (IObjectIA *) new NLAISCRIPT::COperandSimple( new NLAIC::CIdentType( DigitalType::IdDigitalType) );
00400 result.push( NLAIAGENT::CIdMethod(2 + IObjetOp::getMethodIndexSize(), 0.0, NULL, op_type ) );
00401 }
00402 }
00403 return result;
00404 }
00405 }