diff options
Diffstat (limited to 'src/jcgp/backend/parsers')
-rw-r--r-- | src/jcgp/backend/parsers/ChromosomeParser.java | 189 | ||||
-rw-r--r-- | src/jcgp/backend/parsers/FunctionParser.java | 53 | ||||
-rw-r--r-- | src/jcgp/backend/parsers/ParameterParser.java | 77 | ||||
-rw-r--r-- | src/jcgp/backend/parsers/TestCaseParser.java | 90 |
4 files changed, 409 insertions, 0 deletions
diff --git a/src/jcgp/backend/parsers/ChromosomeParser.java b/src/jcgp/backend/parsers/ChromosomeParser.java new file mode 100644 index 0000000..fe58ff8 --- /dev/null +++ b/src/jcgp/backend/parsers/ChromosomeParser.java @@ -0,0 +1,189 @@ +package jcgp.backend.parsers; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.PrintWriter; +import java.util.Scanner; + +import jcgp.backend.population.Chromosome; +import jcgp.backend.population.Connection; +import jcgp.backend.population.Input; +import jcgp.backend.population.Node; +import jcgp.backend.resources.ModifiableResources; + +/** + * This class includes a method for parsing .chr files and another + * for writing .chr files from given chromosomes. + * + * @author Eduardo Pedroni + * + */ +public abstract class ChromosomeParser { + + /** + * Use this method to parse .chr files into a given chromosome. + * <br><br> + * This is not fully defensive as it doesn't check for number of inputs, + * doesn't compare rows and columns individually and doesn't account for levels back. It + * is not viable to implement these defensive measures with the chromosome format used + * by CGP. + * + * @param file the .chr file to parse from + * @param chromosome the chromosome to configure + * @param resources the experiment resources + */ + public static void parse(File file, Chromosome chromosome, ModifiableResources resources) { + /* + * Count the nodes to make sure the size of the .chr file matches the experiment parameters. + * + * We do this by using the scanner to get the node and output portions of the file as they + * are separated by 3 tab characters. Every number is replaced by a single known character, + * and the length of the string with the new characters is compared with that of a string + * where the new known character has been removed, yielding the total number of values. + * + * TODO this is NOT ideal and should be refactored + * + */ + FileReader fr; + try { + fr = new FileReader(file); + } catch (FileNotFoundException e) { + resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + "."); + return; + } + Scanner in = new Scanner(fr); + + in.useDelimiter("\\t\\t\\t"); + String geneString = in.next().replaceAll("[0-9]+", "g"); + String outString = in.next().replaceAll("[0-9]+", "o"); + int geneCount = geneString.length() - geneString.replace("g", "").length(); + int outCount = outString.length() - outString.replace("o", "").length(); + in.close(); + + + // if the acquired values match the current parameters, apply them to the chromosome + if ((geneCount == resources.nodes() * (resources.arity() + 1)) + && outCount == resources.outputs()) { + // prepare a new scanner + try { + fr = new FileReader(file); + } catch (FileNotFoundException e) { + resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + "."); + return; + } + in = new Scanner(fr); + + resources.println("[Parser] Parsing file: " + file.getAbsolutePath() + "..."); + + int gene; + Connection newConnection; + Node changingNode; + // for all nodes, columns first + for (int c = 0; c < resources.columns(); c++) { + for (int r = 0; r < resources.rows(); r++) { + // store the changing node + changingNode = chromosome.getNode(r, c); + + // for every connection + for (int i = 0; i < resources.arity(); i++) { + // get connection number from the .chr file + gene = in.nextInt(); + if (gene < resources.inputs()) { + // connection was an input + newConnection = chromosome.getInput(gene); + } else { + // connection was another node, calculate which from its number + newConnection = chromosome.getNode((gene - resources.inputs()) % resources.rows(), + (gene - resources.inputs()) / resources.rows()); + } + changingNode.setConnection(i, newConnection); + } + + // set the function, straight indexing should work - this is not entirely + // safe, but it is not viable to check for functionset compatibility + changingNode.setFunction(resources.getFunction(in.nextInt())); + } + } + + // outputs + for (int o = 0; o < resources.outputs(); o ++) { + gene = in.nextInt(); + if (gene < resources.inputs()) { + // connection was an input + newConnection = chromosome.getInput(gene); + } else { + // connection was another node, calculate which from its number + newConnection = chromosome.getNode((gene - resources.inputs()) % resources.rows(), + (gene - resources.inputs()) / resources.rows()); + } + chromosome.getOutput(o).setConnection(0, newConnection); + } + in.close(); + + resources.println("[Parser] File parsed successfully."); + + } else { + resources.println("[Parser] Error: the topology of the chromosome in " + file.getName() + " does not match that of the experiment."); + } + } + + /** + * Writes a chromosome into the specified .chr file. + * <br><br> + * The file is written in the standard .chr format and can + * be read by the original CGP implementation. + * + * @param file the file to write to + * @param chromosome the chromosome to save + */ + public static void save(File file, Chromosome chromosome, ModifiableResources resources) { + PrintWriter writer; + try { + writer = new PrintWriter(file); + } catch (FileNotFoundException e) { + resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + "."); + return; + } + + resources.println("[Parser] Saving to " + file.getAbsolutePath() + "..."); + + // for all nodes, columns first + for (int c = 0; c < resources.columns(); c++) { + for (int r = 0; r < resources.rows(); r++) { + for (int i = 0; i < resources.arity(); i++) { + // print the connections, separated by spaces + Connection conn = chromosome.getNode(r, c).getConnection(i); + if (conn instanceof Input) { + writer.print(" " + ((Input) conn).getIndex()); + } else if (conn instanceof Node) { + writer.print(" " + (((((Node) conn).getColumn() + 1) * resources.inputs()) + ((Node) conn).getRow())); + } else { + resources.println("[Parser] Error: could not handle " + conn.getClass() + " as a subclass of Connection"); + } + } + // print the function numbers + writer.print(" " + resources.getFunctionIndex(chromosome.getNode(r, c).getFunction())); + // node is done, print tab + writer.print("\t"); + } + } + // nodes are done, print two tabs to separate from output + writer.print("\t\t"); + for (int o = 0; o < resources.outputs(); o ++) { + Connection source = chromosome.getOutput(o).getSource(); + if (source instanceof Input) { + writer.print(" " + ((Input) source).getIndex()); + } else if (source instanceof Node) { + writer.print(" " + (((((Node) source).getColumn() + 1) * resources.inputs()) + ((Node) source).getRow())); + } else { + resources.println("[Parser] Error: could not handle " + source.getClass() + " as a subclass of Connection"); + } + } + + writer.close(); + + resources.println("[Parser] Chromosome saved successfully."); + } + +} diff --git a/src/jcgp/backend/parsers/FunctionParser.java b/src/jcgp/backend/parsers/FunctionParser.java new file mode 100644 index 0000000..6d6c73b --- /dev/null +++ b/src/jcgp/backend/parsers/FunctionParser.java @@ -0,0 +1,53 @@ +package jcgp.backend.parsers; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.Scanner; + +import jcgp.backend.function.FunctionSet; +import jcgp.backend.modules.problem.Problem; +import jcgp.backend.resources.ModifiableResources; + +/** + * Parses the functions from a .par file. + * Functions marked with a 1 will be enabled, + * and those marked with 0 are disabled. + * + * @author Eduardo Pedroni + * + */ +public abstract class FunctionParser { + + public static void parseFunctions(File file, Problem problem, ModifiableResources resources) { + + FileReader fr; + try { + fr = new FileReader(file); + } catch (FileNotFoundException e) { + resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + "."); + return; + } + + Scanner in = new Scanner(fr); + FunctionSet functionSet = problem.getFunctionSet(); + resources.println("[Parser] Parsing file: " + file.getAbsolutePath() + "..."); + + while (in.hasNextLine()) { + String line = in.nextLine(); + if (line.substring(line.length() - 1).matches("[0-9]")) { + String[] splitString = line.split("[^0-9]+"); + int functionIndex = Integer.parseInt(splitString[splitString.length - 1]); + if (Integer.parseInt(splitString[0]) != 0 && !functionSet.isEnabled(functionSet.getFunction(functionIndex))) { + functionSet.enableFunction(functionIndex); + resources.println("[Parser] Enabled function: " + functionSet.getFunction(functionIndex).getName() + "."); + } else if (Integer.parseInt(splitString[0]) == 0 && functionSet.isEnabled(functionSet.getFunction(functionIndex))) { + functionSet.disableFunction(functionIndex); + resources.println("[Parser] Disabled function: " + functionSet.getFunction(functionIndex).getName() + "."); + } + } + } + in.close(); + resources.println("[Parser] Finished parsing functions."); + } +} diff --git a/src/jcgp/backend/parsers/ParameterParser.java b/src/jcgp/backend/parsers/ParameterParser.java new file mode 100644 index 0000000..ae72126 --- /dev/null +++ b/src/jcgp/backend/parsers/ParameterParser.java @@ -0,0 +1,77 @@ +package jcgp.backend.parsers; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.Scanner; + +import jcgp.backend.resources.ModifiableResources; + +public abstract class ParameterParser { + + public static void parseParameters(File file, ModifiableResources resources) { + + FileReader fr; + try { + fr = new FileReader(file); + } catch (FileNotFoundException e) { + resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + "."); + return; + } + + Scanner in = new Scanner(fr); + resources.println("[Parser] Parsing file: " + file.getAbsolutePath() + "..."); + + while (in.hasNextLine()) { + String[] splitString = in.nextLine().split("( |\t)+"); + + switch (splitString[1]) { + case "population_size": + resources.setPopulationSize(Integer.parseInt(splitString[0])); + resources.println("[Parser] Population size is now " + resources.populationSize() + "."); + break; + + case "num_generations": + resources.setGenerations(Integer.parseInt(splitString[0])); + resources.println("[Parser] Total generations is now " + resources.generations() + "."); + break; + + case "num_runs_total": + resources.setRuns(Integer.parseInt(splitString[0])); + resources.println("[Parser] Total runs is now " + resources.runs() + "."); + break; + + case "num_rows": + resources.setRows(Integer.parseInt(splitString[0])); + resources.println("[Parser] Row number is now " + resources.rows() + "."); + break; + + case "num_cols": + resources.setColumns(Integer.parseInt(splitString[0])); + resources.println("[Parser] Column number is now " + resources.columns() + "."); + break; + + case "levels_back": + resources.setLevelsBack(Integer.parseInt(splitString[0])); + resources.println("[Parser] Levels back is now " + resources.levelsBack() + "."); + break; + + case "report_interval": + resources.setReportInterval(Integer.parseInt(splitString[0])); + resources.println("[Parser] Report interval is now " + resources.levelsBack() + "."); + break; + + case "global_seed": + resources.setSeed(Integer.parseInt(splitString[0])); + resources.println("[Parser] Seed is now " + resources.seed() + "."); + break; + + default: + break; + } + } + + in.close(); + resources.println("[Parser] Finished parsing parameters."); + } +} diff --git a/src/jcgp/backend/parsers/TestCaseParser.java b/src/jcgp/backend/parsers/TestCaseParser.java new file mode 100644 index 0000000..cef018e --- /dev/null +++ b/src/jcgp/backend/parsers/TestCaseParser.java @@ -0,0 +1,90 @@ +package jcgp.backend.parsers; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.util.Scanner; + +import jcgp.backend.modules.problem.TestCaseProblem; +import jcgp.backend.resources.ModifiableResources; + +public abstract class TestCaseParser { + + public static void parse(File file, TestCaseProblem<?> problem, ModifiableResources resources) { + FileReader fr; + try { + fr = new FileReader(file); + } catch (FileNotFoundException e) { + resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + "."); + return; + } + resources.println("[Parser] Parsing file: " + file.getAbsolutePath() + "..."); + Scanner in = new Scanner(fr); + boolean readingTestCases = false; + int inputs = 0, outputs = 0; + int cases = 0; + + problem.clearTestCases(); + + while (in.hasNextLine()) { + String nextLine = in.nextLine(); + + if (nextLine.startsWith(".i")) { + String[] split = nextLine.split(" +"); + inputs = Integer.parseInt(split[1]); + } else if (nextLine.startsWith(".o")) { + String[] split = nextLine.split(" +"); + outputs = Integer.parseInt(split[1]); + } else if (nextLine.startsWith(".p") || nextLine.startsWith(".t")) { + readingTestCases = true; + } else if (nextLine.startsWith(".e")) { + readingTestCases = false; + } else if (readingTestCases) { + String[] split = nextLine.split("( |\t)+"); + String[] inputCases = new String[inputs]; + String[] outputCases = new String[outputs]; + for (int i = 0; i < inputs; i++) { + inputCases[i] = split[i]; + } + for (int o = 0; o < outputs; o++) { + outputCases[o] = split[o + inputs]; + } + + problem.addTestCase(inputCases, outputCases); + cases++; + } + } + resources.println("[Parser] Finished, added " + cases + " test cases."); + in.close(); + } + + public static void parseParameters(File file, ModifiableResources resources) { + + FileReader fr; + try { + fr = new FileReader(file); + } catch (FileNotFoundException e) { + resources.println("[Parser] Error: could not find " + file.getAbsolutePath() + "."); + return; + } + + resources.println("[Parser] Parsing parameters..."); + Scanner in = new Scanner(fr); + + while (in.hasNextLine()) { + String nextLine = in.nextLine(); + if (nextLine.startsWith(".i")) { + String[] split = nextLine.split(" +"); + resources.setInputs(Integer.parseInt(split[1])); + resources.println("[Parser] Number of inputs set to " + resources.inputs()); + } else if (nextLine.startsWith(".o")) { + String[] split = nextLine.split(" +"); + resources.setOutputs(Integer.parseInt(split[1])); + resources.println("[Parser] Number of outputs set to " + resources.outputs()); + } + } + in.close(); + + resources.println("[Parser] Finished parsing parameters."); + } +} |