aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/resources/Resources.java
blob: 59a29ea1632c47ee0ce4289624b712e2e2ac5cd1 (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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
package jcgp.backend.resources;

import java.util.Random;

import jcgp.backend.function.Function;
import jcgp.backend.function.FunctionSet;
import jcgp.backend.modules.problem.BestFitness;
import jcgp.backend.parameters.IntegerParameter;

/**
 * 
 * Encapsulates all of the resources based on which the program operates.
 * Each instance of JCGP contains a single instance of {@code Resources}.
 * <br><br>
 * The experiment's {@code Resources} object is passed to modules as the program operates, and
 * the actual parameter values can be obtained using getter methods. Note that, for code brevity,
 * this class's getters do not start with the word "get". For instance, to get the number of rows, 
 * one would use {@code rows()} instead of {@code getRows()} which doesn't exist.
 * The fitness orientation of the problem being solved can also be retrieved using {@code fitnessOrientation()}.
 * Evolutionary strategies will typically use this to perform selection.
 * <br><br>
 * In addition to parameters, this class also offers utility methods. Any necessary random numbers
 * should be obtained using {@code getRandomInt()} and {@code getRandomDouble()} as these methods
 * use a particular {@code Random} object guaranteed to generate random numbers based on the seed 
 * parameter. Functions from the selected function set can be obtained through this class as well.
 * Finally, printing to the console should be done via the resources using the report and print
 * methods, so that these prints also get sent to the GUI console (if one is present).
 * 
 * @see jcgp.backend.parameters.Parameter
 * @author Eduardo Pedroni
 *
 */
public class Resources {
	protected IntegerParameter rows, columns, inputs, outputs, populationSize,
			levelsBack, currentGeneration, generations, currentRun, runs,
			arity, seed, reportInterval;

	protected Random numberGenerator = new Random();
	protected FunctionSet functionSet;
	
	protected Console console;
	
	protected BestFitness fitnessOrientation;
	
	/**
	 * @return the number of rows.
	 */
	public int rows() {
		return rows.get();
	}

	/**
	 * @return the number of columns.
	 */
	public int columns() {
		return columns.get();
	}

	/**
	 * @return the number of inputs.
	 */
	public int inputs() {
		return inputs.get();
	}

	/**
	 * @return the number of outputs.
	 */
	public int outputs() {
		return outputs.get();
	}

	/**
	 * @return the population size.
	 */
	public int populationSize() {
		return populationSize.get();
	}

	/**
	 * @return the levels back value.
	 */
	public int levelsBack() {
		return levelsBack.get();
	}

	/**
	 * @return the total number of nodes.
	 */
	public int nodes() {
		return columns.get() * rows.get();
	}

	/**
	 * @return the current generation.
	 */
	public int currentGeneration() {
		return currentGeneration.get();
	}

	/**
	 * @return the total number of generations.
	 */
	public int generations() {
		return generations.get();
	}

	/**
	 * @return the current run.
	 */
	public int currentRun() {
		return currentRun.get();
	}

	/**
	 * @return the total number of runs.
	 */
	public int runs() {
		return runs.get();
	}

	/**
	 * @return the maximum arity out of the function set.
	 */
	public int arity() {
		return arity.get();
	}

	/**
	 * @return the random seed being used.
	 */
	public int seed() {
		return seed.get();
	}

	/**
	 * @return the report interval.
	 */
	public int reportInterval() {
		return reportInterval.get();
	}
	
	/**
	 * @return the fitness orientation.
	 */
	public BestFitness fitnessOrientation() {
		return fitnessOrientation;
	}
	
	/*
	 * Utility functions
	 */
	/**
	 * Gets the next random integer using the experiment's random
	 * number generator. The integer returned will be between 0 (inclusive)
	 * and limit (exclusive).
	 * 
	 * @param limit the limit value.
	 * @return a random integer between 0 and limit.
	 */
	public int getRandomInt(int limit) {
		return numberGenerator.nextInt(limit);
	}
	
	/**
	 * Gets the next random double using the experiment's random
	 * number generator. The double returned will be between 0 (inclusive)
	 * and limit (exclusive).
	 * 
	 * @param limit the limit value.
	 * @return a random double between 0 and limit.
	 */
	public double getRandomDouble(int limit) {
		return numberGenerator.nextDouble() * limit;
	}
	
	/**
	 * Gets the next random integer using the experiment's random
	 * number generator. The integer returned will be between 0 (inclusive)
	 * and 1 (exclusive).
	 * 
	 * @return a random integer between 0 and 1.
	 */
	public double getRandomDouble() {
		return numberGenerator.nextDouble();
	}
	
	/*
	 * FunctionSet functions
	 */
	/**
	 * Gets a random allowed function from the problem function set.
	 * This function uses {@code getRandomInt()} to choose the random
	 * function.
	 * 
	 * @return a random allowed function.
	 */
	public Function getRandomFunction() {
		Function f = functionSet.getAllowedFunction(numberGenerator.nextInt(functionSet.getAllowedFunctionCount()));
		return f;
	}

	/**
	 * Gets the indexed function out of the
	 * complete set of functions.
	 * 
	 * @param index the function to return.
	 * @return the indexed function.
	 */
	public Function getFunction(int index) {
		return functionSet.getFunction(index);
	}
	
	/**
	 * @return the problem's function set.
	 */
	public FunctionSet getFunctionSet() {
		return functionSet;
	}
	
	/**
	 * Returns the index of a specified function. If the function is not found,
	 * -1 is returned.
	 * 
	 * @param function the function with unknown index.
	 * @return the index of the function, or -1 if it was not found.
	 */
	public int getFunctionIndex(Function function) {
		for (int i = 0; i < functionSet.getTotalFunctionCount(); i++) {
			if (function == functionSet.getFunction(i)) {
				return i;
			}
		}
		// not found, default to -1
		return -1;
	}
	
	/*
	 * Console functionality
	 * These are affected by parameter report interval
	 */
	/**
	 * Prints a message to the consoles taking into account the
	 * report interval parameter. If no reports are allowed in
	 * the current generation, this does nothing.
	 * <br>
	 * This method automatically appends a line break to the message
	 * being printed.
	 * 
	 * @param message the message to print.
	 */
	public void reportln(String message) {
		if (reportInterval.get() > 0) {
			if (currentGeneration.get() % reportInterval.get() == 0) {
				System.out.println(message);
				if (console != null) {
					console.println(message);
				}
			}
		}
	}
	
	/**
	 * Prints a message to the consoles taking into account the
	 * report interval parameter. If no reports are allowed in
	 * the current generation, this does nothing.
	 * <br>
	 * This method does not append a line break to the message
	 * being printed.
	 * 
	 * @param message the message to print.
	 */
	public void report(String message) {
		if (reportInterval.get() > 0) {
			if (currentGeneration.get() % reportInterval.get() == 0) {
				System.out.print(message);
				if (console != null) {
					console.print(message);
				}
			}
		}
	}
	
	/*
	 * Console functionality
	 * These are not affected by parameter report interval
	 */
	/**
	 * Prints a message to the consoles ignoring
	 * report interval. In other words, messages printed 
	 * using this method will always appear (though the
	 * GUI console will still need to be flushed).
	 * <br>
	 * This method automatically appends a line break to the message
	 * being printed.
	 * 
	 * @param message the message to print.
	 */
	public void println(String message) {
		System.out.println(message);
		if (console != null) {
			console.println(message);
		}
	}
	
	/**
	 * Prints a message to the consoles ignoring
	 * report interval. In other words, messages printed 
	 * using this method will always appear (though the
	 * GUI console will still need to be flushed).
	 * <br>
	 * This method does not append a line break to the message
	 * being printed.
	 * 
	 * @param message the message to print.
	 */
	public void print(String message) {
		System.out.print(message);
		if (console != null) {
			console.print(message);
		}
	}
}