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); } }