aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/Utilities.java
blob: f0525950b29a219c1931655bbe3fc97def08baed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package jcgp;

import java.util.Random;

import jcgp.function.Function;
import jcgp.function.FunctionSet;
import jcgp.population.*;

public class Utilities {
	
	private static Random numberGenerator;
	private static FunctionSet functionSet;
	
	public static void setResources(Random numberGenerator, FunctionSet functionSet) {
		Utilities.numberGenerator = numberGenerator;
		Utilities.functionSet = functionSet;
	}

	public static int getRandomInt(int limit){
		return numberGenerator.nextInt(limit);
	}

	public static double getRandomDouble(int limit){
		return numberGenerator.nextDouble() * limit;
	}

	/**
	 * Returns a random allowed connection respecting levels back.
	 * This method may always pick inputs, as they can be picked
	 * regardless of the column.
	 * 
	 * TODO remove?
	 * 
	 * @param chromosome the chromosome to pick from
	 * @param column the column to use as reference
	 * @return a random connection
	 */
	public static Connection getRandomConnection(Chromosome chromosome, int column){
		// work out the allowed range obeying levels back
		int allowedColumns = ((column >= Parameters.getLevelsBack()) ? Parameters.getLevelsBack() : column);
		int offset = column - allowedColumns;

		// choose input or node
		int connectionType = getRandomInt(Parameters.getInputs() + (Parameters.getRows() * allowedColumns));
		if (connectionType < Parameters.getInputs()) {
			// input
			return chromosome.getInput(getRandomInt(Parameters.getInputs()));
		} else {
			// node				
			return chromosome.getNode(getRandomInt(Parameters.getRows()), getRandomInt(allowedColumns) + offset);
		}
	}

	/**
	 * Returns a random allowed connection. 
	 * 
	 * This method may always pick inputs, as they can be picked
	 * regardless of the column.
	 * 
	 * TODO remove?
	 * 
	 * @param chromosome the chromosome to pick from
	 * @param column the column to use as reference
	 * @param levelsBack whether or not to respect levels back
	 * @return a random connection
	 */
	public static Connection getRandomConnection(Chromosome chromosome, int column, boolean levelsBack){
		if (levelsBack) {
			return getRandomConnection(chromosome, column);
		} else {
			// choose input or node
			int connectionType = getRandomInt(Parameters.getInputs() + (Parameters.getRows() * column));
			if (connectionType < Parameters.getInputs()) {
				// input
				return chromosome.getInput(getRandomInt(Parameters.getInputs()));
			} else {
				// node				
				return chromosome.getNode(getRandomInt(Parameters.getRows()), getRandomInt(column));
			}
		}
	}

	/**
	 * @param chromosome the chromosome to choose from
	 * @return a random input
	 */
	public static Input getRandomInput(Chromosome chromosome){
		return chromosome.getInput(getRandomInt(Parameters.getInputs()));
	}

	/**
	 * Returns a random allowed node respecting levels back.
	 * 
	 * This method will NOT pick inputs.
	 * 
	 * @param chromosome the chromosome to pick from
	 * @param column the column to use as reference
	 * @return a random node
	 */
	public static Node getRandomNode(Chromosome chromosome, int column){
		// work out the allowed range obeying levels back
		int allowedColumns = ((column >= Parameters.getLevelsBack()) ? Parameters.getLevelsBack() : column);
		int offset = column - allowedColumns;

		// pick a random allowed column and row
		int randomColumn = (getRandomInt(allowedColumns) + offset);
		int randomRow = (getRandomInt(Parameters.getRows()));

		return chromosome.getNode(randomRow, randomColumn);
	}

	/**
	 * Returns a random allowed node.
	 * 
	 * This method will NOT pick inputs.
	 * 
	 * @param chromosome the chromosome to pick from
	 * @param column the column to use as reference
	 * @param levelsBack whether or not to respect levels back
	 * @return a random node
	 */
	public static Node getRandomNode(Chromosome chromosome, int column, boolean levelsBack){
		if (levelsBack) {
			return getRandomNode(chromosome, column);
		} else {
			// pick any random column before the given column
			int randomColumn = (getRandomInt(column));
			// pick a random rowgetColumns
			int randomRow = (getRandomInt(Parameters.getRows()));
			return chromosome.getNode(randomRow, randomColumn);
		}
	}

	/**
	 * This method picks a random mutable element from the given chromosome.
	 * 
	 * It will pick outputs or nodes fairly.
	 * 
	 * TODO probably remove this
	 * 
	 * @param chromosome the chromosome to pick from
	 * @return a random mutable element
	 */
	public static MutableElement getRandomMutable(Chromosome chromosome){
		// choose output or node
		int connectionType = getRandomInt(Parameters.getOutputs() + Parameters.getNodeCount());

		if (connectionType < Parameters.getOutputs()) {
			// outputs
			return chromosome.getOutput(getRandomInt(Parameters.getOutputs()));
		} else {
			// node				
			return chromosome.getNode(getRandomInt(Parameters.getRows()), getRandomInt(Parameters.getRows()));
		}
	}		

	/**
	 * pick from any column - use this for setting outputs
	 * 
	 * @param chromosome
	 * @return
	 */
	public static Node getRandomNode(Chromosome chromosome) {
		return chromosome.getNode(getRandomInt(Parameters.getRows()), getRandomInt(Parameters.getColumns()));
	}

	public static Function getRandomFunction() {
		return functionSet.getFunction(Utilities.getRandomInt(functionSet.getFunctionCount()));
	}

	public static Function getFunction(int index) {
		return functionSet.getFunction(index);
	}

}