View Javadoc
1   package net.bmahe.genetics4j.gp.math;
2   
3   import java.util.List;
4   import java.util.Objects;
5   import java.util.random.RandomGenerator;
6   import java.util.stream.Collectors;
7   import java.util.stream.IntStream;
8   
9   import org.apache.commons.lang3.Validate;
10  
11  import net.bmahe.genetics4j.gp.OperationFactories;
12  import net.bmahe.genetics4j.gp.OperationFactory;
13  
14  public class Terminals {
15  
16  	public static final String TYPE_COEFFICIENT = "Coefficient";
17  	public static final String TYPE_COEFFICIENT_INT = "CoefficientInt";
18  	public static final String TYPE_INPUT = "Input";
19  
20  	public static final String NAME_PI = "PI";
21  	public static final String NAME_E = "E";
22  
23  	public static OperationFactory PI = OperationFactories.ofTerminal(NAME_PI, Double.class, () -> Math.PI);
24  
25  	public static OperationFactory E = OperationFactories.ofTerminal(NAME_E, Double.class, () -> Math.E);
26  
27  	public static OperationFactory Coefficient(final RandomGenerator randomGenerator, final double min,
28  			final double max) {
29  		return OperationFactories.ofOperationSupplier(new Class[] {}, Double.class, () -> {
30  
31  			final double value = randomGenerator.nextDouble() * (max - min) + min;
32  
33  			final var operationBuilder = ImmutableCoefficientOperation.builder();
34  
35  			operationBuilder.name(TYPE_COEFFICIENT)
36  					.prettyName(TYPE_COEFFICIENT + "[" + value + "]")
37  					.returnedType(Double.class)
38  					.value(value);
39  
40  			return operationBuilder.build();
41  		});
42  	}
43  
44  	public static OperationFactory CoefficientRounded(final RandomGenerator randomGenerator, final int min,
45  			final int max) {
46  		return OperationFactories.ofOperationSupplier(new Class[] {}, Double.class, () -> {
47  
48  			final double value = randomGenerator.nextInt(max - min) + min;
49  
50  			final var operationBuilder = ImmutableCoefficientOperation.builder();
51  			operationBuilder.name(TYPE_COEFFICIENT)
52  					.prettyName("CoefficientRounded[" + value + "]")
53  					.returnedType(Double.class)
54  					.value(value);
55  
56  			return operationBuilder.build();
57  		});
58  	}
59  
60  	public static OperationFactory CoefficientInt(final RandomGenerator randomGenerator, final int min, final int max) {
61  		return OperationFactories.ofOperationSupplier(new Class[] {}, Integer.class, () -> {
62  
63  			final int value = randomGenerator.nextInt(max - min) + min;
64  
65  			final var operationBuilder = ImmutableCoefficientOperation.builder();
66  			operationBuilder.name(TYPE_COEFFICIENT_INT)
67  					.prettyName("CoefficientInt[" + value + "]")
68  					.returnedType(Integer.class)
69  					.value(value);
70  
71  			return operationBuilder.build();
72  		});
73  	}
74  
75  	@SuppressWarnings({ "unchecked", "rawtypes" })
76  	public static <T> OperationFactory Input(final int inputIndex, final Class<T> clazz) {
77  		Validate.isTrue(inputIndex >= 0);
78  		Objects.requireNonNull(clazz);
79  
80  		return OperationFactories.of(new Class[] {}, clazz, inputSpec -> {
81  			final List<Class> types = inputSpec.types();
82  			Validate.isTrue(types.get(inputIndex).isAssignableFrom(clazz));
83  
84  			final var operationBuilder = ImmutableInputOperation.builder();
85  			operationBuilder.name(TYPE_INPUT)
86  					.prettyName(TYPE_INPUT + "[" + inputIndex + "]")
87  					.returnedType(clazz)
88  					.index(inputIndex);
89  
90  			return operationBuilder.build();
91  		});
92  	}
93  
94  	@SuppressWarnings({ "unchecked", "rawtypes" })
95  	public static <T> OperationFactory Input(final RandomGenerator randomGenerator, final Class<T> clazz) {
96  		Objects.requireNonNull(randomGenerator);
97  		Objects.requireNonNull(clazz);
98  
99  		return OperationFactories.of(new Class[] {}, clazz, inputSpec -> {
100 			final List<Class> types = inputSpec.types();
101 			final List<Integer> candidates = IntStream.range(0, types.size())
102 					.filter(i -> types.get(i).isAssignableFrom(clazz))
103 					.boxed()
104 					.collect(Collectors.toList());
105 
106 			if (candidates.isEmpty()) {
107 				throw new IllegalArgumentException("No input with type " + clazz + " found");
108 			}
109 
110 			final Integer inputIdx = candidates.get(randomGenerator.nextInt(candidates.size()));
111 
112 			final var operationBuilder = ImmutableInputOperation.builder();
113 			operationBuilder.name(TYPE_INPUT)
114 					.prettyName(TYPE_INPUT + "[" + inputIdx + "]")
115 					.returnedType(clazz)
116 					.index(inputIdx);
117 
118 			return operationBuilder.build();
119 		});
120 	}
121 
122 	public static OperationFactory InputDouble(final RandomGenerator randomGenerator) {
123 		return Input(randomGenerator, Double.class);
124 	}
125 
126 	public static OperationFactory InputString(final RandomGenerator randomGenerator) {
127 		return Input(randomGenerator, String.class);
128 	}
129 }