00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdexcept>
00010 #include "RuleSet.h"
00011
00012 namespace dynrules
00013 {
00014
00015 RuleSet::RuleSet () :
00016 _minweight(0),
00017 _maxweight(0),
00018 _weight(0),
00019 _rules(0)
00020 {
00021 }
00022
00023 RuleSet::RuleSet (double minweight, double maxweight) :
00024 _minweight(0),
00025 _maxweight(0),
00026 _weight(0),
00027 _rules(0)
00028 {
00029 if (minweight > maxweight)
00030 throw std::invalid_argument ("maxweight must not be smaller than minweight");
00031 this->_minweight = minweight;
00032 this->_maxweight = maxweight;
00033 }
00034
00035 RuleSet::~RuleSet ()
00036 {
00037 }
00038
00039 double RuleSet::getMinWeight () const
00040 {
00041 return this->_minweight;
00042 }
00043
00044 void RuleSet::setMinWeight (double minweight)
00045 {
00046 if (minweight > this->_maxweight)
00047 throw std::invalid_argument ("maxweight must not be smaller than minweight");
00048 this->_minweight = minweight;
00049 }
00050
00051 double RuleSet::getMaxWeight () const
00052 {
00053 return this->_maxweight;
00054 }
00055
00056 void RuleSet::setMaxWeight (double maxweight)
00057 {
00058 if (maxweight < this->_minweight)
00059 throw std::invalid_argument ("maxweight must not be smaller than minweight");
00060 this->_maxweight = maxweight;
00061 }
00062
00063 double RuleSet::getWeight () const
00064 {
00065 return this->_weight;
00066 }
00067
00068 std::vector<Rule*> RuleSet::getRules () const
00069 {
00070 return this->_rules;
00071 }
00072
00073 void RuleSet::addRule (Rule* rule)
00074 {
00075 if (rule == 0)
00076 throw std::invalid_argument ("rule must not be NULL");
00077
00078 this->_rules.push_back (rule);
00079 if (rule->getWeight() > this->_maxweight)
00080 rule->setWeight (this->_maxweight);
00081 else if (rule->getWeight () < this->_minweight)
00082 rule->setWeight (this->_minweight);
00083 this->_weight += rule->getWeight ();
00084 }
00085
00086 bool RuleSet::removeRule (Rule* rule)
00087 {
00088 if (rule == 0)
00089 return false;
00090
00091 bool found = false;
00092 std::vector<Rule*>::iterator iter;
00093 for (iter = this->_rules.begin (); iter != this->_rules.end (); iter++)
00094 {
00095 if ((*iter) == rule)
00096 {
00097 found = true;
00098 break;
00099 }
00100 }
00101 if (found)
00102 {
00103 this->_rules.erase (iter);
00104 this->_weight -= (*iter)->getWeight ();
00105 }
00106 return found;
00107 }
00108
00109 Rule *RuleSet::find (int id)
00110 {
00111 std::vector<Rule*>::iterator iter;
00112 for (iter = this->_rules.begin (); iter != this->_rules.end (); iter++)
00113 if ((*iter)->getId () == id)
00114 return *iter;
00115 return 0;
00116 }
00117
00118 void RuleSet::clear ()
00119 {
00120 this->_rules.clear();
00121 this->_weight = 0.f;
00122 }
00123
00124 void RuleSet::updateWeights (void *fitness)
00125 {
00126
00127
00128
00129
00130 Rule *rule;
00131 std::vector<Rule*>::iterator it;
00132 size_t count, usedcount = 0, nonactive;
00133 double totweight = 0, adjustment, compensation, _remainder, weight;
00134
00135 count = this->_rules.size ();
00136 if (count == 0)
00137 return;
00138
00139 for (it = this->_rules.begin (); it != this->_rules.end (); it++)
00140 {
00141 rule = *it;
00142 if (rule->getUsed ())
00143 usedcount++;
00144 }
00145 if (usedcount == 0 || usedcount == count)
00146 return;
00147
00148 nonactive = count - usedcount;
00149 adjustment = this->calculateAdjustment (fitness);
00150 compensation = (static_cast<double>(-(static_cast<int>(usedcount)) *
00151 adjustment)) / nonactive;
00152 _remainder = 0;
00153
00154 for (it = this->_rules.begin (); it != this->_rules.end (); it++)
00155 {
00156 rule = *it;
00157
00158 weight = rule->getWeight () +
00159 ((rule->getUsed ()) ? adjustment : compensation);
00160
00161 if (weight < this->_minweight)
00162 {
00163 _remainder += (weight - this->_minweight);
00164 rule->setWeight (this->_minweight);
00165 }
00166 else if (weight > this->_maxweight)
00167 {
00168 _remainder += (weight - this->_maxweight);
00169 rule->setWeight (this->_maxweight);
00170 }
00171 else
00172 rule->setWeight (weight);
00173 totweight += rule->getWeight();
00174 }
00175
00176 this->_weight = totweight;
00177 this->distributeRemainder (_remainder);
00178
00179 totweight = 0;
00180 for (it = this->_rules.begin (); it != this->_rules.end (); it++)
00181 {
00182 rule = *it;
00183 rule->setUsed (false);
00184 totweight += rule->getWeight ();
00185 }
00186 this->_weight = totweight;
00187 }
00188
00189 double RuleSet::calculateAdjustment (void *fitness)
00190 {
00191 return 0.f;
00192 }
00193
00194 void RuleSet::distributeRemainder (double remainder)
00195 {
00196 }
00197
00198 }