1 package net.bmahe.genetics4j.gp.program;
2
3 import java.util.random.RandomGenerator;
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 StdProgramGenerator implements ProgramGenerator {
12
13 private final ProgramHelper programHelper;
14 private final RandomGenerator randomGenerator;
15
16 @SuppressWarnings({ "unchecked", "rawtypes" })
17 private <T, U> TreeNode<Operation<T>> generate(final Program program, Class<U> acceptedType, int maxDepth,
18 int depth) {
19
20 OperationFactory currentNode = depth < maxDepth - 1 && randomGenerator.nextDouble() < 0.5
21 ? programHelper.pickRandomFunction(program, acceptedType)
22 : programHelper.pickRandomTerminal(program, acceptedType);
23
24 final Operation<T> currentOperation = currentNode.build(program.inputSpec());
25 final TreeNode<Operation<T>> currentTreeNode = new TreeNode<>(currentOperation);
26
27 final Class[] acceptedTypes = currentNode.acceptedTypes();
28
29 for (int i = 0; i < acceptedTypes.length; i++) {
30 final Class childAcceptedType = acceptedTypes[i];
31 final TreeNode<Operation<T>> operation = generate(program, childAcceptedType, maxDepth, depth + 1);
32
33 currentTreeNode.addChild(operation);
34 }
35
36 return currentTreeNode;
37 }
38
39 public StdProgramGenerator(final ProgramHelper _programHelper, final RandomGenerator _randomGenerator) {
40 Validate.notNull(_programHelper);
41 Validate.notNull(_randomGenerator);
42
43 this.programHelper = _programHelper;
44 this.randomGenerator = _randomGenerator;
45 }
46
47 @SuppressWarnings("rawtypes")
48 @Override
49 public TreeNode<Operation<?>> generate(final Program program, final int maxDepth) {
50 Validate.notNull(program);
51 Validate.isTrue(maxDepth > 0);
52
53 final OperationFactory currentNode = randomGenerator.nextDouble() < 0.98
54 ? programHelper.pickRandomFunction(program)
55 : programHelper.pickRandomTerminal(program);
56
57 final Operation currentOperation = currentNode.build(program.inputSpec());
58 final TreeNode<Operation<?>> currentTreeNode = new TreeNode<>(currentOperation);
59
60 Class[] acceptedTypes = currentNode.acceptedTypes();
61
62 for (int i = 0; i < acceptedTypes.length; i++) {
63 final Class acceptedType = acceptedTypes[i];
64 final TreeNode<Operation<?>> operation = generate(program, acceptedType, maxDepth, 1);
65
66 currentTreeNode.addChild(operation);
67 }
68
69 return currentTreeNode;
70 }
71
72 @Override
73 public TreeNode<Operation<?>> generate(final Program program) {
74 return generate(program, program.maxDepth());
75 }
76
77 @Override
78 public <T, U> TreeNode<Operation<T>> generate(final Program program, final int maxDepth, final Class<U> rootType) {
79 Validate.notNull(program);
80 Validate.notNull(rootType);
81 Validate.isTrue(maxDepth > 0);
82
83 return generate(program, rootType, maxDepth, 0);
84 }
85 }