• Main Page
  • Modules
  • Classes
  • Files
  • File List

D:/Projekt/ECF_trunk/ECF/xcs/Classifier.cpp

00001 #include "../ECF_base.h"
00002 #include "../FitnessMax.h"
00003 #include "../ECF_macro.h"
00004 
00005 #include "Classifier.h"
00006 #include "time.h"
00007 
00008 //Class that represents single classifier in XCS system
00009 //This implementation is designed for BitString::BitString genotypes for
00010 //rule, input and action definition
00011 //By extending it, other genotypes could also be used.
00012 //All used genotypes need to have the same type as corresponding in configuration file.
00013 
00014 Classifier::Classifier(XCSParamsP xcsParams, unsigned long long int time, IndividualP ind, StateP state){
00015 
00016     this->xcsParams = xcsParams;
00017     params = boost::dynamic_pointer_cast<ClassifierParams> (ind->getGenotype(3));
00018 
00019     this->ind = ind;
00020     this->ind->fitness = static_cast<FitnessP> (new FitnessMax);
00021     setFitness(xcsParams->initF_);
00022     
00023     setTimeStamp(time);
00024 
00025     BitStringP dontCareBits = getDontCareBitString();
00026     for (uint i = 0; i < dontCareBits->bits.size(); ++i){
00027         double rnd = state->getRandomizer()->getRandomDouble();
00028         if (rnd < xcsParams->pdc_) 
00029             dontCareBits->bits[i] = true;
00030         else
00031             dontCareBits->bits[i] = false;
00032     }
00033     valid = true;
00034 }
00035 
00036 Classifier::Classifier(ClassifierP cl){
00037 
00038     xcsParams = cl->xcsParams;
00039     ind = static_cast<IndividualP> (cl->ind->copy());
00040     params = boost::dynamic_pointer_cast<ClassifierParams> (ind->getGenotype(3));
00041     valid = true;
00042 }
00043 
00044 //Checks if current state configuration is acceptable by Classifier
00045 bool Classifier::checkState(const StateP state) {
00046 
00047     // minimum 3 genotypes required
00048     if(state->getGenotypes().size() < 3) {
00049         ECF_LOG_ERROR(state, "Error: XCS algorithm requires min. 3 genotypes!");
00050         return false;
00051     }
00052     
00053     BitStringP bitstring = static_cast<BitStringP> (new BitString::BitString);
00054 
00055     if(state->getGenotypes()[0]->getName() != bitstring->getName() 
00056         || state->getGenotypes()[1]->getName() != bitstring->getName()) {
00057             ECF_LOG_ERROR(state, "Error: XCS algorithm accepts only BitString::BitString genotype as input!");
00058             return false;
00059     }
00060 
00061     return true;
00062 }
00063 
00064 //Checks if classifier matches input value
00065 bool Classifier::doesMatch(const GenotypeP inp) {
00066     
00067     BitStringP input = boost::static_pointer_cast<BitString::BitString> (inp);
00068 
00069     BitStringP ruleBits = boost::static_pointer_cast<BitString::BitString> (ind->getGenotype(0));
00070     BitStringP dontCareBits = boost::static_pointer_cast<BitString::BitString> (ind->getGenotype(1));   
00071     
00072     for (uint i = 0; i < input->bits.size(); i++){
00073         if (dontCareBits->bits[i] ) continue;
00074         if (ruleBits->bits[i] != input->bits[i]) return false;
00075     }
00076     return true;
00077 }
00078 //Fits classifier rule to match the input value
00079 void Classifier::cover (std::set<int> actions, const GenotypeP input, StateP state){
00080     ind->at(0) = static_cast<GenotypeP> (input->copy());
00081     BitStringP action = boost::dynamic_pointer_cast<BitString::BitString> (getAction());
00082 
00083     do {
00084         action->initialize(state);
00085     } while (actions.find(getActionId()) != actions.end());
00086 
00087 }
00088 
00089 //Prints classifier data on screen
00090 void Classifier::print(){
00091     
00092     std::cout << "  [" << ind->index << "] ";
00093     printRuleString (getRuleBitString(),getDontCareBitString());
00094     std::cout << " : ";
00095     
00096     printBitString (boost::dynamic_pointer_cast<BitString::BitString> (getAction()) );
00097     
00098     std::cout << " ("<< getError() << ", " << getPrediction() <<", "<< getFitness() << ")";
00099     std::cout << "\t[ " << getNumerosity() << ", " << getActSetSize() << ", " << getExperience() << ", " << getTimeStamp() << " ]";
00100     std::cout << std::endl;
00101 }
00102 
00103 void Classifier::printRuleString (const BitStringP bString, const BitStringP hashString) {
00104     char sign;
00105     
00106     for (uint i = 0; i < bString->bits.size(); i++){
00107         if (hashString != NULL && hashString->bits[i]) sign = '#';
00108         else sign = bString->bits[i] ? '1':'0';
00109         std::cout << sign;
00110         
00111     }
00112 }
00113 
00114 void Classifier::printBitString (const BitStringP bString) {
00115     
00116     for (uint i = 0; i < bString->bits.size(); i++){
00117         std::cout << bString->bits[i] ? '1':'0';
00118     }
00119     
00120 }
00121 
00122 //Each action has id that is used for creating PA
00123 //Since action is Genotype XCS can't make a difference
00124 //beetwean two abstract classes
00125 int Classifier::getActionId(){
00126     
00127     int ret = 0;
00128     BitStringP bstring = boost::dynamic_pointer_cast<BitString::BitString> (ind->getGenotype(2));
00129     /* Promjenjeno zbog mux problema
00130     if (bstring->bits[0]) ret += 1;
00131     if (bstring->bits[1]) ret += 10;
00132     if (bstring->bits[2]) ret += 100;
00133     */
00134 
00135     int add = 1;
00136     for (uint i =0; i < bstring->bits.size(); ++i){
00137         if (bstring->bits[i]) ret += add;
00138         add *= 10;
00139     }
00140 
00141     return ret;
00142 }
00143 
00144 GenotypeP Classifier::getAction(){
00145     return ind->getGenotype(2);
00146 }
00147 void Classifier::setAction(GenotypeP action){
00148     ind->at(2) = static_cast<GenotypeP> (action->copy());
00149 }
00150 
00151 
00152 #pragma region Parameters setters
00153 
00154 void Classifier::setError(double eps){
00155     params->eps_ = eps;
00156 }
00157 
00158 void Classifier::setPrediction(double p){
00159     params->p_ = p;
00160 }
00161 
00162 void Classifier::setFitness(double F){
00163     ind->fitness->setValue(F);
00164 }
00165 
00166 void Classifier::setTimeStamp(unsigned long long int ts) {
00167     params->ts_ = ts;
00168 }
00169 
00170 void Classifier::setNumerosity(int num) {
00171     params->num_ = num;
00172 }
00173 
00174 void Classifier::setActSetSize(double as) {
00175     params->as_ = as;
00176 }
00177 
00178 void Classifier::setExperience(double exp) {
00179     params->exp_ = exp;
00180 }
00181 
00182 #pragma endregion
00183 
00184 #pragma region Parameters getters
00185 
00186 double Classifier::getError(){
00187     return params->eps_;
00188 }
00189 
00190 double Classifier::getPrediction(){
00191     return params->p_;
00192 }
00193 
00194 double Classifier::getFitness(){
00195     return ind->fitness->getValue();
00196 }
00197 
00198 unsigned long long int Classifier::getTimeStamp() {
00199     return params->ts_;
00200 }
00201 
00202 int Classifier::getNumerosity(){
00203     return params->num_;
00204 }
00205 
00206 double Classifier::getActSetSize(){
00207     return params->as_;
00208 }
00209 
00210 double Classifier::getExperience(){
00211     return params->exp_;
00212 }
00213 
00214 #pragma endregion
00215 
00216 double Classifier::getDeletionVote(double avFit){
00217     double vote = getActSetSize() * getNumerosity();
00218     if (getExperience() > xcsParams->thresholdDel_ && 
00219         getFitness() / getNumerosity() < xcsParams->delta_ * avFit){
00220             vote = vote * avFit / (getFitness() / getNumerosity());
00221     }
00222     return vote;
00223 }
00224 bool Classifier::couldSubsume(){
00225     double exp = getExperience();
00226     double eps = getError();
00227     if (exp > xcsParams->thresholdSub_ && eps < xcsParams->eps0_){
00228         return true;
00229     }
00230     return false;
00231 }
00232 
00233 int Classifier::numOfDCBits(){
00234     int num = 0;
00235     BitStringP dcbstring = getDontCareBitString();
00236     for (uint i = 0; i < dcbstring->bits.size(); ++i){
00237         if (dcbstring->bits[i]) ++num;
00238     }
00239     return num;
00240 }
00241 bool Classifier::isMoreGeneral(ClassifierP cl){
00242     if (numOfDCBits() <= cl->numOfDCBits()) return false;
00243 
00244     BitStringP dcGen = getDontCareBitString();
00245     BitStringP ruleGen = getRuleBitString();
00246     BitStringP ruleSpec = cl->getRuleBitString();
00247     int bitsSize = (int) ruleGen->bits.size();
00248 
00249     int i = 0;
00250     do {
00251         if (!dcGen->bits[i] && ruleGen->bits[i] != ruleSpec->bits[i])
00252             return false;
00253         ++i;
00254     } while(i < bitsSize);
00255 
00256     return true;
00257 }
00258 
00259 bool Classifier::doesSubsume(ClassifierP cl){
00260 
00261     if (cl->getActionId() == getActionId()){
00262         if (couldSubsume()){
00263             if (isMoreGeneral(cl)){
00264                 return true;
00265             }
00266         }
00267     }
00268     return false;
00269 }
00270 
00271 
00272 BitStringP Classifier::getRuleBitString(){
00273     return boost::dynamic_pointer_cast<BitString::BitString> (ind->getGenotype(0));
00274 }
00275 
00276 BitStringP Classifier::getDontCareBitString(){
00277     return boost::dynamic_pointer_cast<BitString::BitString> (ind->getGenotype(1));
00278 }
00279 
00280 void Classifier::mutateRule(GenotypeP genInput, StateP state) {
00281 
00282     double rnd = state->getRandomizer()->getRandomDouble();
00283     BitStringP input = boost::dynamic_pointer_cast<BitString::BitString> (genInput);
00284 
00285     for (uint i= 0; i < input->bits.size(); i++){
00286         if (rnd < xcsParams->pMutation_){
00287             BitStringP ruleBits = getRuleBitString();
00288             BitStringP dontCareBits = getDontCareBitString();
00289             
00290             if (dontCareBits->bits[i] == true){
00291                 dontCareBits->bits[i] = false;
00292                 ruleBits->bits[i] = input->bits[i];
00293             } else 
00294                 dontCareBits->bits[i] = true;
00295         }
00296     }
00297 }
00298 
00299 void Classifier::mutateAction(StateP state) {
00300         double rnd = state->getRandomizer()->getRandomDouble();
00301         if (rnd < xcsParams->pMutation_){
00302             BitStringP actionBits = boost::dynamic_pointer_cast<BitString::BitString>  (getAction());
00303             actionBits->initialize(state);
00304         }
00305 }

Generated on Tue Nov 4 2014 13:04:31 for ECF by  doxygen 1.7.1