00001 #include <cmath>
00002 #include "../ECF_base.h"
00003 #include "Binary.h"
00004 #include<sstream>
00005
00006 namespace Binary
00007 {
00008
00009 double Binary::logbase (double a, double base)
00010 {
00011 return log(a) / log(base);
00012 }
00013
00014
00015 double Binary::round(double val, int decimals)
00016 {
00017 double r = val * pow(10., decimals);
00018 r = floor(r + 0.5);
00019 return r / pow(10., decimals);
00020 }
00021
00022
00023 void Binary::registerParameters(StateP state)
00024 {
00025 registerParameter(state, "lbound", (voidP) new double(0), ECF::DOUBLE);
00026 registerParameter(state, "ubound", (voidP) new double(10), ECF::DOUBLE);
00027 registerParameter(state, "precision", (voidP) new uint(1), ECF::UINT);
00028 registerParameter(state, "dimension", (voidP) new uint(1), ECF::UINT);
00029 registerParameter(state, "rounding", (voidP) new uint(0), ECF::UINT);
00030 }
00031
00032
00033 bool Binary::initialize (StateP state)
00034 {
00035 if(!isParameterDefined(state, "lbound") ||
00036 !isParameterDefined(state, "ubound") ||
00037 !isParameterDefined(state, "precision") ||
00038 !isParameterDefined(state, "dimension")) {
00039 ECF_LOG_ERROR(state, "Error: required parameters for Binary genotype not defined (lbound, ubound, precision, dimension)!");
00040 throw("");
00041 }
00042
00043 voidP genp = getParameterValue(state, "lbound");
00044 minValue_ = *((double*) genp.get());
00045
00046 genp = getParameterValue(state, "ubound");
00047 maxValue_ = *((double*) genp.get());
00048
00049 if(minValue_ >= maxValue_) {
00050 ECF_LOG_ERROR(state, "Error: 'lbound' must be smaller than 'ubound' for Binary genotype!");
00051 throw("");
00052 }
00053
00054 genp = getParameterValue(state, "precision");
00055 nDecimal_ = *((uint*) genp.get());
00056
00057 if(nDecimal_ > 16) {
00058 ECF_LOG_ERROR(state, "Error: 'precision' too large (> 16) for Binary genotype!");
00059 throw("");
00060 }
00061
00062 genp = getParameterValue(state, "dimension");
00063 nDimension_ = *((uint*) genp.get());
00064
00065 if(nDimension_ < 1) {
00066 ECF_LOG_ERROR(state, "Error: 'dimension' must be > 0 for Binary genotype!");
00067 throw("");
00068 }
00069
00070 genp = getParameterValue(state, "rounding");
00071 bRounding_ = (*((uint*) genp.get())) == 0 ? false : true;
00072
00073 double numIndividual = ((maxValue_ - minValue_) * pow(10., (int) nDecimal_));
00074 nBits_ = static_cast<int> (logbase(numIndividual, 2) + 1);
00075
00076 variables.resize(nDimension_);
00077 decValue.resize(nDimension_);
00078 realValue.resize(nDimension_);
00079 vBool_.resize(nBits_);
00080
00081 potention_ = static_cast<long> (pow(2., (int) nBits_) - 1);
00082
00083
00084 for (uint i = 0; i < nDimension_; i++){
00085 realValue[i] = ( minValue_ + (maxValue_ - minValue_) * state->getRandomizer()->getRandomDouble() );
00086 decValue[i] = static_cast<long int> ((realValue[i] - minValue_) / (maxValue_ - minValue_) * potention_);
00087 if(bRounding_) {
00088 realValue[i] = round(realValue[i], nDecimal_);
00089 }
00090
00091 long dec = decValue[i];
00092 for (int iBit = nBits_; iBit > 0; dec = dec / 2, iBit--) {
00093
00094 vBool_[iBit - 1] = (dec % 2) ? true:false;
00095 }
00096 variables[i] = vBool_;
00097 }
00098
00099 return true;
00100 }
00101
00102
00103 bool Binary::update (void)
00104 {
00105 for (uint iDim = 0; iDim < nDimension_; iDim++) {
00106 long dec = 0;
00107 long weight = 1;
00108 for (int iBit = nBits_ - 1; iBit >= 0; iBit--) {
00109 dec += static_cast<int>(variables[iDim][iBit]) * weight;
00110 weight *= 2;
00111 }
00112
00113 decValue[iDim] = dec;
00114 realValue[iDim] = minValue_ + (maxValue_ - minValue_) / potention_ * dec;
00115 if(bRounding_) {
00116 realValue[iDim] = round(realValue[iDim], nDecimal_);
00117 }
00118 }
00119
00120 return true;
00121 }
00122
00123
00124 void Binary::write(XMLNode &xBinary)
00125 {
00126 xBinary = XMLNode::createXMLTopNode("Binary");
00127 std::stringstream sValue;
00128 sValue << nDimension_;
00129 xBinary.addAttribute("size", sValue.str().c_str());
00130
00131 sValue.str("");
00132 for(uint iVar = 0; iVar < nDimension_; iVar++)
00133 sValue << "\t" << realValue[iVar];
00134 xBinary.addText(sValue.str().c_str());
00135 }
00136
00137
00138 void Binary::read(XMLNode& xBinary)
00139 {
00140 XMLCSTR values = xBinary.getText();
00141 std::stringstream sValues;
00142 sValues << values;
00143
00144 for(uint iVar = 0; iVar < nDimension_; iVar++) {
00145 sValues >> realValue[iVar];
00146 decValue[iVar] = static_cast<long int> ((realValue[iVar] - minValue_) / (maxValue_ - minValue_) * potention_);
00147
00148 long dec = decValue[iVar];
00149 for (int iBit = nBits_; iBit > 0; dec = dec/2, iBit--) {
00150 vBool_[iBit - 1] = (dec % 2) ? true:false;
00151 }
00152 variables[iVar] = vBool_;
00153 }
00154
00155 }
00156
00157 }