1 package net.bmahe.genetics4j.gp.program;
2
3 import org.apache.commons.lang3.Validate;
4
5 import net.bmahe.genetics4j.core.chromosomes.TreeNode;
6 import net.bmahe.genetics4j.gp.Operation;
7 import net.bmahe.genetics4j.gp.OperationFactory;
8
9 public class FullProgramGenerator implements ProgramGenerator {
10
11 private final ProgramHelper programHelper;
12
13 @SuppressWarnings({ "unchecked", "rawtypes" })
14 private <T, U> TreeNode<Operation<T>> generate(final Program program, final Class<U> acceptedType,
15 final int maxDepth, final int depth) {
16
17 OperationFactory currentNode = depth < maxDepth - 1 ? programHelper.pickRandomFunction(program, acceptedType)
18 : programHelper.pickRandomTerminal(program, acceptedType);
19
20 final Operation<T> currentOperation = currentNode.build(program.inputSpec());
21 final TreeNode<Operation<T>> currentTreeNode = new TreeNode<>(currentOperation);
22
23 final Class[] acceptedTypes = currentNode.acceptedTypes();
24
25 for (int i = 0; i < acceptedTypes.length; i++) {
26 final Class childAcceptedType = acceptedTypes[i];
27 final TreeNode<Operation<T>> operation = generate(program, childAcceptedType, maxDepth, depth + 1);
28
29 currentTreeNode.addChild(operation);
30 }
31
32 return currentTreeNode;
33 }
34
35 public FullProgramGenerator(final ProgramHelper _programHelper) {
36 Validate.notNull(_programHelper);
37
38 this.programHelper = _programHelper;
39 }
40
41 @Override
42 public TreeNode<Operation<?>> generate(final Program program) {
43 return generate(program, program.maxDepth());
44 }
45
46 @SuppressWarnings("rawtypes")
47 @Override
48 public TreeNode<Operation<?>> generate(final Program program, final int maxDepth) {
49 Validate.notNull(program);
50 Validate.isTrue(maxDepth > 0);
51
52 final OperationFactory currentNode = programHelper.pickRandomFunction(program);
53
54 final Operation currentOperation = currentNode.build(program.inputSpec());
55 final TreeNode<Operation<?>> currentTreeNode = new TreeNode<>(currentOperation);
56
57 Class[] acceptedTypes = currentNode.acceptedTypes();
58
59 for (int i = 0; i < acceptedTypes.length; i++) {
60 final Class acceptedType = acceptedTypes[i];
61 final TreeNode<Operation<?>> operation = generate(program, acceptedType, maxDepth, 1);
62
63 currentTreeNode.addChild(operation);
64 }
65
66 return currentTreeNode;
67 }
68
69 @Override
70 public <T, U> TreeNode<Operation<T>> generate(final Program program, final int maxDepth, final Class<U> rootType) {
71 Validate.notNull(program);
72 Validate.notNull(rootType);
73 Validate.isTrue(maxDepth > 0);
74
75 return generate(program, rootType, maxDepth, 0);
76 }
77 }