1 | /* |
---|
2 | Copyright 2006 by Sean Luke |
---|
3 | Licensed under the Academic Free License version 3.0 |
---|
4 | See the file "LICENSE" for more information |
---|
5 | */ |
---|
6 | |
---|
7 | |
---|
8 | package ec.gp.build; |
---|
9 | import ec.*; |
---|
10 | import ec.util.*; |
---|
11 | import ec.gp.*; |
---|
12 | |
---|
13 | /* |
---|
14 | * PTCFunctionSet.java |
---|
15 | * |
---|
16 | * Created: Wed Jan 26 21:10:59 2000 |
---|
17 | * By: Sean Luke |
---|
18 | */ |
---|
19 | |
---|
20 | /** |
---|
21 | * PTCFunctionSet is a GPFunctionSet which adheres to PTCFunctionSetForm, and thus |
---|
22 | * can be used with the PTC1 and PTC2 methods. Terminal and nonterminal probabilities |
---|
23 | * for nodes used in this function set are determined by the <tt>prob</tt> parameter |
---|
24 | * for the nodes' GPNodeConstraints object. That's not the greatest solution, |
---|
25 | * because it could require making a lot of different GPNodeConstraints, customized for each |
---|
26 | * node, but it's the best I can do for now. |
---|
27 | * |
---|
28 | * The nonterminalSelectionProbabilities() method computes nonterminal selection |
---|
29 | * probability using the probabilities above, per type, for the size requested. |
---|
30 | * If the size is small enough (smaller than CACHE_SIZE), then the result is |
---|
31 | * memoized so it doesn't need to be computed again next time. |
---|
32 | * |
---|
33 | * @author Sean Luke |
---|
34 | * @version 1.0 |
---|
35 | */ |
---|
36 | |
---|
37 | public class PTCFunctionSet extends GPFunctionSet implements PTCFunctionSetForm |
---|
38 | { |
---|
39 | /** terminal probabilities[type][thenodes], in organized form */ |
---|
40 | public float q_ty[][]; |
---|
41 | /** nonterminal probabilities[type][thenodes], in organized form */ |
---|
42 | public float q_ny[][]; |
---|
43 | |
---|
44 | public static final int CACHE_SIZE = 1024; |
---|
45 | /** cache of nonterminal selection probabilities -- dense array |
---|
46 | [size-1][type]. If any items are null, they're not in the dense cache. */ |
---|
47 | public float p_y[][]; |
---|
48 | |
---|
49 | public float[] terminalProbabilities(final int type) |
---|
50 | { return q_ty[type]; } |
---|
51 | |
---|
52 | public float[] nonterminalProbabilities(final int type) |
---|
53 | { return q_ny[type]; } |
---|
54 | |
---|
55 | public void setup(final EvolutionState state, final Parameter base) |
---|
56 | { |
---|
57 | super.setup(state,base); |
---|
58 | |
---|
59 | // load our probabilities here. |
---|
60 | |
---|
61 | q_ny = new float[nonterminals.length][]; |
---|
62 | q_ty = new float[terminals.length][]; |
---|
63 | |
---|
64 | boolean allOnes = true; |
---|
65 | boolean noOnes = true; |
---|
66 | boolean allZeros = true; |
---|
67 | GPInitializer initializer = ((GPInitializer)state.initializer); |
---|
68 | |
---|
69 | for(int type=0;type<nonterminals.length;type++) |
---|
70 | { |
---|
71 | q_ny[type] = new float[nonterminals[type].length]; |
---|
72 | for(int x=0;x<nonterminals[type].length;x++) |
---|
73 | { |
---|
74 | q_ny[type][x] = nonterminals[type][x].constraints(initializer).probabilityOfSelection; |
---|
75 | if (q_ny[type][x] != 0.0f) allZeros = false; |
---|
76 | if (q_ny[type][x] == 1.0f) noOnes = false; |
---|
77 | else allOnes = false; |
---|
78 | } |
---|
79 | } |
---|
80 | |
---|
81 | if (allZeros) |
---|
82 | state.output.warning("In this function set, the probabilities of all nonterminal functions have a 0.0 selection probability -- this will cause them all to be selected uniformly. That could be an error.", base); |
---|
83 | allZeros = false; |
---|
84 | |
---|
85 | for(int type=0;type<terminals.length;type++) |
---|
86 | { |
---|
87 | q_ty[type] = new float[terminals[type].length]; |
---|
88 | for(int x=0;x<terminals[type].length;x++) |
---|
89 | { |
---|
90 | q_ty[type][x] = terminals[type][x].constraints(initializer).probabilityOfSelection; |
---|
91 | if (q_ty[type][x] != 0.0f) allZeros = false; |
---|
92 | if (q_ty[type][x] == 1.0f) noOnes = false; |
---|
93 | else allOnes = false; |
---|
94 | } |
---|
95 | } |
---|
96 | |
---|
97 | if (allZeros) |
---|
98 | state.output.warning("In this function set, the probabilities of all terminal functions have a 0.0 selection probability -- this will cause them all to be selected uniformly. That could be an error.", base); |
---|
99 | |
---|
100 | if (!allOnes && !noOnes) |
---|
101 | state.output.warning("In this function set, there are some functions with a selection probability of 1.0, but not all of them. That could be an error.",base); |
---|
102 | |
---|
103 | // set up our node probabilities. Allow all zeros. |
---|
104 | for(int x=0;x<q_ty.length;x++) |
---|
105 | { |
---|
106 | if (q_ty[x].length == 0) state.output.warning("Function Set " + name + " has no terminals for type number " + x + ". This may cause problems for you."); |
---|
107 | else RandomChoice.organizeDistribution(q_ty[x], true); |
---|
108 | if (q_ny[x].length == 0) state.output.warning("Function Set " + name + " has no nonterminals for type number " + x + ". This may cause problems for you."); |
---|
109 | else RandomChoice.organizeDistribution(q_ny[x], true); |
---|
110 | } |
---|
111 | |
---|
112 | // set up cache |
---|
113 | p_y = new float[CACHE_SIZE][]; |
---|
114 | } |
---|
115 | |
---|
116 | public float[] nonterminalSelectionProbabilities(final int expectedTreeSize) |
---|
117 | { |
---|
118 | // check cache first |
---|
119 | if (expectedTreeSize<CACHE_SIZE) |
---|
120 | { |
---|
121 | if (p_y[expectedTreeSize-1]!=null) return p_y[expectedTreeSize-1]; |
---|
122 | else return p_y[expectedTreeSize-1] = |
---|
123 | computeNonterminalSelectionProbabilities(expectedTreeSize); |
---|
124 | } |
---|
125 | else |
---|
126 | // we'll have to compute it |
---|
127 | return computeNonterminalSelectionProbabilities(expectedTreeSize); |
---|
128 | } |
---|
129 | |
---|
130 | |
---|
131 | public float[] computeNonterminalSelectionProbabilities(final int expectedTreeSize) |
---|
132 | { |
---|
133 | float[] p = new float[q_ny.length]; |
---|
134 | |
---|
135 | // for each type... |
---|
136 | for(int x=0;x<q_ny.length;x++) |
---|
137 | { |
---|
138 | double count=0; |
---|
139 | // gather branching factor * prob for each nonterminal |
---|
140 | for(int y=0;y<q_ny[x].length;y++) |
---|
141 | count += (y==0 ? q_ny[x][y] : q_ny[x][y]-q_ny[x][y-1]) // it's organized |
---|
142 | * nonterminals[x][y].children.length; |
---|
143 | |
---|
144 | p[x] = (float)((1.0-(1.0/expectedTreeSize))/count); |
---|
145 | } |
---|
146 | return p; |
---|
147 | } |
---|
148 | } |
---|