00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "nel/ai/nimat/classifier.h"
00027 #include "nel/misc/debug.h"
00028
00029 namespace NLAINIMAT
00030 {
00031
00033
00035
00036 CClassifierSystem::CClassifierSystem()
00037 {
00038 }
00039
00040 CClassifierSystem::~CClassifierSystem()
00041 {
00042 std::list<CClassifier*>::iterator itClassifiers = _classifiers.begin();
00043 while (itClassifiers != _classifiers.end())
00044 {
00045 delete (*itClassifiers);
00046 itClassifiers++;
00047 }
00048 }
00049
00050 void CClassifierSystem::addClassifier(const TSensorMap &conditionsMap, sint16 priority, const char* behavior)
00051 {
00052
00053 CClassifier* classifier = new CClassifier();
00054 classifier->Behavior = behavior;
00055 classifier->Priority = priority;
00056
00057 CClassifierConditionCell* condCell;
00058 std::map<std::string, char>::const_iterator itCondition;
00059 for (itCondition = conditionsMap.begin(); itCondition != conditionsMap.end(); itCondition++)
00060 {
00061
00062 _sensors[(*itCondition).first] = '#';
00063
00064
00065 condCell = new CClassifierConditionCell(_sensors.find((*itCondition).first), (*itCondition).second);
00066 classifier->Condition.push_back(condCell);
00067 }
00068
00069
00070 _classifiers.push_back(classifier);
00071 }
00072
00074 void CClassifierSystem::addClassifierSystem(const CClassifierSystem &cs)
00075 {
00076 std::list<CClassifier*>::const_iterator itCSClassifiers;
00077 for (itCSClassifiers = cs._classifiers.begin(); itCSClassifiers != cs._classifiers.end(); itCSClassifiers++)
00078 {
00079 TSensorMap conditionsMap;
00080
00081 std::list<CClassifierConditionCell*>::const_iterator itCondCell;
00082 for (itCondCell = (*itCSClassifiers)->Condition.begin(); itCondCell !=(*itCSClassifiers)->Condition.end(); itCondCell++)
00083 {
00084 CClassifierConditionCell* pCondCell = (*itCondCell);
00085 conditionsMap[pCondCell->getSensorName()] = pCondCell->getValue();
00086 }
00087 addClassifier(conditionsMap, (*itCSClassifiers)->Priority, (*itCSClassifiers)->Behavior.c_str());
00088 }
00089 }
00090
00091 std::string CClassifierSystem::selectBehavior( const TSensorMap &sensorMap)
00092 {
00093
00094 std::map<std::string, char>::const_iterator itConditionsmap;
00095 for (itConditionsmap = sensorMap.begin(); itConditionsmap != sensorMap.end(); itConditionsmap++)
00096 {
00097 char c = (*itConditionsmap).second;
00098 std::string sensName = (*itConditionsmap).first;
00099 _sensors[sensName ] = c;
00100 int size = _sensors.size();
00101 }
00102
00103
00104 std::list<CClassifier*> activableList;
00105 std::list<CClassifier*>::iterator itClassifiers = _classifiers.begin();
00106 std::list<CClassifierConditionCell*>::iterator itConditions;
00107 bool activable;
00108 int totalPriority = 0;
00109
00110 while (itClassifiers != _classifiers.end())
00111 {
00112 activable = true;
00113 itConditions = (*itClassifiers)->Condition.begin();
00114 while (itConditions != (*itClassifiers)->Condition.end())
00115 {
00116 if (! (*itConditions)->isActivable() )
00117 {
00118 activable = false;
00119 break;
00120 }
00121 itConditions++;
00122 }
00123 if (activable)
00124 {
00125 activableList.push_back(*itClassifiers);
00126 totalPriority += (*itClassifiers)->Priority;
00127 }
00128 itClassifiers++;
00129 }
00130
00131
00132 for (itConditionsmap = sensorMap.begin(); itConditionsmap != sensorMap.end(); itConditionsmap++)
00133 {
00134 char c = (*itConditionsmap).second;
00135 std::string sensName = (*itConditionsmap).first;
00136 _sensors[sensName ] = '#';
00137 int size = _sensors.size();
00138 }
00139
00140
00141 int r = rand() * totalPriority;
00142 r /= RAND_MAX;
00143 itClassifiers = activableList.begin();
00144 while (itClassifiers != activableList.end())
00145 {
00146 r -= (*itClassifiers)->Priority;
00147 if (r<=0)
00148 {
00149 return (*itClassifiers)->Behavior;
00150 }
00151 itClassifiers++;
00152 }
00153
00154
00155 return "#";
00156 }
00157
00158 void CClassifierSystem::getDebugString(std::string &t) const
00159 {
00160 std::string dbg = "\n";
00161
00162 std::list<CClassifier*>::const_iterator itClassifiers;
00163 for (itClassifiers = _classifiers.begin(); itClassifiers != _classifiers.end(); itClassifiers++)
00164 {
00165 std::list<CClassifierConditionCell*>::const_iterator itConditions;
00166 for (itConditions = (*itClassifiers)->Condition.begin(); itConditions != (*itClassifiers)->Condition.end(); itConditions++)
00167 {
00168 CClassifierConditionCell* condCell = (*itConditions);
00169 dbg += " (" + condCell->getSensorName() + "=" + condCell->getValue() + ") +";
00170 }
00171 std::string actionName = (*itClassifiers)->Behavior;
00172 sint16 prio = (*itClassifiers)->Priority;
00173 dbg += "> " + actionName + " [" + NLMISC::toString(prio) + "]\n";
00174 }
00175 t += dbg;
00176 }
00177
00179
00181
00182 CClassifierSystem::CClassifier::CClassifier()
00183 {
00184 }
00185
00186 CClassifierSystem::CClassifier::~CClassifier()
00187 {
00188 std::list<CClassifierConditionCell*>::iterator itConditions = Condition.begin();
00189 while (itConditions != Condition.end())
00190 {
00191 delete (*itConditions );
00192 itConditions++;
00193 }
00194 }
00195
00197
00199
00200 CClassifierSystem::CClassifierConditionCell::CClassifierConditionCell(TSensorMap::const_iterator itSensor, char value)
00201 {
00202 _itSensor = itSensor;
00203 _value = value;
00204 }
00205
00206 bool CClassifierSystem::CClassifierConditionCell::isActivable() const
00207 {
00208 if ((*_itSensor).second == _value)
00209 return true;
00210 else
00211 return false;
00212 }
00213
00214 std::string CClassifierSystem::CClassifierConditionCell::getSensorName() const
00215 {
00216 return (*_itSensor).first;
00217 }
00218
00219 char CClassifierSystem::CClassifierConditionCell::getValue()
00220 {
00221 return _value;
00222 }
00223
00225
00227
00228 {
00229 _Name = name;
00230 }
00231
00232 CActionCS::~CActionCS()
00233 {
00234 }
00235
00237 std::string CActionCS::getName() const
00238 {
00239 return _Name;
00240 }
00241
00243 void CActionCS::addMotivationRule (std::string motivationName, const TSensorMap &conditionsMap, sint16 priority)
00244 {
00245 CClassifierSystem* pCS;
00246
00247 pCS = &(_ClassifiersByMotivation[motivationName]);
00248 pCS->addClassifier(conditionsMap, priority, _Name.c_str());
00249 }
00250
00251 const std::map<std::string, CClassifierSystem> *CActionCS::getClassifiersMap () const
00252 {
00253 return &_ClassifiersByMotivation;
00254 }
00255
00256
00258 void CActionCS::getDebugString(std::string &t) const
00259 {
00260 std::string ret = "\nACTION :\t" + _Name + "\n";
00261 std::map<std::string, CClassifierSystem>::const_iterator ItClassifiersByMotivation;
00262 for (ItClassifiersByMotivation = _ClassifiersByMotivation.begin(); ItClassifiersByMotivation != _ClassifiersByMotivation.end(); ItClassifiersByMotivation++)
00263 {
00264 ret += "\nMotivation : " + (*ItClassifiersByMotivation).first + "\n";
00265 (*ItClassifiersByMotivation).second.getDebugString(ret);
00266 }
00267 t+=ret;
00268 }
00269
00270
00272
00274
00275 {
00276 _SumValue = 0;
00277 }
00278
00279 CMotivationEnergy::~CMotivationEnergy()
00280 {
00281 }
00282
00283 sint16 CMotivationEnergy::getSumValue() const
00284 {
00285 return _SumValue;
00286 }
00287
00288 void CMotivationEnergy::removeProvider(std::string providerName)
00289 {
00290 _MotivationProviders.erase(providerName);
00291 computeMotivationValue();
00292 }
00293
00294 void CMotivationEnergy::addProvider(std::string providerName, const CMotivationEnergy& providerMotivation)
00295 {
00296 _MotivationProviders[providerName] = providerMotivation._EnergyByMotivation ;
00297 computeMotivationValue();
00298 }
00299
00300 void CMotivationEnergy::computeMotivationValue()
00301 {
00302 _EnergyByMotivation.clear();
00303 std::map<std::string, TEnergyByMotivation>::iterator itMotivationProviders;
00304
00305 for (itMotivationProviders = _MotivationProviders.begin(); itMotivationProviders != _MotivationProviders.end(); itMotivationProviders++)
00306 {
00307 TEnergyByMotivation &motivation = (*itMotivationProviders).second;
00308 TEnergyByMotivation::iterator itMotivation, itMyMotivation;
00309 for (itMotivation = motivation.begin(); itMotivation != motivation.end(); itMotivation++)
00310 {
00311 std::string motivSource = (*itMotivation).first;
00312 sint16 motiveValue = (*itMotivation).second.Value;
00313 sint16 motivePP = (*itMotivation).second.PP;
00314 itMyMotivation = _EnergyByMotivation.find(motivSource);
00315 if (itMyMotivation != _EnergyByMotivation.end())
00316 {
00317 sint16 myMotiveValue = (*itMyMotivation).second.Value;
00318 if (motiveValue > myMotiveValue)
00319 {
00320 _EnergyByMotivation[motivSource].Value = motiveValue;
00321 _EnergyByMotivation[motivSource].PP = motivePP;
00322 }
00323 }
00324 else
00325 {
00326 _EnergyByMotivation[motivSource].Value = motiveValue;
00327 _EnergyByMotivation[motivSource].PP = motivePP;
00328 }
00329 }
00330 }
00331
00332 TEnergyByMotivation::const_iterator itEnergyByMotivation;
00333 sint16 sum = 0;
00334 for (itEnergyByMotivation = _EnergyByMotivation.begin(); itEnergyByMotivation != _EnergyByMotivation.end(); itEnergyByMotivation++)
00335 {
00336 sum += (*itEnergyByMotivation).second.Value * (*itEnergyByMotivation).second.PP;
00337 }
00338 _SumValue = sum;
00339 }
00340
00342 void CMotivationEnergy::setMotivationPP(std::string motivationName, sint16 PP)
00343 {
00344 _SumValue -= _EnergyByMotivation[motivationName].Value * _EnergyByMotivation[motivationName].PP;
00345 _SumValue += _EnergyByMotivation[motivationName].Value * PP;
00346 _EnergyByMotivation[motivationName].PP = PP;
00347 }
00348
00350 void CMotivationEnergy::setMotivationValue(std::string motivationName, sint16 value)
00351 {
00352 _SumValue -= _EnergyByMotivation[motivationName].Value * _EnergyByMotivation[motivationName].PP;
00353 _SumValue += value * _EnergyByMotivation[motivationName].PP;
00354 _EnergyByMotivation[motivationName].Value = value;
00355 }
00356
00358 void CMotivationEnergy::getDebugString(std::string &t) const
00359 {
00360 std::string ret;
00361 TEnergyByMotivation::const_iterator itEnergyByMotivation;
00362
00363 for (itEnergyByMotivation = _EnergyByMotivation.begin(); itEnergyByMotivation!= _EnergyByMotivation.end(); itEnergyByMotivation++)
00364 {
00365 ret += " Motivation source : " + (*itEnergyByMotivation).first + " (" + NLMISC::toString((*itEnergyByMotivation).second.Value * (*itEnergyByMotivation).second.PP) + ")\n";
00366 }
00367 t+=ret;
00368 }
00369
00371
00373
00374 CNetCS::CNetCS()
00375 {
00376 }
00377
00378 CNetCS::~CNetCS()
00379 {
00380 }
00381
00382 void CNetCS::addVirtualActionCS(const CActionCS &action)
00383 {
00384 const std::map<std::string, CClassifierSystem> *mapAction = action.getClassifiersMap();
00385 std::map<std::string, CClassifierSystem>::const_iterator ItMapAction;
00386 for (ItMapAction = mapAction->begin(); ItMapAction != mapAction->end(); ItMapAction++)
00387 {
00388 CClassifierSystem* pCS;
00389 std::string motivationName = (*ItMapAction).first;
00390 const CClassifierSystem* pOtherCS = &((*ItMapAction).second);
00391
00392 pCS = &(_ClassifiersAndMotivationIntensity[motivationName].CS);
00393 pCS->addClassifierSystem(*pOtherCS);
00394 }
00395 }
00396
00397 void CNetCS::addActionCS(const CActionCS& action)
00398 {
00399 addVirtualActionCS(action);
00400 CMotivationEnergy motivalue;
00401 _ActionsExecutionIntensity[action.getName()] = motivalue;
00402 }
00403
00404
00406 void CNetCS::getDebugString(std::string &t) const
00407 {
00408 std::string ret = "\n---------------------------";
00409 std::map<std::string, CMotivateCS>::const_iterator itClassifiers;
00410 for (itClassifiers = _ClassifiersAndMotivationIntensity.begin(); itClassifiers!= _ClassifiersAndMotivationIntensity.end(); itClassifiers++)
00411 {
00412 ret += "\nMotivation : " + (*itClassifiers).first;
00413 (*itClassifiers).second.CS.getDebugString(ret);
00414 (*itClassifiers).second.MotivationIntensity.getDebugString(ret);
00415 }
00416 ret += "\nACTIONS :\n";
00417 std::map<std::string, CMotivationEnergy>::const_iterator itActionsExecutionIntensity;
00418 for (itActionsExecutionIntensity = _ActionsExecutionIntensity.begin(); itActionsExecutionIntensity != _ActionsExecutionIntensity.end(); itActionsExecutionIntensity++)
00419 {
00420 ret += (* itActionsExecutionIntensity).first + " :\n";
00421 (*itActionsExecutionIntensity).second.getDebugString(ret);
00422 }
00423 t+=ret;
00424 }
00425
00427 void CNetCS::setMotivationPP(std::string motivationName, sint16 PP)
00428 {
00429 _ClassifiersAndMotivationIntensity[motivationName].MotivationIntensity.setMotivationPP(motivationName, PP);
00430 }
00431
00433 void CNetCS::setMotivationValue(std::string motivationName, sint16 value)
00434 {
00435 _ClassifiersAndMotivationIntensity[motivationName].MotivationIntensity.setMotivationValue(motivationName, value);
00436 }
00437
00438 void CNetCS::run()
00439 {
00440
00441
00442
00443
00444 sint16 somme = 0;
00445 typedef std::map<std::string, CMotivateCS>::iterator TitNameAndMotivation;
00446 std::map<sint16, TitNameAndMotivation > mapCSweel;
00447 std::map<std::string, CMotivateCS>::iterator itClassifiers;
00448
00449 for (itClassifiers = _ClassifiersAndMotivationIntensity.begin(); itClassifiers != _ClassifiersAndMotivationIntensity.end(); itClassifiers++)
00450 {
00451 CMotivateCS* pCMotivateCS = &((*itClassifiers).second);
00452 sint16 energy = pCMotivateCS->MotivationIntensity.getSumValue();
00453 if (energy > 0)
00454 {
00455 somme += energy;
00456 mapCSweel[somme] = itClassifiers;
00457 }
00458 }
00459 if (somme>0)
00460 {
00461
00462 sint16 randomeNumber = rand()%(somme);
00463 std::map<sint16, TitNameAndMotivation>::iterator itMapCSweel = mapCSweel.upper_bound(randomeNumber);
00464 CMotivateCS* pCSselection = &((*((*itMapCSweel).second)).second);
00465 std::string selectionName = (*((*itMapCSweel).second)).first;
00466
00467
00468 std::string behav = pCSselection->CS.selectBehavior(_SensorsValues);
00469
00470
00471 CMotivationEnergy* pEnergy2Evolve;
00472 CMotivationEnergy& refMyEnergy = pCSselection->MotivationIntensity;
00473 std::map<std::string, CMotivationEnergy>::iterator itActionsExecutionIntensity;
00474 itActionsExecutionIntensity = _ActionsExecutionIntensity.find(behav);
00475 if (itActionsExecutionIntensity != _ActionsExecutionIntensity.end())
00476 {
00477 pEnergy2Evolve = &((*itActionsExecutionIntensity).second);
00478 }
00479 else
00480 {
00481 std::map<std::string, CMotivateCS>::iterator itClassifiersAndMotivationIntensity;
00482 itClassifiersAndMotivationIntensity = _ClassifiersAndMotivationIntensity.find(behav);
00483 nlassert (itClassifiersAndMotivationIntensity != _ClassifiersAndMotivationIntensity.end());
00484 pEnergy2Evolve = &((*itClassifiersAndMotivationIntensity).second.MotivationIntensity);
00485 }
00486 nlassert(pEnergy2Evolve);
00487
00488
00489
00490 _ClassifiersAndMotivationIntensity[pCSselection->LastMotivedAction].MotivationIntensity.removeProvider(selectionName);
00491
00492
00493 pEnergy2Evolve->addProvider(selectionName, refMyEnergy);
00494
00495 }
00496 }
00497
00498 void CNetCS::setSensors(const TSensorMap &sensorMap)
00499 {
00500 _SensorsValues = sensorMap;
00501 }
00502
00503
00504 std::string CNetCS::selectBehavior()
00505 {
00506
00507 std::string ret = "";
00508 sint16 executionIntensity = 0;
00509 std::map<std::string, CMotivationEnergy>::iterator itActionsExecutionIntensity;
00510 for (itActionsExecutionIntensity = _ActionsExecutionIntensity.begin(); itActionsExecutionIntensity != _ActionsExecutionIntensity.end(); itActionsExecutionIntensity++)
00511 {
00512 sint16 value = (*itActionsExecutionIntensity).second.getSumValue();
00513 if (value > executionIntensity)
00514 {
00515 ret = (*itActionsExecutionIntensity).first;
00516 }
00517 }
00518 return ret;
00519 }
00520
00521
00522 }