001 package org.jaga.individualRepresentation.booleanFormulas;
002
003 import org.jaga.reproduction.booleanFormulas.nodes.*;
004 import org.jaga.definitions.*;
005
006
007 /**
008 * TODO: Complete these comments.
009 *
010 * <p><u>Project:</u> JAGA - Java API for Genetic Algorithms.</p>
011 *
012 * <p><u>Company:</u> University College London and JAGA.Org
013 * (<a href="http://www.jaga.org" target="_blank">http://www.jaga.org</a>).
014 * </p>
015 *
016 * <p><u>Copyright:</u> (c) 2004 by G. Paperin.<br/>
017 * This program is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU General Public License as published by
019 * the Free Software Foundation, ONLY if you include a note of the original
020 * author(s) in any redistributed/modified copy.<br/>
021 * This program is distributed in the hope that it will be useful,
022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
024 * GNU General Public License for more details.<br/>
025 * You should have received a copy of the GNU General Public License
026 * along with this program; if not, write to the Free Software
027 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
028 * or see http://www.gnu.org/licenses/gpl.html</p>
029 *
030 * @author Greg Paperin (greg@jaga.org)
031 *
032 * @version JAGA public release 1.0 beta
033 */
034
035 public class BooleanFormulaTreeFactory implements IndividualsFactory {
036
037 private static final Class [] stoppersWithConsts = new Class[] { TrueNode.class,
038 FalseNode.class,
039 TerminalNode.class };
040
041 private static final Class [] stoppersWithoutConsts = new Class[] { TerminalNode.class };
042
043 private int maxTreeDepth = 20;
044 private int numberOfParameters = 6;
045 private Class [] allowedNodeTypes = new Class[] { ANDNode.class, ORNode.class,
046 NOTNode.class, TerminalNode.class };
047 private boolean allowConstants = true;
048
049 public BooleanFormulaTreeFactory() {}
050
051 public BooleanFormulaTreeFactory(int maxTreeDepth, int numberOfParameters,
052 Class [] allowedNodeTypes, boolean allowConstants) {
053 this.numberOfParameters = numberOfParameters;
054 if (null == allowedNodeTypes)
055 this.allowedNodeTypes = new Class[0];
056 else
057 this.allowedNodeTypes = allowedNodeTypes;
058 this.allowConstants = allowConstants;
059 this.maxTreeDepth = maxTreeDepth;
060 }
061
062 public int getMaxTreeDepth() {
063 return this.maxTreeDepth;
064 }
065
066 public void setMaxTreeDepth(int maxDepth) {
067 if (maxDepth < 1)
068 throw new IndexOutOfBoundsException("Max. tree depth may not be < 1");
069 this.maxTreeDepth = maxDepth;
070 }
071
072 public int getNumberOfParameters() {
073 return this.numberOfParameters;
074 }
075
076 public void setNumberOfParameters(int val) {
077 if (numberOfParameters < 0)
078 throw new IndexOutOfBoundsException("Number of parameters may not be < 0");
079 this.numberOfParameters = val;
080 }
081
082 public Class [] getAllowedNodeTypes() {
083 return this.allowedNodeTypes;
084 }
085
086 public void setAllowedNodeTypes(Class [] val) {
087 if (null == allowedNodeTypes)
088 this.allowedNodeTypes = new Class[0];
089 else
090 this.allowedNodeTypes = val;
091 }
092
093 public boolean getAllowConstants() {
094 return this.allowConstants;
095 }
096
097 public void setAllowConstants(boolean val) {
098 this.allowConstants = val;
099 }
100
101 public Individual createDefaultIndividual(GAParameterSet params) {
102 BooleanFormulaTree formula = new BooleanFormulaTree(numberOfParameters);
103 return formula;
104 }
105
106 public Individual createRandomIndividual(GAParameterSet params) {
107 BooleanFormulaTree formula = null;
108 Long root = null;
109 BooleanFormulaTreeNode node = null;
110 formula = new BooleanFormulaTree(numberOfParameters);
111 root = formula.selectRootNode();
112 node = createRandomNode(1, params);
113 formula.replaceNode(root, node);
114 return formula;
115 }
116
117 public Individual createSpecificIndividual(Object init, GAParameterSet params) {
118 if (null == init)
119 throw new NullPointerException("Cannot have an null initialisation object.");
120
121 if (init instanceof BooleanFormulaTree)
122 return clone((BooleanFormulaTree) init, params);
123
124 throw new ClassCastException("Initialisation value for BooleanFormulaTree "
125 + "must be of type Integer (but is "
126 + init.getClass() + ")");
127 }
128
129 public BooleanFormulaTree clone(BooleanFormulaTree template, GAParameterSet params) {
130 BooleanFormulaTree copy = new BooleanFormulaTree(template.getNumberOfParameters());
131 copy.setFitness(template.getFitness());
132 Long trh = template.selectRootNode();
133 BooleanFormulaTreeNode nodeClone = template.exportNode(trh);
134 Long crh = copy.selectRootNode();
135 copy.replaceNode(crh, nodeClone);
136 return copy;
137 }
138
139 public BooleanFormulaTreeNode createRandomNode(int thisDepth, GAParameterSet params) {
140
141 BooleanFormulaTreeNode node = null;
142
143 if (thisDepth >= this.maxTreeDepth)
144 return createRandomStopNode(params);
145 node = createOneNodeOfRandomType(allowedNodeTypes, params);
146
147 for (int i = 0; i < node.getRequiredChildrenNumber(); i++) {
148 BooleanFormulaTreeNode child = createRandomNode(thisDepth + 1, params);
149 ((OperatorNode) node).setChild(i, child);
150 }
151
152 return node;
153
154 }
155
156 private BooleanFormulaTreeNode createRandomStopNode(GAParameterSet params) {
157 if (allowConstants)
158 return createOneNodeOfRandomType(stoppersWithConsts, params);
159 else
160 return createOneNodeOfRandomType(stoppersWithoutConsts, params);
161 }
162
163 private BooleanFormulaTreeNode createOneNodeOfRandomType(Class [] nodeTypes, GAParameterSet params) {
164
165 BooleanFormulaTreeNode node = null;
166
167 int rndType = params.getRandomGenerator().nextInt(0, nodeTypes.length);
168 Class type = nodeTypes[rndType];
169
170 try {
171 node = (BooleanFormulaTreeNode) type.newInstance();
172 } catch (InstantiationException e1) {
173 throw new Error("Dodgy: can't instantiate " + type.getName()
174 + ". (" + e1.getMessage() + ")");
175 } catch (IllegalAccessException e2) {
176 throw new Error("Dodgy: can't instantiate " + type.getName()
177 + ". (" + e2.getMessage() + ")");
178 }
179
180 assert null != node;
181
182 if (node instanceof TerminalNode) {
183 int rndTerm = params.getRandomGenerator().nextInt(0, this.numberOfParameters);
184 ((TerminalNode) node).setTerminalIndex(rndTerm);
185 }
186
187 return node;
188 }
189
190 /*
191 //TEST:
192 public static void main(String[] args) {
193 GAParameterSet params = new com.gregPaperin.ga.simpleImplementation.DefaultParameterSet();
194 BooleanFormulaTreeFactory fact = new BooleanFormulaTreeFactory();
195 fact.setMaxTreeDepth(6);
196 fact.setAllowConstants(false);
197 for (int i = 0; i < 5; i++) {
198 Individual form = fact.createRandomIndividual(params);
199 System.out.println(i + ") " + form);
200 }
201 }
202 */
203
204 }