dynrules
|
00001 /* 00002 * dynrules - Python dynamic rules engine 00003 * 00004 * Authors: Marcus von Appen 00005 * 00006 * This file is distributed under the Public Domain. 00007 */ 00008 00009 #include <ctime> 00010 #include <stdexcept> 00011 #include "LearnSystem.h" 00012 00013 namespace dynrules 00014 { 00015 00016 LearnSystem::LearnSystem () : 00017 _maxtries (100), 00018 _maxscriptsize(1024), 00019 _ruleset (new RuleSet(0,0)) 00020 { 00021 } 00022 00023 LearnSystem::LearnSystem (double minweight, double maxweight) : 00024 _maxtries (100), 00025 _maxscriptsize(1024), 00026 _ruleset(new RuleSet (minweight, maxweight)) 00027 { 00028 } 00029 00030 LearnSystem::LearnSystem (RuleSet* ruleset) : 00031 _maxtries(100), 00032 _maxscriptsize(1024), 00033 _ruleset(ruleset) 00034 { 00035 } 00036 00037 LearnSystem::LearnSystem (const LearnSystem& lsystem) : 00038 _maxtries(lsystem.getMaxTries ()), 00039 _maxscriptsize(lsystem.getMaxScriptSize ()), 00040 _ruleset(new RuleSet (*(lsystem.getRuleSet()))) 00041 { 00042 } 00043 00044 LearnSystem::~LearnSystem () 00045 { 00046 delete this->_ruleset; 00047 } 00048 00049 RuleSet* LearnSystem::getRuleSet () const 00050 { 00051 return this->_ruleset; 00052 } 00053 00054 void LearnSystem::setRuleSet (RuleSet* ruleset) 00055 { 00056 if (ruleset == 0) 00057 throw new std::invalid_argument ("ruleset must not be NULL"); 00058 this->_ruleset = ruleset; 00059 } 00060 00061 unsigned int LearnSystem::getMaxTries () const 00062 { 00063 return this->_maxtries; 00064 } 00065 00066 void LearnSystem::setMaxTries (unsigned int maxtries) 00067 { 00068 this->_maxtries = maxtries; 00069 } 00070 00071 unsigned int LearnSystem::getMaxScriptSize () const 00072 { 00073 return this->_maxscriptsize; 00074 } 00075 00076 void LearnSystem::setMaxScriptSize (unsigned int maxscriptsize) 00077 { 00078 this->_maxscriptsize = maxscriptsize; 00079 } 00080 00081 std::string LearnSystem::createHeader () const 00082 { 00083 std::string retval = ""; 00084 return retval; 00085 } 00086 00087 std::string LearnSystem::createFooter () const 00088 { 00089 std::string retval = ""; 00090 return retval; 00091 } 00092 00093 std::string LearnSystem::createRules (unsigned int maxrules) const 00094 { 00095 std::string buf, retval = ""; 00096 std::vector<Rule*> rules; 00097 Rule *rule; 00098 unsigned int tries, i; 00099 int added = 0, j, selected; 00100 size_t len, count, written = 0; 00101 double wsum, fraction, weights = this->_ruleset->getWeight (); 00102 00103 if (weights == 0 || maxrules == 0) 00104 return retval; 00105 00106 rules = this->_ruleset->getRules (); 00107 count = rules.size (); 00108 00109 /* Initialise the random number generator */ 00110 srand (static_cast<unsigned int>(time (0))); 00111 00112 for (i = 0; i < maxrules; i++) 00113 { 00114 if (written >= static_cast<size_t>(this->_maxscriptsize)) 00115 break; 00116 00117 tries = added = 0; 00118 while (tries < this->_maxtries && !added) 00119 { 00120 j = 0; 00121 selected = -1; 00122 wsum = 0.; 00123 fraction = ((static_cast<double>(rand())) / RAND_MAX) * weights; 00124 while (selected == -1) 00125 { 00126 rule = rules.at (j); 00127 wsum += rule->getWeight (); 00128 if (wsum > fraction) 00129 { 00130 selected = j; 00131 break; 00132 } 00133 j = ((j + 1) % count); 00134 } 00135 00136 rule = rules.at (selected); 00137 00138 /* Write the rule code */ 00139 buf = rule->getCode (); 00140 len = buf.size (); 00141 /* Buffer acquired, write the raw data. */ 00142 if (written + len > static_cast<size_t>(this->_maxscriptsize)) 00143 goto finish; 00144 retval.append (buf); 00145 written += len; 00146 added = 1; 00147 00148 tries++; 00149 break; 00150 } 00151 } 00152 00153 finish: 00154 return retval; 00155 } 00156 00157 void LearnSystem::createScript (std::ostream& stream, unsigned int maxrules) 00158 { 00159 stream << this->createHeader () << std::endl; 00160 stream << this->createRules (maxrules) << std::endl; 00161 stream << this->createFooter () << std::endl; 00162 return; 00163 } 00164 00165 } // namespace