aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/parsers
diff options
context:
space:
mode:
Diffstat (limited to 'src/jcgp/backend/parsers')
-rw-r--r--src/jcgp/backend/parsers/ChromosomeParser.java189
-rw-r--r--src/jcgp/backend/parsers/FunctionParser.java53
-rw-r--r--src/jcgp/backend/parsers/ParameterParser.java77
-rw-r--r--src/jcgp/backend/parsers/TestCaseParser.java90
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.");
+ }
+}