Module tutorial1
[hide private]
[frames] | no frames]

Source Code for Module tutorial1

  1  """ 
  2  tutorial1 
  3  ========= 
  4  Contains all parameters for the evolutionary run, grammar rules, constraints,  
  5  and specifics about the terminal and function set of the trees in tutorial1. 
  6  This example file gather all the settings for a simple polynomial regression 
  7  using one variable x and the following mathematical operators: '+','-','neg','*','^2'(or square),'cos','sin'. 
  8  We try to find a third degree polynomial: x^3 + x^2 + cos(x) 
  9  from 2 sets of testing data (2 different values for x). 
 10  Considering the constraints for building the trees, the root node will only have 
 11  one child, and there will be no need for ADF in the function and terminal set. 
 12  A typical way to run the tutorial would be to: 
 13      - modify the settings file so that:  
 14       
 15      >>>     #setup for running tutorial 1 
 16              functions = tutorial1.functions 
 17              terminals =tutorial1.terminals 
 18              crossover_mapping=tutorial1.crossover_mapping 
 19              nb_eval=tutorial1.nb_eval 
 20              ideal_results=tutorial1.GetIdealResultsData() 
 21              Strongly_Typed_Crossover_degree=tutorial1.Strongly_Typed_Crossover_degree 
 22              Substitute_Mutation=tutorial1.Substitute_Mutation 
 23              treeRules = tutorial1.treeRules 
 24              adfOrdered = tutorial1.adfOrdered 
 25              FitnessFunction = tutorial1.FitnessFunction 
 26       
 27      - run the evolution in the main method, and make sure that the root node parameter 
 28      only have one child.e.g. 
 29       
 30      >>>    import evolver 
 31      if __name__ == "__main__": 
 32      >>>    dbname=r'C:\pop_db' 
 33      >>>    evolver.EvolutionRun(2000,(0,1,'root'),2,8,'AddHalfNode',100, 0.00001 ,0.5,0.49,7,0.8,dbname,True) 
 34   
 35      This means that we define: 
 36      - a population size of 2000 individuals, 
 37      - a root node with 1 child 
 38      - a minimum tree depth of 2 
 39      - a maximum tree depth of 8 
 40      - the use of a Ramped half and Half Koza tree building method 
 41      - a maximum number of runs of 100 generations before we stop 
 42      - a stoping fitness criteria of 0.1 (if the fitness<=0.1, solution found) 
 43      - a crossover probability of 0.5 
 44      - a mutation probability of 0.49 
 45      - a reproduction probability of 0.01 (automatically deduced from the 2 previous values) 
 46      - the size of the tournament selection 
 47      - the probability of selecting the fitttest during tournament selection  
 48      - a database of name and path dbname 
 49      - a run done in verbose mode (printing the fittest element of each generation)  
 50            
 51  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 52  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 53  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 54  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 55  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 56  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
 57  THE SOFTWARE. 
 58   
 59  @author: by Mehdi Khoury 
 60  @version: 1.20 
 61  @copyright: (c) 2009 Mehdi Khoury under the mit license 
 62  http://www.opensource.org/licenses/mit-license.html 
 63  @contact: mehdi.khoury at gmail.com 
 64  """ 
 65   
 66   
 67   
 68  import psyco 
 69  import evalfitness 
 70  import random 
 71  import math 
 72   
 73  psyco.profile() 
 74   
 75   
 76  # first, we create result processing methods for each function: 
77 -def add(listElem):
78 try: 79 return listElem[0]+listElem[1] 80 except: 81 raise WrongValues, "Wrong values sent to function node.\nCan't get result" 82 exit
83
84 -def sub(listElem):
85 try: 86 return listElem[0]-listElem[1] 87 except: 88 raise WrongValues, "Wrong values sent to function node.\nCan't get result" 89 exit
90
91 -def neg(listElem):
92 try: 93 return 0-listElem[0] 94 except: 95 raise WrongValues, "Wrong values sent to function node.\nCan't get result" 96 exit
97 98 99
100 -def multiply(listElem):
101 try: 102 return listElem[0]*listElem[1] 103 except: 104 raise WrongValues, "Wrong values sent to function node.\nCan't get result" 105 exit
106
107 -def square(listElem):
108 try: 109 return listElem[0]*listElem[0] 110 except: 111 raise WrongValues, "Wrong values sent to function node.\nCan't get result" 112 exit
113
114 -def cos(listElem):
115 try: 116 return math.cos(listElem[0]) 117 except: 118 raise WrongValues, "Wrong values sent to function node.\nCan't get result" 119 exit
120
121 -def sin(listElem):
122 try: 123 return math.sin(listElem[0]) 124 except: 125 raise WrongValues, "Wrong values sent to function node.\nCan't get result" 126 exit
127
128 -def rootBranch(x):
129 try: 130 return x 131 except: 132 raise WrongValues, "Wrong values sent to function node.\nCan't get result" 133 exit
134 135 # then, we create a set of functions and associate them with the corresponding 136 # processing methods 137 functions = {'+':add, 138 '-':sub, 139 'neg':neg, 140 '*':multiply, 141 '^2':square, 142 'cos':cos, 143 'sin':sin, 144 'root':rootBranch 145 } 146 147 # we create the list of all possible values a variable can have in the learning examples 148 nb_eval=2 149 all_x=[] 150 for i in xrange(nb_eval): 151 all_x.append(random.random()*10) 152 153 # then, we create a mapping of terminals 154 # the variables will be given a value coming from a set of examples 155 # the constants will just be given as such or produced by a 156 # random producer 157 terminals = { 158 'x':all_x 159 } 160 161 # ideal polynomial to find 162 ideal_results=[]
163 -def GetIdealResultsData():
164 for nb in xrange(nb_eval): 165 ideal_results.append([all_x[nb]**3+all_x[nb]**2+math.cos(all_x[nb])]) 166 return ideal_results
167 168
169 -def FitnessFunction(my_tree):
170 return evalfitness.FinalFitness(evalfitness.EvalTreeForAllInputSets(my_tree,xrange(nb_eval)))
171 172 173 crossover_mapping=[] 174 175 # default function set applicable by for branches: 176 defaultFunctionSet= [(1,2,'+'),(1,2,'*'),(1,1,'^2'),(1,2,'-'),(1,1,'cos'),(1,1,'sin'),(1,1,'neg')] 177 # default terminal set applicable by for branches: 178 defaultTerminalSet= [(3,0,'x')] 179 treeRules = {'root':[(defaultFunctionSet,defaultTerminalSet)], 180 '+':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)], 181 '*':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)], 182 '^2':[(defaultFunctionSet,defaultTerminalSet)], 183 '-':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)], 184 'neg':[([(1,2,'+'),(1,2,'*'),(1,2,'-'),(1,1,'cos'),(1,1,'sin')],defaultTerminalSet)], 185 'cos':[([(1,2,'+'),(1,2,'*'),(1,2,'-'),(1,1,'sin'),(1,1,'neg')],defaultTerminalSet)], 186 'sin':[([(1,2,'+'),(1,2,'*'),(1,2,'-'),(1,1,'cos'),(1,1,'neg')],defaultTerminalSet)] 187 } 188 189 Strongly_Typed_Crossover_degree=0 190 Substitute_Mutation=0 191 adfOrdered = False 192