From 36f4393bcc9e55afa2334baa33e603ce839741a1 Mon Sep 17 00:00:00 2001 From: Eduardo Pedroni Date: Thu, 1 May 2014 13:05:27 +0100 Subject: Did more commenting, implemented reflection and statistics --- .../backend/function/DigitalCircuitFunctions.java | 85 ++++++++++++++++++++-- src/jcgp/backend/function/Function.java | 6 +- src/jcgp/backend/function/FunctionSet.java | 64 +++++++++------- .../function/SymbolicRegressionFunctions.java | 21 ++++-- .../function/TravellingSalesmanFunctions.java | 19 +++-- src/jcgp/backend/function/UnsignedInteger.java | 20 +++-- 6 files changed, 166 insertions(+), 49 deletions(-) (limited to 'src/jcgp/backend/function') diff --git a/src/jcgp/backend/function/DigitalCircuitFunctions.java b/src/jcgp/backend/function/DigitalCircuitFunctions.java index 31cdf17..0d4ae8e 100644 --- a/src/jcgp/backend/function/DigitalCircuitFunctions.java +++ b/src/jcgp/backend/function/DigitalCircuitFunctions.java @@ -1,10 +1,23 @@ package jcgp.backend.function; +/** + * This class contains all digital circuit functions + * (defined as unsigned integer functions in the classic + * CGP implementation) defined in static nested classes. + *
+ * This is the function set used by DigitalCircuitProblem. + * + * @see DigitalCircuiProblem + * @author Eduardo Pedroni + * + */ public class DigitalCircuitFunctions extends FunctionSet { + /** + * Creates a new instance of DigitalCircuitFunctions. + */ public DigitalCircuitFunctions() { - name = "32-bit Logic"; - functionList = new Function[]{ + registerFunctions( new ConstantZero(), new ConstantOne(), new WireA(), @@ -25,11 +38,12 @@ public class DigitalCircuitFunctions extends FunctionSet { new Mux2(), new Mux3(), new Mux4() - }; - - enableAll(); + ); } + /** + * Outputs a constant 0, has no inputs. + */ public static class ConstantZero extends Function { @Override public UnsignedInteger run(Object... args) { @@ -47,6 +61,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * Outputs a constant 1, has no inputs. + */ public static class ConstantOne extends Function { @Override public UnsignedInteger run(Object... args) { @@ -64,6 +81,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * Connects one node to another with no function. + */ public static class WireA extends Function { @Override public UnsignedInteger run(Object... args) { @@ -85,6 +105,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * Connects one node to another with no function. + */ public static class WireB extends Function { @Override public UnsignedInteger run(Object... args) { @@ -106,6 +129,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * Inverts input, equivalent to inverter logic gate. + */ public static class NotA extends Function { @Override public UnsignedInteger run(Object... args) { @@ -127,6 +153,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * Inverts input, equivalent to inverter logic gate. + */ public static class NotB extends Function { @Override public UnsignedInteger run(Object... args) { @@ -148,6 +177,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * ANDs inputs together. + */ public static class And extends Function { @Override public UnsignedInteger run(Object... args) { @@ -173,6 +205,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * ANDs inputs together with one input inverted. + */ public static class AndNotA extends Function { @Override public UnsignedInteger run(Object... args) { @@ -198,6 +233,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * ANDs inputs together with one input inverted. + */ public static class AndNotB extends Function { @Override public UnsignedInteger run(Object... args) { @@ -223,6 +261,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * NORs inputs together. + */ public static class Nor extends Function { @Override public UnsignedInteger run(Object... args) { @@ -248,6 +289,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * XORs inputs together. + */ public static class Xor extends Function { @Override public UnsignedInteger run(Object... args) { @@ -273,6 +317,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * XNORs inputs together. + */ public static class Xnor extends Function { @Override public UnsignedInteger run(Object... args) { @@ -298,6 +345,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * ORs inputs together. + */ public static class Or extends Function { @Override public UnsignedInteger run(Object... args) { @@ -323,6 +373,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * ORs inputs together with one inverted input. + */ public static class OrNotA extends Function { @Override public UnsignedInteger run(Object... args) { @@ -348,6 +401,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * ORs inputs together with one inverted input. + */ public static class OrNotB extends Function { @Override public UnsignedInteger run(Object... args) { @@ -373,6 +429,9 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * NANDs inputs together. + */ public static class Nand extends Function { @Override public UnsignedInteger run(Object... args) { @@ -398,6 +457,10 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * Works as a multiplexer. Outputs either one of its two inputs + * depending on a third input (select). + */ public static class Mux1 extends Function { @Override public UnsignedInteger run(Object... args) { @@ -424,6 +487,10 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * Works as a multiplexer. Outputs either one of its two inputs + * depending on a third input (select). Input 0 is inverted. + */ public static class Mux2 extends Function { @Override public UnsignedInteger run(Object... args) { @@ -450,6 +517,10 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * Works as a multiplexer. Outputs either one of its two inputs + * depending on a third input (select). Input 1 is inverted. + */ public static class Mux3 extends Function { @Override public UnsignedInteger run(Object... args) { @@ -476,6 +547,10 @@ public class DigitalCircuitFunctions extends FunctionSet { } } + /** + * Works as a multiplexer. Outputs either one of its two inputs + * depending on a third input (select). Both inputs are inverted. + */ public static class Mux4 extends Function { @Override public UnsignedInteger run(Object... args) { diff --git a/src/jcgp/backend/function/Function.java b/src/jcgp/backend/function/Function.java index fdacac0..2e1f3c6 100644 --- a/src/jcgp/backend/function/Function.java +++ b/src/jcgp/backend/function/Function.java @@ -7,17 +7,15 @@ package jcgp.backend.function; * any arbitrary operation on the arguments specified. It must also override * {@code getArity()} to return the function arity. * - * * @author Eduardo Pedroni - * */ public abstract class Function { /** * Executes the function. * - * @param args the function arguments - * @return the function result + * @param args the function arguments. + * @return the function result. */ public abstract Object run(Object... args); diff --git a/src/jcgp/backend/function/FunctionSet.java b/src/jcgp/backend/function/FunctionSet.java index 926ed68..052183a 100644 --- a/src/jcgp/backend/function/FunctionSet.java +++ b/src/jcgp/backend/function/FunctionSet.java @@ -4,9 +4,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; - /** - * FunctionSet encapsulates a group of functions. This is usually done to + * FunctionSet encapsulates a group of functions. This is done to * simplify the implementation of problem types. *

* FunctionSet contains a variety of useful methods for acquiring general @@ -18,18 +17,16 @@ import java.util.Iterator; * allowed functions only, providing an easy way to control which functions * can be used in mutations. *

- * An implementation of FunctionSet must simply set the name field and initialise - * the functionList array with all of the functions. It is advisable to call - * {@code enableAll()} to enable all functions once the array is initialised. - * + * An implementation of FunctionSet must simply use its constructor to set + * the name field and use {@code registerFunctions()} to add the required + * functions. * * @author Eduardo Pedroni * */ public abstract class FunctionSet { - protected Function[] functionList; - protected ArrayList allowedFunctions; - protected String name; + private ArrayList functionList = new ArrayList(); + private ArrayList allowedFunctions = new ArrayList(); /** * @return the number of currently allowed functions. @@ -42,7 +39,7 @@ public abstract class FunctionSet { * @return the total number of functions, including disabled ones. */ public int getTotalFunctionCount() { - return functionList.length; + return functionList.size(); } /** @@ -54,7 +51,7 @@ public abstract class FunctionSet { * @return the allowed function object. */ public Function getAllowedFunction(int index) { - return functionList[allowedFunctions.get(index)]; + return functionList.get(allowedFunctions.get(index)); } /** @@ -67,7 +64,7 @@ public abstract class FunctionSet { * @return the function object. */ public Function getFunction(int index) { - return functionList[index]; + return functionList.get(index); } /** @@ -100,7 +97,7 @@ public abstract class FunctionSet { * list of allowed functions and removes any elements which are equal * to the specified index. */ - if (index < functionList.length) { + if (index < functionList.size()) { for (Iterator iterator = allowedFunctions.iterator(); iterator.hasNext();) { int function = iterator.next(); if (function == index) { @@ -108,7 +105,7 @@ public abstract class FunctionSet { } } } else { - throw new ArrayIndexOutOfBoundsException("Function " + index + " does not exist, the set only has " + functionList.length + " functions."); + throw new ArrayIndexOutOfBoundsException("Function " + index + " does not exist, the set only has " + functionList.size() + " functions."); } } @@ -126,11 +123,6 @@ public abstract class FunctionSet { } } - @Override - public String toString() { - return name; - } - /** * Checks if a specified function is enabled. If the function * does not belong in the FunctionSet, this returns false. @@ -140,7 +132,7 @@ public abstract class FunctionSet { */ public boolean isEnabled(Function function) { for (int i = 0; i < allowedFunctions.size(); i++) { - if (functionList[allowedFunctions.get(i)] == function) { + if (functionList.get(allowedFunctions.get(i)) == function) { return true; } } @@ -148,12 +140,34 @@ public abstract class FunctionSet { } /** - * Enables all functions. + * For internal use in subclass constructors. This method + * adds the specified functions and enables them. The same + * function cannot be added more than once. + * + * @param functions the functions to register in the function set. */ - public void enableAll() { - allowedFunctions = new ArrayList(); - for (int i = 0; i < functionList.length; i++) { - allowedFunctions.add(i); + protected void registerFunctions(Function... functions) { + for (int i = 0; i < functions.length; i++) { + if (!alreadyHave(functions[i])) { + functionList.add(functions[i]); + enableFunction(functionList.size() - 1); + } } } + + /** + * For internal use only, this checks whether a function + * is already present in the function set. + * + * @param function the function to look for. + * @return true if the function is already in the function set. + */ + private boolean alreadyHave(Function function) { + for (int i = 0; i < functionList.size(); i++) { + if (functionList.get(i).getClass() == function.getClass()) { + return true; + } + } + return false; + } } \ No newline at end of file diff --git a/src/jcgp/backend/function/SymbolicRegressionFunctions.java b/src/jcgp/backend/function/SymbolicRegressionFunctions.java index a35f258..6f72723 100644 --- a/src/jcgp/backend/function/SymbolicRegressionFunctions.java +++ b/src/jcgp/backend/function/SymbolicRegressionFunctions.java @@ -1,12 +1,25 @@ package jcgp.backend.function; +/** + * This class contains all symbolic regression functions + * (defined as double functions in the classic CGP implementation) + * in static nested classes. + *
+ * This is the function set used by SymbolicRegressionProblem. + * + * @see SymbolicRegressionProblem + * @author Eduardo Pedroni + * + */ public class SymbolicRegressionFunctions extends FunctionSet { public final static double DIVISION_LIMIT = 0.0001; + /** + * Creates a new instance of SymbolicRegressionFunctions. + */ public SymbolicRegressionFunctions() { - name = "Symbolic regression functions"; - functionList = new Function[] { + registerFunctions( new Absolute(), new SquareRoot(), new Reciprocal(), @@ -26,9 +39,7 @@ public class SymbolicRegressionFunctions extends FunctionSet { new Addition(), new Subtraction(), new Multiplication(), - new Division()}; - - enableAll(); + new Division()); } /** diff --git a/src/jcgp/backend/function/TravellingSalesmanFunctions.java b/src/jcgp/backend/function/TravellingSalesmanFunctions.java index 472b7ad..06b44bb 100644 --- a/src/jcgp/backend/function/TravellingSalesmanFunctions.java +++ b/src/jcgp/backend/function/TravellingSalesmanFunctions.java @@ -1,10 +1,21 @@ package jcgp.backend.function; +/** + * This class contains all travelling salesman functions in static nested classes. + *
+ * This is the function set used by TravellingSalesmanProblem. + * + * @see TravellingSalesmanProblem + * @author Eduardo Pedroni + * + */ public class TravellingSalesmanFunctions extends FunctionSet { + /** + * Creates a new instance of TravellingSalesmanFunctions. + */ public TravellingSalesmanFunctions() { - name = "Travelling salesman functions"; - functionList = new Function[]{ + registerFunctions( new SquareRoot(), new Square(), new Cube(), @@ -16,9 +27,7 @@ public class TravellingSalesmanFunctions extends FunctionSet { new ScaledAddition(), new SymmetricSubtraction(), new Multiplication(), - new BoundedDivision() }; - - enableAll(); + new BoundedDivision()); } /** diff --git a/src/jcgp/backend/function/UnsignedInteger.java b/src/jcgp/backend/function/UnsignedInteger.java index 7feb33f..d23862c 100644 --- a/src/jcgp/backend/function/UnsignedInteger.java +++ b/src/jcgp/backend/function/UnsignedInteger.java @@ -14,7 +14,12 @@ package jcgp.backend.function; * signed and will behave as such for all arithmetic operations. * Bitwise operations can still be performed as they work at the bit * level, making this data type particularly suitable for circuit design. - * + *

+ * TODO in the unlikely event that unsigned integers are natively + * implemented in Java, they should be used instead of this class. + *

+ * Why are unsigned integers not supported?
+ * http://stackoverflow.com/questions/430346/why-doesnt-java-support-unsigned-ints * * @author Eduardo Pedroni * @see Integer @@ -27,7 +32,7 @@ public class UnsignedInteger { /** * Makes a new instance of UnsignedInteger with a specified value. * - * @param i the value with which to initialise + * @param i the value with which to initialise. */ public UnsignedInteger(int i) { value = new Integer(i); @@ -36,7 +41,7 @@ public class UnsignedInteger { /** * Makes a new instance of UnsignedInteger with a specified value. * - * @param i the value with which to initialise + * @param i the value with which to initialise. */ public UnsignedInteger(Integer i) { value = i; @@ -46,14 +51,14 @@ public class UnsignedInteger { * Makes a new instance of UnsignedInteger from the string representation * of an unsigned integer. * - * @param i the string with which to initialise + * @param i the string with which to initialise. */ public UnsignedInteger(String i) { value = Integer.parseUnsignedInt(i); } /** - * @return the wrapped Integer object + * @return the wrapped Integer object. */ public Integer get() { return value; @@ -61,6 +66,11 @@ public class UnsignedInteger { @Override public String toString() { + /* + * It is important to override this so that + * the visual representation of the integer + * is unsigned as well. + */ return Integer.toUnsignedString(value); } } -- cgit v1.2.3