diff --git a/resources/GenericConstraint.html b/resources/GenericConstraint.html new file mode 100644 index 00000000..179b1f43 --- /dev/null +++ b/resources/GenericConstraint.html @@ -0,0 +1,56 @@ + + +Generic Constraints + + +

Generic Constraints

+
+ +

To represent generic constraints on real-valued functions, this class can parse +String expressions in prefix notation of the form: +

+<expr> ::= <constant-operator> | <functional-operator> "(" <arguments> ")"
+<arguments> ::= <expr> | <expr> "," <arguments> +
+

+ +Setting the constraint string: +Constant operators have an arity of zero. Examples are:
+(pi,0) (X,0) (1.0,0)
+ +Functional operators have an arity greater zero. Examples are:
+ (sum,1) (prod,1) (abs,1) (sin,1) (pow2,1) (pow3,1) (sqrt,1) (neg,1) (cos,1) (exp,1)
+ (+,2) (-,2) (/,2) (*,2)
+ +

+Additionally, any numerical strings can also be used; they are parsed to numeric constants. The literal n +is parsed to the current number of problem dimensions.
+Notice that only the sum and prod operators may receive the literal X as input, standing +for the full solution vector. Access to single solution components is possible by writing x0...x9 +for a problem with 10 dimensions. +

+ +

+Thus you may write +(-(5,sum(X)),+sin(/(x0,pi))) +and select 'lessEqZero' as relation to require valid solutions to fulfill 5-sum(X)+sin(x0/pi)<=0.
+

+ +

+Typical relations concerning constraints allow for g(x)<=0, g(x)==0, or g(x)>=0 for +constraint g. Notice that equal-to-zero constraints are converted to g(x)==0 <=> |g(x)-epsilon|<=0 for +customizable small values of epsilon. +

+ +

+The handling method defines how EvA 2 copes with the constraint. Simplest variant is an +additive penalty which is scaled by the penalty factor and then added directly to the fitness +of an individual. This will work for any optimization strategy, but results will depend on +the selection of penalty factors. Multiplicative penalty works analogously with the difference of +being multiplied with the raw fitness.
+In the variant called specific tag, the constraint violation is stored in an extra field of any +individual and may be regarded by the optimization strategy. However, not all strategies provide +simple mechanisms of incorporating this specific tag. +

+ + + \ No newline at end of file diff --git a/src/eva2/server/go/individuals/codings/gp/AbstractGPNode.java b/src/eva2/server/go/individuals/codings/gp/AbstractGPNode.java index b8a6aec1..e8c10b7a 100644 --- a/src/eva2/server/go/individuals/codings/gp/AbstractGPNode.java +++ b/src/eva2/server/go/individuals/codings/gp/AbstractGPNode.java @@ -1,6 +1,7 @@ package eva2.server.go.individuals.codings.gp; +import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Vector; @@ -10,6 +11,7 @@ import eva2.server.go.problems.GPFunctionProblem; import eva2.server.go.problems.InterfaceProgramProblem; import eva2.tools.Mathematics; import eva2.tools.Pair; +import eva2.tools.ReflectPackage; /** This gives an abstract node, with default functionality for get and set methods. @@ -271,10 +273,37 @@ public abstract class AbstractGPNode implements InterfaceProgram, java.io.Serial test("-(*(x1,x2),*(5,*(x3,x4)))", solG13); test("+(pow3(x0),+(pow3(x1),1))", solG13); System.out.println("" + Math.exp(Mathematics.product(solG13))); + test("+(sum(x),abs(sin(*(x0,x3))))", solG5); + test("-(abs(sum(x)),*(abs(-7.5),n))", solG5); - test("-(sum(x),*(7.5,n))", solG5); + System.out.println(createNodeList()); } + /** + * Print all operator identifiers with arities. + * + * @return + */ + public static String createNodeList() { + String ret = new String(); + + Class cls = AbstractGPNode.class; + Class[] nodes = ReflectPackage.getAssignableClassesInPackage(cls.getPackage().getName(), AbstractGPNode.class, true, false); + for (Class c : nodes) { + if (Modifier.isAbstract(c.getModifiers()) || c.isInterface()) continue; + AbstractGPNode node; + try { + node = (AbstractGPNode)c.newInstance(); + ret = ret + " (" + node.getOpIdentifier() + "," + node.getArity() + ")"; + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + return ret; + } + public static void test(String constr, double[] pos) { AbstractGPNode node = AbstractGPNode.parseFromString(constr); GPFunctionProblem func = new GPFunctionProblem(node, null, pos.length, 0., 0.); diff --git a/src/eva2/server/go/individuals/codings/gp/GPNodeAbs.java b/src/eva2/server/go/individuals/codings/gp/GPNodeAbs.java new file mode 100644 index 00000000..d3d8a7f4 --- /dev/null +++ b/src/eva2/server/go/individuals/codings/gp/GPNodeAbs.java @@ -0,0 +1,79 @@ +package eva2.server.go.individuals.codings.gp; + +import eva2.server.go.problems.InterfaceProgramProblem; + + +/** + * A node for retrieving the absolute value + * + */ +public class GPNodeAbs extends AbstractGPNode implements java.io.Serializable { + + public GPNodeAbs() { + } + public GPNodeAbs(GPNodeAbs node) { + this.m_Depth = node.m_Depth; + this.m_Parent = node.m_Parent; + this.m_Nodes = new AbstractGPNode[node.m_Nodes.length]; + for (int i = 0; i < node.m_Nodes.length; i++) this.m_Nodes[i] = (AbstractGPNode) node.m_Nodes[i].clone(); + } + + /** This method allows you to determine wehter or not two subtrees + * are actually the same. + * @param obj The other subtree. + * @return boolean if equal true else false. + */ + public boolean equals(Object obj) { + if (obj instanceof GPNodeAbs) { + GPNodeAbs node = (GPNodeAbs)obj; + if (this.m_Nodes.length != node.m_Nodes.length) return false; + for (int i = 0; i < this.m_Nodes.length; i++) { + if (!this.m_Nodes[i].equals(node.m_Nodes[i])) return false; + } + return true; + } else { + return false; + } + } + + /** This method will be used to identify the node in the GPAreaEditor + * @return The name. + */ + public String getName() { + return "Abs"; + } + + /** This method allows you to clone the Nodes + * @return the clone + */ + public Object clone() { + return (Object) new GPNodeAbs(this); + } + + /** This method will return the current arity + * @return Arity. + */ + public int getArity() { + return 1; + } + + /** This method will evaluate a given node + * @param environment + */ + public Object evaluate(InterfaceProgramProblem environment) { + Object tmpObj; + double result = 0; + + tmpObj = this.m_Nodes[0].evaluate(environment); + if (tmpObj instanceof Double) result += ((Double)tmpObj).doubleValue(); + Double ret = new Double(result); + + if (ret<0) return -ret; + else return ret; + } + + @Override + public String getOpIdentifier() { + return "abs"; + } +}