aboutsummaryrefslogtreecommitdiffstats
path: root/src/jcgp/backend/population
diff options
context:
space:
mode:
authorEduardo Pedroni <ep625@york.ac.uk>2014-05-14 01:32:51 +0100
committerEduardo Pedroni <ep625@york.ac.uk>2014-05-14 01:32:51 +0100
commitc35a6806df01481c1b169cd0fc47660ea1cc10fb (patch)
tree7a9a90d88a9b962bcc091533997df798ac454423 /src/jcgp/backend/population
parent95b4a9421923cec63b6e0e8f58972d146100bd0f (diff)
Refactored Mutable, commented a little bit of the GUI package
Diffstat (limited to 'src/jcgp/backend/population')
-rw-r--r--src/jcgp/backend/population/Chromosome.java26
-rw-r--r--src/jcgp/backend/population/Mutable.java22
-rw-r--r--src/jcgp/backend/population/Node.java41
-rw-r--r--src/jcgp/backend/population/Output.java51
4 files changed, 98 insertions, 42 deletions
diff --git a/src/jcgp/backend/population/Chromosome.java b/src/jcgp/backend/population/Chromosome.java
index 673bb26..e28032c 100644
--- a/src/jcgp/backend/population/Chromosome.java
+++ b/src/jcgp/backend/population/Chromosome.java
@@ -149,7 +149,7 @@ public class Chromosome implements Comparable<Chromosome> {
// set random outputs
for (Output output : outputs) {
- output.setConnection(0, getRandomConnection());
+ output.setSource(getRandomConnection());
}
}
@@ -198,9 +198,9 @@ public class Chromosome implements Comparable<Chromosome> {
for (int o = 0; o < outputs.length; o++) {
copyOutput = clone.getOutput(o).getSource();
if (copyOutput instanceof Input) {
- outputs[o].setConnection(0, inputs[((Input) copyOutput).getIndex()]);
+ outputs[o].setSource(inputs[((Input) copyOutput).getIndex()]);
} else if (copyOutput instanceof Node) {
- outputs[o].setConnection(0, nodes[((Node) copyOutput).getRow()][((Node) copyOutput).getColumn()]);
+ outputs[o].setSource(nodes[((Node) copyOutput).getRow()][((Node) copyOutput).getColumn()]);
} else {
// something bad happened
System.out.println("Warning: Connection of subtype " + copyOutput.getClass().toString() + " is not explicitly handled by copy constructor.");
@@ -212,6 +212,16 @@ public class Chromosome implements Comparable<Chromosome> {
}
/**
+ * Returns a reference to the indexed input.
+ *
+ * @param index the input index.
+ * @return the input reference.
+ */
+ public Input getInput(int index) {
+ return inputs[index];
+ }
+
+ /**
* Returns a reference to any node, addressed by row and column.
*
* @param row the row of the node.
@@ -233,16 +243,6 @@ public class Chromosome implements Comparable<Chromosome> {
}
/**
- * Returns a reference to the indexed input.
- *
- * @param index the input index.
- * @return the input reference.
- */
- public Input getInput(int index) {
- return inputs[index];
- }
-
- /**
* @return the fitness of the chromosome.
*/
public double getFitness() {
diff --git a/src/jcgp/backend/population/Mutable.java b/src/jcgp/backend/population/Mutable.java
index 3ce7065..a5cbe37 100644
--- a/src/jcgp/backend/population/Mutable.java
+++ b/src/jcgp/backend/population/Mutable.java
@@ -8,8 +8,8 @@ package jcgp.backend.population;
* <br><br>
* This interface provides a way to deal with mutable elements
* generically without having to specify whether they are nodes
- * or outputs. In this way a random mutable element can be picked and
- * dealt with more easily, facilitating mutations.
+ * or outputs. When mutating a mutable, {@code mutate()} is guaranteed
+ * to perform a fair mutation.
*
* @author Eduardo Pedroni
*
@@ -17,14 +17,16 @@ package jcgp.backend.population;
public interface Mutable {
/**
- * This method sets the indexed connection to the specified new connection.
- * Implementing classes may choose to ignore the given index (such as in the
- * case of outputs, which only have one connection).
- *
- * @param index the connection index to set.
- * @param newConnection the chromosome element to connect to.
+ * This method performs an arbitrary mutation on the {@code Mutable}.
+ * <br><br>
+ * In the case of nodes, this chooses to mutate a function or connection
+ * fairly, and carries out the required mutation by using the node's own
+ * reference to chromosome.
+ * <br><br>
+ * In the case of outputs, this simply picks a random connection to serve
+ * as the source - any connection is allowed.
*/
- public void setConnection(int index, Connection newConnection);
+ public void mutate();
/**
* Asserts if the specified element is a copy of the elements
@@ -48,6 +50,6 @@ public interface Mutable {
* @param element the mutable element to compare to.
* @return true if {@code element} is a copy of this element.
*/
- boolean copyOf(Mutable element);
+ public boolean copyOf(Mutable element);
}
diff --git a/src/jcgp/backend/population/Node.java b/src/jcgp/backend/population/Node.java
index 3bcf3da..7712c50 100644
--- a/src/jcgp/backend/population/Node.java
+++ b/src/jcgp/backend/population/Node.java
@@ -3,6 +3,7 @@ package jcgp.backend.population;
import java.util.ArrayList;
import jcgp.backend.function.Function;
+import jcgp.backend.resources.Resources;
/**
* Nodes make up the main part of the chromosome,
@@ -16,6 +17,10 @@ import jcgp.backend.function.Function;
* (determined by the maximum arity of the function set)
* and must be reinstantiated if the experiment arity
* changes.
+ * <br><br>
+ * When mutating a node, it is easiest to use {@code mutate()}.
+ * Alternatively, you may also perform a specific mutation using
+ * {@code setConnection(...)} and {@code setFunction(...)}.
*
* @author Eduardo Pedroni
*
@@ -122,6 +127,24 @@ public class Node implements Mutable, Connection {
}
}
}
+
+ /**
+ * This method sets the indexed connection to the specified new connection.
+ * If the given connection is null or disrespects levels back, it is discarded
+ * and no connections are changed.
+ *
+ * @param index the connection index to set.
+ * @param newConnection the {@code Connection} to connect to.
+ */
+ public void setConnection(int index, Connection newConnection) {
+ // connection must not be null
+ if (newConnection != null) {
+ //if () {
+ connections[index] = newConnection;
+ chromosome.recomputeActiveNodes();
+ //}
+ }
+ }
@Override
public boolean copyOf(Mutable element) {
@@ -174,11 +197,19 @@ public class Node implements Mutable, Connection {
}
@Override
- public void setConnection(int index, Connection newConnection) {
- // connection must not be null
- if (newConnection != null) {
- connections[index] = newConnection;
- chromosome.recomputeActiveNodes();
+ public void mutate() {
+ Resources resources = chromosome.getResources();
+
+ // choose to mutate the function or a connection
+ int geneType = resources.getRandomInt(1 + resources.arity());
+
+ // if the int is less than 1, mutate function, else mutate connections
+ if (geneType < 1) {
+ setFunction(resources.getRandomFunction());
+ } else {
+ // if we decided to mutate connection, subtract 1 from geneType so it fits into the arity range
+ geneType--;
+ setConnection(geneType, chromosome.getRandomConnection(column));
}
}
diff --git a/src/jcgp/backend/population/Output.java b/src/jcgp/backend/population/Output.java
index 938741b..a346d4a 100644
--- a/src/jcgp/backend/population/Output.java
+++ b/src/jcgp/backend/population/Output.java
@@ -8,6 +8,10 @@ import java.util.ArrayList;
* returns the value of its single connection, but it
* may not be connected to - it terminates a chromosome
* active connection path.
+ * <br><br>
+ * When mutating an output, it is easiest to use {@code mutate()}.
+ * Alternatively, you may also perform a specific mutation using
+ * {@code setSource(...)}.
*
* @author Eduardo Pedroni
*
@@ -37,34 +41,47 @@ public class Output implements Mutable {
return source.getValue();
}
+ /**
+ * @return this output's index.
+ */
public int getIndex() {
return index;
}
+
+ /**
+ * This method sets the output source to the specified connection.
+ *
+ * @param newConnection the {@code Connection} to connect to.
+ */
+ public void setSource(Connection newConnection) {
+ source = newConnection;
+ // trigger active path recomputation
+ chromosome.recomputeActiveNodes();
+ }
+ /**
+ * @return the source of this output's value.
+ */
public Connection getSource() {
return source;
}
+ /**
+ * Calls {@code getActive(...)} on this output's
+ * source. This kicks off a recursive process whereby
+ * all nodes connected to this output are added to the
+ * specified list of nodes. This is used to create a
+ * list of all active nodes.
+ *
+ * @param activeNodes the list to add all active nodes to.
+ */
public void getActiveNodes(ArrayList<Node> activeNodes) {
+ // do not add if the source is an input
if (source instanceof Node) {
((Node) source).getActive(activeNodes);
}
}
- /**
- * When mutating an output, the index parameter
- * is simply ignored and the output source is
- * set.
- *
- * @see jcgp.backend.population.Mutable#setConnection(int, jcgp.backend.population.Connection)
- */
- @Override
- public void setConnection(int index, Connection newConnection) {
- source = newConnection;
- // trigger active path recomputation
- chromosome.recomputeActiveNodes();
- }
-
@Override
public boolean copyOf(Mutable m) {
// both cannot be the same instance
@@ -94,6 +111,12 @@ public class Output implements Mutable {
}
@Override
+ public void mutate() {
+ // simply change output to a new, random connection
+ setSource(chromosome.getRandomConnection());
+ }
+
+ @Override
public String toString() {
return "Output " + index;
}