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