1 """
2 tutorial5
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 tutorial5.
6 In this example, we evolve hybrid system: a model containing discrete values
7 and logic operators and numerical operations.
8 More specifically, we will evolve if_then_else types rules that will determine
9 the application of different polynomials...
10 from 20 sets of testing data (20 different values for x and y).
11 Considering the constraints for building the trees, the root node will have
12 3 children, and these will be ordered ADF defining branches (we simply won't use ADF terminals nodes)
13 describing the structure of the if then else statement.
14 The solution found should be the equivalent of this expression:
15 if x>y then cos(x) else sin(y)
16
17 A typical way to run the tutorial would be to:
18 - modify the settings file so that:
19
20 >>> # setup for running tutorial 5
21 functions = tutorial5.functions
22 crossover_mapping=tutorial5.crossover_mapping
23 nb_eval=tutorial5.nb_eval
24 ideal_results=tutorial5.GetIdealResultsData()
25 terminals =tutorial5.terminals
26 Strongly_Typed_Crossover_degree=tutorial5.Strongly_Typed_Crossover_degree
27 Substitute_Mutation=tutorial5.Substitute_Mutation
28 treeRules = tutorial5.treeRules
29 adfOrdered = tutorial5.adfOrdered
30 FitnessFunction = tutorial5.FitnessFunction
31
32 - use a different fitness function for the evaluation of a hybrid system (we
33 use both discrete and continuous values now!)
34 We create 1 new fitness function:
35 - FinalFitness3 is a modification of FinalFitness that take as input
36 sets of If Then Else types of trees and return the sum of their fitnesses.
37 These fitness functions are called in 3 different places. We need to update
38 the code that call them.
39 These fitness functions are called in FitnessFunction in the tutorial5 module.
40
41 >>> def FitnessFunction(my_tree):
42 >>> return evalfitness.FinalFitness3(evalfitness.EvalTreeForAllInputSets(my_tree,xrange(nb_eval)))
43
44 - run the evolution in the main method, and make sure that the root node parameter
45 only have three children.e.g.
46
47 >>> import evolver
48 if __name__ == "__main__":
49 >>> dbname=r'C:\pop_db'
50 >>> evolver.EvolutionRun(2000,(0,3,'root'),3,8,'AddHalfNode',100, 0.00001 ,0.5,0.49,7,0.8,dbname,True)
51
52 This means that we define:
53 - a population size of 2000 individuals,
54 - a root node with 3 children
55 - a minimum tree depth of 3 (because the constraints of the tree would not work for a depth <3)
56 - a maximum tree depth of 8
57 - the use of a Ramped half and Half Koza tree building method
58 - a maximum number of runs of 100 generations before we stop
59 - a stoping fitness criteria of 0.1 (if the fitness<=0.1, solution found)
60 - a crossover probability of 0.5
61 - a mutation probability of 0.49
62 - a reproduction probability of 0.01 (automatically deduced from the 2 previous values)
63 - the size of the tournament selection
64 - the probability of selecting the fitttest during tournament selection
65 - a database of name and path dbname
66 - a run done in verbose mode (printing the fittest element of each generation)
67
68 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
69 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
70 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
71 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
72 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
73 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
74 THE SOFTWARE.
75
76 @author: by Mehdi Khoury
77 @version: 1.20
78 @copyright: (c) 2009 Mehdi Khoury under the mit license
79 http://www.opensource.org/licenses/mit-license.html
80 @contact: mehdi.khoury at gmail.com
81 """
82
83 from treeutil import PostOrder_Search
84 from collections import deque
85 import psyco
86 import random
87 import math
88 import evalfitness
89
90 psyco.profile()
91
92
93
95 try:
96 if listElem[0]==listElem[1]:
97 return True
98 else:
99 return False
100 except:
101 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
102 exit
103
105 try:
106 if listElem[0]>listElem[1]:
107 return True
108 else:
109 return False
110 except:
111 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
112 exit
113
115 try:
116 if listElem[0]<listElem[1]:
117 return True
118 else:
119 return False
120 except:
121 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
122 exit
123
125 try:
126 if listElem[0] and listElem[1]:
127 return True
128 else:
129 return False
130 except:
131 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
132 exit
133
135 try:
136 if listElem[0] or listElem[1]:
137 return True
138 else:
139 return False
140 except:
141 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
142 exit
143
144
145
146
148 try:
149 return listElem[0]+listElem[1]
150 except:
151 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
152 exit
153
155 try:
156 return listElem[0]-listElem[1]
157 except:
158 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
159 exit
160
162 try:
163 return 0-listElem[0]
164 except:
165 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
166 exit
167
168
169
171 try:
172 return listElem[0]*listElem[1]
173 except:
174 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
175 exit
176
178 try:
179 return listElem[0]*listElem[0]
180 except:
181 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
182 exit
183
185 try:
186 return math.cos(listElem[0])
187 except:
188 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
189 exit
190
192 try:
193 return math.sin(listElem[0])
194 except:
195 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
196 exit
197
199 try:
200 return x
201 except:
202 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
203 exit
204
206 try:
207 return x
208 except:
209 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
210 exit
211
213 try:
214 return x
215 except:
216 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
217 exit
218
220 try:
221 return x
222 except:
223 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
224 exit
225
226
227
228 functions = {'+':add,
229 '-':sub,
230 'neg':neg,
231 '*':multiply,
232 '^2':square,
233 'cos':cos,
234 'sin':sin,
235 '=':equal_,
236 '>':superior_,
237 '<':inferior_,
238 'and':and_,
239 'or':or_,
240 'if':if_,
241 'then':then_,
242 'else':else_,
243 'root':rootBranch
244 }
245
246
247 nb_eval=20
248 all_x=[]
249 all_y=[]
250 for i in xrange(nb_eval):
251 all_x.append(random.random()*10)
252 all_y.append(random.random()*10)
253
254
255
256
257 terminals = {
258 'x':all_x,
259 'y':all_y
260 }
261
262
263 ideal_results=[]
272
273
276
277
278 crossover_mapping=[]
279
280
281 defaultFunctionSet= [(1,2,'+'),(1,2,'*'),(1,1,'^2'),(1,2,'-'),(1,1,'cos'),(1,1,'sin'),(1,1,'neg')]
282
283 defaultTerminalSet= [(3,0,'x'),(3,0,'y')]
284 treeRules = {'root':[([(2,1,'if')],[]),([(2,1,'then')],[]),([(2,1,'else')],[])],
285 'if':[([(1,2,'and'),(1,2,'or'),(1,2,'>'),(1,2,'<'),(1,2,'=')],[])],
286 'then':[(defaultFunctionSet,defaultTerminalSet)],
287 'else':[(defaultFunctionSet,defaultTerminalSet)],
288 'and':[([(1,2,'and'),(1,2,'or'),(1,2,'>'),(1,2,'<'),(1,2,'=')],[]),([(1,2,'and'),(1,2,'or'),(1,2,'>'),(1,2,'<'),(1,2,'=')],[])],
289 'or':[([(1,2,'and'),(1,2,'or'),(1,2,'>'),(1,2,'<'),(1,2,'=')],[]),([(1,2,'and'),(1,2,'or'),(1,2,'>'),(1,2,'<'),(1,2,'=')],[])],
290 '=':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)],
291 '>':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)],
292 '<':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)],
293 '+':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)],
294 '*':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)],
295 '^2':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)],
296 '-':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)],
297 'neg':[([(1,2,'+'),(1,2,'*'),(1,2,'-'),(1,1,'cos'),(1,1,'sin')],defaultTerminalSet)],
298 'cos':[([(1,2,'+'),(1,2,'*'),(1,2,'-'),(1,1,'sin'),(1,1,'neg')],defaultTerminalSet)],
299 'sin':[([(1,2,'+'),(1,2,'*'),(1,2,'-'),(1,1,'cos'),(1,1,'neg')],defaultTerminalSet)]
300 }
301
302 Strongly_Typed_Crossover_degree=0
303 Substitute_Mutation=0
304 adfOrdered = True
305