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