1 """
2 tutorial3
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 tutorial3.
6 This example file gather all the settings for a 'multiple' polynomial regression.
7 We want to evolve a system of ordered polynomial equations by using the
8 mathematical operators: '+','*' and the ADF: ADF1 and ADF2, in the said order.
9 an ADF2 branch could then call for an ADF1 terminal, but not the opposite.
10 We try to find the following model being shaped as a system of polynomials:
11
12 |ADF1=x+y
13
14 |ADF2=ADF1^3
15
16 from 30 sets of testing data (30 different values for x and y).
17 This means the each tree has to be evaluated for every different example,
18 so 30 times. There is an alternative solution which we will see in the next tutorial,
19 where instead of evaluating a tree 30 times, we will input an array of 30 data in the
20 variable leafs of the tree.
21 Considering the constraints for building the trees, the root node will have 2 children ADF1 and ADF2 (in order),
22 and ADF2 must be able to reuse ADF1 as a terminal...
23 A typical way to run the tutorial would be to:
24 - modify the settings file so that:
25
26 >>> # setup for running tutorial 3
27 functions = tutorial3.functions
28 crossover_mapping=tutorial3.crossover_mapping
29 nb_eval=tutorial3.nb_eval
30 ideal_results=tutorial3.GetIdealResultsData()
31 terminals =tutorial3.terminals
32 Strongly_Typed_Crossover_degree=tutorial3.Strongly_Typed_Crossover_degree
33 Substitute_Mutation=tutorial3.Substitute_Mutation
34 treeRules = tutorial3.treeRules
35 adfOrdered = tutorial3.adfOrdered
36 FitnessFunction = tutorial3.FitnessFunction
37
38 - run the evolution in the main method, and make sure that the root node parameter
39 only have two children.e.g.
40
41 >>> import evolver
42 if __name__ == "__main__":
43 >>> dbname=r'C:\pop_db'
44 >>> evolver.EvolutionRun(2000,(0,2,'root'),2,8,'AddHalfNode',100, 0.00001 ,0.5,0.49,7,0.8,dbname,True)
45
46 This means that we define:
47 - a population size of 2000 individuals,
48 - a root node with 2 children
49 - a minimum tree depth of 2
50 - a maximum tree depth of 8
51 - the use of a Ramped half and Half Koza tree building method
52 - a maximum number of runs of 100 generations before we stop
53 - a stoping fitness criteria of 0.1 (if the fitness<=0.1, solution found)
54 - a crossover probability of 0.5
55 - a mutation probability of 0.49
56 - a reproduction probability of 0.01 (automatically deduced from the 2 previous values)
57 - the size of the tournament selection
58 - the probability of selecting the fitttest during tournament selection
59 - a database of name and path dbname
60 - a run done in verbose mode (printing the fittest element of each generation)
61
62 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
65 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
66 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
68 THE SOFTWARE.
69
70 @author: by Mehdi Khoury
71 @version: 1.20
72 @copyright: (c) 2009 Mehdi Khoury under the mit license
73 http://www.opensource.org/licenses/mit-license.html
74 @contact: mehdi.khoury at gmail.com
75 """
76
77
78 import psyco
79 import random
80 import math
81 from treeutil import PostOrder_Search
82 from collections import deque
83 import evalfitness
84
85 psyco.profile()
86
87
89 try:
90 return listElem[0]+listElem[1]
91 except:
92 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
93 exit
94
95
97 try:
98 return listElem[0]*listElem[1]
99 except:
100 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
101 exit
102
104 try:
105 return x
106 except:
107 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
108 exit
109
111 try:
112 return x
113 except:
114 raise WrongValues, "Wrong values sent to function node.\nCan't get result"
115 exit
116
117
118
119 functions = {'+':add,
120 '*':multiply,
121 'adf2_+':add,
122 'adf2_*':multiply,
123 'adf1':adfBranch,
124 'adf2':adfBranch,
125 'root':rootBranch
126 }
127
128
129 crossover_mapping=[('+','adf2_+'),('adf2_+','+'),('*','adf2_*'),('adf2_*','*')]
130
131
132
133 nb_eval=30
134 all_x=[]
135 all_y=[]
136 for i in xrange(nb_eval):
137 all_x.append(random.random()*10)
138 all_y.append(random.random()*10)
139
140
141
142 ideal_results=[]
143
148
149
150
151
152 terminals = {
153 'x':all_x,
154 'y':all_y
155 }
156
157
158 Strongly_Typed_Crossover_degree=1
159
162
163
164 defaultFunctionSet= [(1,2,'+'),(1,2,'*')]
165
166 defaultTerminalSet= [(3,0,'x'),(3,0,'y')]
167 Adf2DefaultFunctionSet= [(1,2,'adf2_+'),(1,2,'adf2_*')]
168 Adf2DefaultTerminalSet= [(3,0,'x'),(3,0,'y'),(5,0,'adf1')]
169 treeRules = {'root':[ ([(2,1,'adf1')],[]) , ([(2,1,'adf2')],[]) ],
170 'adf1':[(defaultFunctionSet,defaultTerminalSet)],
171 'adf2':[(Adf2DefaultFunctionSet,Adf2DefaultTerminalSet)],
172 '+':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)],
173 '*':[(defaultFunctionSet,defaultTerminalSet),(defaultFunctionSet,defaultTerminalSet)],
174 'adf2_+':[(Adf2DefaultFunctionSet,Adf2DefaultTerminalSet),(Adf2DefaultFunctionSet,Adf2DefaultTerminalSet)],
175 'adf2_*':[(Adf2DefaultFunctionSet,Adf2DefaultTerminalSet),(Adf2DefaultFunctionSet,Adf2DefaultTerminalSet)],
176 }
177
178 Strongly_Typed_Crossover_degree=1
179 Substitute_Mutation=0
180 adfOrdered = True
181