New GP node and help-file for GenericConstraint.

This commit is contained in:
Marcel Kronfeld 2009-10-19 10:04:05 +00:00
parent e56af4fb60
commit ca490cf482
3 changed files with 165 additions and 1 deletions

View File

@ -0,0 +1,56 @@
<html>
<head>
<title>Generic Constraints</title>
</head>
<body>
<h1 align="center">Generic Constraints</h1>
<br>
<p>To represent generic constraints on real-valued functions, this class can parse
String expressions in prefix notation of the form:
<blockquote>
&lt;expr&gt; ::= &lt;constant-operator&gt; | &lt;functional-operator&gt; "(" &lt;arguments&gt; ")"<br>
&lt;arguments> ::= &lt;expr&gt; | &lt;expr&gt; "," &lt;arguments&gt;
</blockquote>
</p>
Setting the <b>constraint string</b>:
Constant operators have an arity of zero. Examples are:<br>
(pi,0) (X,0) (1.0,0)<br>
Functional operators have an arity greater zero. Examples are:<br>
(sum,1) (prod,1) (abs,1) (sin,1) (pow2,1) (pow3,1) (sqrt,1) (neg,1) (cos,1) (exp,1)<br>
(+,2) (-,2) (/,2) (*,2)<br>
<p>
Additionally, any numerical strings can also be used; they are parsed to numeric constants. The literal <i>n</i>
is parsed to the current number of problem dimensions.<br>
Notice that only the <i>sum</i> and <i>prod</i> operators may receive the literal X as input, standing
for the full solution vector. Access to single solution components is possible by writing <i>x0...x9</i>
for a problem with 10 dimensions.
</p>
<p>
Thus you may write <font face="Courier">+(-(5,sum(X)),+sin(/(x0,pi)))</font>
and select 'lessEqZero' as relation to require valid solutions to fulfill 5-sum(X)+sin(x0/pi)&lt;=0.<br>
</p>
<p>
Typical <b>relations</b> concerning constraints allow for g(x)&lt;=0, g(x)==0, or g(x)&gt;=0 for
constraint g. Notice that equal-to-zero constraints are converted to g(x)==0 &lt;=&gt; |g(x)-epsilon|&lt;=0 for
customizable small values of epsilon.
</p>
<p>
The <b>handling method</b> 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.<br>
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.
</p>
</body>
</html>

View File

@ -1,6 +1,7 @@
package eva2.server.go.individuals.codings.gp; package eva2.server.go.individuals.codings.gp;
import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Vector; import java.util.Vector;
@ -10,6 +11,7 @@ import eva2.server.go.problems.GPFunctionProblem;
import eva2.server.go.problems.InterfaceProgramProblem; import eva2.server.go.problems.InterfaceProgramProblem;
import eva2.tools.Mathematics; import eva2.tools.Mathematics;
import eva2.tools.Pair; import eva2.tools.Pair;
import eva2.tools.ReflectPackage;
/** This gives an abstract node, with default functionality for get and set methods. /** 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("-(*(x1,x2),*(5,*(x3,x4)))", solG13);
test("+(pow3(x0),+(pow3(x1),1))", solG13); test("+(pow3(x0),+(pow3(x1),1))", solG13);
System.out.println("" + Math.exp(Mathematics.product(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) { public static void test(String constr, double[] pos) {
AbstractGPNode node = AbstractGPNode.parseFromString(constr); AbstractGPNode node = AbstractGPNode.parseFromString(constr);
GPFunctionProblem func = new GPFunctionProblem(node, null, pos.length, 0., 0.); GPFunctionProblem func = new GPFunctionProblem(node, null, pos.length, 0., 0.);

View File

@ -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";
}
}