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
00009
00010
00011
00012
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
00045 bool Classifier::checkState(const StateP state) {
00046
00047
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
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
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
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
00123
00124
00125 int Classifier::getActionId(){
00126
00127 int ret = 0;
00128 BitStringP bstring = boost::dynamic_pointer_cast<BitString::BitString> (ind->getGenotype(2));
00129
00130
00131
00132
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 }