Skip to content

Commit

Permalink
added a way to obtain the node class to the node type
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasWeise committed Dec 26, 2020
1 parent 8d8c9b6 commit 9766670
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 12 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ First, you need to add the following repository, which is a repository that can
```

Than you can add the dependency on our `aitoa-code` repository into your `dependencies` section.
Here, `0.8.78` is the current version of `aitoa-code`.
Here, `0.8.79` is the current version of `aitoa-code`.
Notice that you may have more dependencies in your `dependencies` section, say on `junit`, but here I just put the one for `aitoa-code` as example.

```xml
<dependencies>
<dependency>
<groupId>com.github.thomasWeise</groupId>
<artifactId>aitoa-code</artifactId>
<version>0.8.78</version>
<version>0.8.79</version>
</dependency>
</dependencies>
```
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>aitoa</groupId>
<artifactId>aitoa-code</artifactId>
<version>0.8.78</version>
<version>0.8.79</version>
<packaging>jar</packaging>
<name>aitoa-code</name>
<description>Example Source Codes from the Book "Introduction to Optimization Algorithms"</description>
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/aitoa/examples/jssp/trees/JobStatistic.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,12 @@ public JobStatistic instantiate(final Node[] children,
return (this.mStatistics[i]);
}

/** {@inheritDoc} */
@Override
public Class<JobStatistic> getNodeClass() {
return JobStatistic.class;
}

/** {@inheritDoc} */
@Override
public JobStatistic createModifiedCopy(
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/aitoa/searchSpaces/trees/NodeType.java
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,13 @@ public int hashCode() {
return super.hashCode();
}

/**
* The node class managed by this node type
*
* @return the node class managed by this type
*/
public abstract Class<T> getNodeClass();

/** get the instance */
@SuppressWarnings("rawtypes")
private static final NodeType DUMMY_TYPE = new DummyType();
Expand Down Expand Up @@ -236,5 +243,11 @@ public Node instantiate(final Node[] children,
throw new UnsupportedOperationException(//
"this is a dummy node type. it cannot be used for instantiating nodes!"); //$NON-NLS-1$
}

/** {@inheritDoc} */
@Override
public Class<Node> getNodeClass() {
return Node.class;
}
}
}
71 changes: 71 additions & 0 deletions src/main/java/aitoa/searchSpaces/trees/NodeTypeSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Arrays;
import java.util.Random;

import aitoa.utils.ReflectionUtils;

/**
* A set of node type records. For each child position of a
* genotype, we need to specify such a set of possible child
Expand Down Expand Up @@ -88,6 +90,75 @@ public NodeType<? extends T> getTerminalType(final int index) {
" terminal node types in total."); //$NON-NLS-1$
}

/**
* Get a node type which, itself, is an instance of the given
* class
*
* @param <X>
* the class of the node type
* @param clazz
* the class of the node type
* @param searchTerminalTypes
* should we search the terminal types?
* @param searchNonTerminalTypes
* should we search the non-terminal types?
* @return the terminal type
*/
public <X extends NodeType<? extends T>> X getTypeOfClass(
final Class<X> clazz, final boolean searchTerminalTypes,
final boolean searchNonTerminalTypes) {

int i = (searchNonTerminalTypes ? this.mTypes.length
: this.mTerminalCount);
final int end =
(searchTerminalTypes ? 0 : this.mTerminalCount);

for (; (--i) >= end;) {
final NodeType<? extends T> n = this.mTypes[i];
if (clazz == n.getClass()) {
return clazz.cast(n);
}
}
throw new IllegalArgumentException(//
"Node type of class '" + //$NON-NLS-1$
ReflectionUtils.className(clazz) + //
"' not found.");//$NON-NLS-1$
}

/**
* Get a type which can produce instances of the given class
*
* @param <X>
* the type of the instances
* @param clazz
* the class of the instances
* @param searchTerminalTypes
* should we search the terminal types?
* @param searchNonTerminalTypes
* should we search the non-terminal types?
* @return the terminal type
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public <X extends T> NodeType<X> getTypeForClass(
final Class<X> clazz, final boolean searchTerminalTypes,
final boolean searchNonTerminalTypes) {
int i = (searchNonTerminalTypes ? this.mTypes.length
: this.mTerminalCount);
final int end =
(searchTerminalTypes ? 0 : this.mTerminalCount);

for (; (--i) >= end;) {
final NodeType<? extends T> n = this.mTypes[i];
if (n.getNodeClass() == clazz) {
return ((NodeType) n);
}
}
throw new IllegalArgumentException(//
"Node type producing instances of class '" + //$NON-NLS-1$
ReflectionUtils.className(clazz) + //
"' not found.");//$NON-NLS-1$
}

/**
* Get the number of non-terminal node types
*
Expand Down
30 changes: 23 additions & 7 deletions src/main/java/aitoa/searchSpaces/trees/ReflectiveNodeTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ public NodeType<T> apply(final NodeTypeSet<?>[] t) {
if (!(Node[].class.isAssignableFrom(p[1]))) {
continue outer;
}
return new ReflectiveNodeType1<>(t, cx);
return new ReflectiveNodeType1<>(t, this.mClazz, cx);
}
return new ReflectiveNodeType0<>(t, cx);
return new ReflectiveNodeType0<>(t, this.mClazz, cx);
}

throw new IllegalArgumentException("class " + //$NON-NLS-1$
Expand All @@ -89,23 +89,35 @@ public NodeType<T> apply(final NodeTypeSet<?>[] t) {
private abstract static class ReflectiveNodeType<
T extends Node> extends NodeType<T> {

/** the class */
private final Class<T> mClazz;

/** the constructor */
final Constructor<T> mConstructor;

/**
* create the node factory
*
* @param clazz
* the class
* @param pConstr
* the constructor
* @param pChildTypes
* the child types
*/
ReflectiveNodeType(final NodeTypeSet<?>[] pChildTypes,
final Constructor<T> pConstr) {
final Class<T> clazz, final Constructor<T> pConstr) {
super(pChildTypes);
this.mClazz = Objects.requireNonNull(clazz);
this.mConstructor = Objects.requireNonNull(pConstr);
}

/** {@inheritDoc} */
@Override
public final Class<T> getNodeClass() {
return this.mClazz;
}

/**
* re-throw an error
*
Expand Down Expand Up @@ -136,14 +148,16 @@ private static final class ReflectiveNodeType0<T extends Node>
/**
* create the node factory
*
* @param clazz
* the class
* @param pConstr
* the constructor
* @param pChildTypes
* the child types
*/
ReflectiveNodeType0(final NodeTypeSet<?>[] pChildTypes,
final Constructor<T> pConstr) {
super(pChildTypes, pConstr);
final Class<T> clazz, final Constructor<T> pConstr) {
super(pChildTypes, clazz, pConstr);
this.mParams = new Object[] { this };
}

Expand Down Expand Up @@ -171,14 +185,16 @@ private static final class ReflectiveNodeType1<T extends Node>
/**
* create the node factory
*
* @param clazz
* the class
* @param pConstr
* the constructor
* @param pChildTypes
* the child types
*/
ReflectiveNodeType1(final NodeTypeSet<?>[] pChildTypes,
final Constructor<T> pConstr) {
super(pChildTypes, pConstr);
final Class<T> clazz, final Constructor<T> pConstr) {
super(pChildTypes, clazz, pConstr);
}

/** {@inheritDoc} */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,13 @@ private static final class ConstantNodeType<C>
}
}

/** {@inheritDoc} */
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Class<DoubleConstant<C>> getNodeClass() {
return (Class) (DoubleConstant.class);
}

/** {@inheritDoc} */
@Override
public DoubleConstant<C> instantiate(final Node[] children,
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/aitoa/searchSpaces/trees/math/LongConstant.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ private static final class ConstantNodeType<C>
}
}

/** {@inheritDoc} */
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Class<LongConstant<C>> getNodeClass() {
return (Class) (LongConstant.class);
}

/**
* create
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ public void testPathDistribution() {
final double sd = meanSd[1].doubleValue();
TestTools.assertGreaterOrEqual(sd, 0d);
final double sdLimit = Math.floor(Math.max(2d,
Math.min(2.5 * Math.sqrt(mean), mean / 3d)));
Math.min(2.75 * Math.sqrt(mean), mean / 3d)));
TestTools.assertLessOrEqual(sd, sdLimit);

final double difLimit = Math.floor(Math.max(2d, Math
.min(0.4 * mean, 3d * Math.min(sdLimit, sd * 3d))));
.min(0.5 * mean, 3d * Math.min(sdLimit, sd * 3d))));
for (final long c : counts) {
TestTools.assertGreater(c, 0);
TestTools.assertLess(c, samples);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package aitoa.searchSpaces.trees.math;

import org.junit.Assert;
import org.junit.Test;

import aitoa.searchSpaces.trees.NodeType;
import aitoa.searchSpaces.trees.NodeTypeSet;
import aitoa.searchSpaces.trees.NodeTypeSetBuilder;
import aitoa.searchSpaces.trees.NodeTypeSetBuilder.Builder;
Expand All @@ -24,6 +28,67 @@ public TestFunctionNodeTypeSet() {
return TestFunctionNodeTypeSet.makeMathNodeTypeSet(false);
}

/** test the node types in this node type set for classes */
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test(timeout = 3600000)
public void testNodeTypesClasses() {
final NodeTypeSet<MathFunction<?>> nts = this.getInstance();

Assert.assertNotNull(
nts.getTypeForClass(Add.class, false, true));
Assert.assertNotNull(
nts.getTypeForClass(Subtract.class, false, true));
Assert.assertNotNull(
nts.getTypeForClass(Divide.class, false, true));
Assert.assertNotNull(
nts.getTypeForClass(ATan2.class, false, true));
Assert.assertNotNull(
nts.getTypeForClass(Multiply.class, false, true));
Assert.assertNotNull(
nts.getTypeForClass(Min.class, false, true));
Assert.assertNotNull(
nts.getTypeForClass(Max.class, false, true));
Assert.assertNotNull(nts
.getTypeForClass(IfGreaterThenElse.class, false, true));

NodeType<LongConstant> lct =
nts.getTypeForClass(LongConstant.class, true, false);
Assert.assertNotNull(lct);
Assert.assertSame(lct,
nts.getTypeOfClass(lct.getClass(), true, false));
NodeType<DoubleConstant> dct =
nts.getTypeForClass(DoubleConstant.class, true, false);
Assert.assertNotNull(dct);
Assert.assertSame(dct,
nts.getTypeOfClass(dct.getClass(), true, false));

Assert.assertNotNull(
nts.getTypeForClass(Add.class, true, true));
Assert.assertNotNull(
nts.getTypeForClass(Subtract.class, true, true));
Assert.assertNotNull(
nts.getTypeForClass(Divide.class, true, true));
Assert.assertNotNull(
nts.getTypeForClass(ATan2.class, true, true));
Assert.assertNotNull(
nts.getTypeForClass(Multiply.class, true, true));
Assert.assertNotNull(
nts.getTypeForClass(Min.class, true, true));
Assert.assertNotNull(
nts.getTypeForClass(Max.class, true, true));
Assert.assertNotNull(nts
.getTypeForClass(IfGreaterThenElse.class, true, true));

lct = nts.getTypeForClass(LongConstant.class, true, true);
Assert.assertNotNull(lct);
Assert.assertSame(lct,
nts.getTypeOfClass(lct.getClass(), true, true));
dct = nts.getTypeForClass(DoubleConstant.class, true, true);
Assert.assertNotNull(dct);
Assert.assertSame(dct,
nts.getTypeOfClass(dct.getClass(), true, true));
}

/**
* make the node type set
*
Expand Down

0 comments on commit 9766670

Please sign in to comment.