Skip to content
Snippets Groups Projects
Commit 75efc6d3 authored by Jeffrey Phillips Freeman's avatar Jeffrey Phillips Freeman :boom:
Browse files

Updated the Path and Walk classes to use the new architecture. Refined many of...

Updated the Path and Walk classes to use the new architecture. Refined many of the Abstract classes to use the new Architecture.
parent a97ee33a
No related branches found
No related tags found
No related merge requests found
Showing
with 1306 additions and 1044 deletions
[submodule "lib"]
path = lib
walk = lib
url = git://git.syncleus.com/dANN-core-lib.git
......@@ -2,26 +2,26 @@
<project name="dANN" default="all" basedir=".">
<property name="debug.level" value="vars,lines,source" />
<path id="classpath.ant">
<walk id="classpath.ant">
<fileset dir="lib/ant" includes="**/*.jar"/>
</path>
<path id="classpath.build">
</walk>
<walk id="classpath.build">
<fileset dir="lib/build" includes="**/*.jar"/>
</path>
<path id="classpath.build.tests">
</walk>
<walk id="classpath.build.tests">
<fileset dir="lib/build" includes="**/*.jar"/>
<pathelement path="build/classes"/>
</path>
<path id="classpath.test">
<pathelement walk="build/classes"/>
</walk>
<walk id="classpath.test">
<fileset dir="lib/test" includes="**/*.jar"/>
<fileset dir="build/jar" includes="dann.jar"/>
<fileset dir="build/jar" includes="dann-tests.jar"/>
</path>
<path id="classpath.test.coverage">
</walk>
<walk id="classpath.test.coverage">
<fileset dir="lib/test" includes="**/*.jar"/>
<fileset dir="build/jar" includes="dann.jar"/>
<fileset dir="build/jar" includes="dann-coverage.jar"/>
</path>
</walk>
<taskdef name="lint4j" classname="com.jutils.lint4j.ant.Lint4jAntTask">
<classpath>
......@@ -89,11 +89,11 @@
<dirset dir="src/main/java">
<include name="**/*.java" />
</dirset>
<pathelement path="src/main/java/" />
<pathelement walk="src/main/java/" />
<dirset dir="src/test/java">
<include name="**/*.java" />
</dirset>
<pathelement path="src/test/java/" />
<pathelement walk="src/test/java/" />
</sourcepath>
<classpath refid="classpath.build"/>
<formatters>
......@@ -116,16 +116,16 @@
<mkdir dir="build/classes"/>
<javac destdir="build/classes" classpathref="classpath.build" debug="true" debuglevel="${debug.level}">
<src path="src/main/java"/>
<src path="build/src-jaxb"/>
<src walk="src/main/java"/>
<src walk="build/src-jaxb"/>
</javac>
<copy file="log4j.properties" todir="build/classes/"/>
<mkdir dir="build/tests/classes"/>
<javac destdir="build/tests/classes" classpathref="classpath.build.tests" debug="true" debuglevel="${debug.level}">
<src path="src/test/java"/>
<src path="build/src-jaxb"/>
<src walk="src/test/java"/>
<src walk="build/src-jaxb"/>
</javac>
<delete dir="build/tests/classes/com/syncleus/dann"/>
......@@ -143,15 +143,15 @@
<mkdir dir="build/classes"/>
<javac destdir="build/classes" classpathref="classpath.build" debug="true" debuglevel="${debug.level}">
<src path="src/main/java"/>
<src path="build/src-jaxb"/>
<src walk="src/main/java"/>
<src walk="build/src-jaxb"/>
<compilerarg value="-Xlint"/>
</javac>
<mkdir dir="build/tests/classes"/>
<javac destdir="build/tests/classes" classpathref="classpath.build.tests" debug="true" debuglevel="${debug.level}">
<src path="src/test/java"/>
<src path="build/src-jaxb"/>
<src walk="src/test/java"/>
<src walk="build/src-jaxb"/>
<compilerarg value="-Xlint"/>
</javac>
......@@ -246,14 +246,14 @@
<findbugs home="lib/ant/findbugs/"
output="xml"
outputFile="build/findbugs/findbugs-report.xml" >
<auxClasspath path="lib/run/java3d/j3dcore.jar"/>
<auxClasspath path="lib/run/java3d/freehep/freehep-j3d.jar"/>
<auxClasspath path="lib/run/java3d/j3dutils.jar"/>
<auxClasspath path="lib/run/java3d/vecmath.jar"/>
<auxClasspath path="lib/run/jaxb/jaxb2-basics-runtime-0.5.3.jar"/>
<auxClasspath path="lib/run/log4j/log4j-1.2.15.jar"/>
<sourcePath path="src/main/java/" />
<sourcePath path="src/test/java/" />
<auxClasspath walk="lib/run/java3d/j3dcore.jar"/>
<auxClasspath walk="lib/run/java3d/freehep/freehep-j3d.jar"/>
<auxClasspath walk="lib/run/java3d/j3dutils.jar"/>
<auxClasspath walk="lib/run/java3d/vecmath.jar"/>
<auxClasspath walk="lib/run/jaxb/jaxb2-basics-runtime-0.5.3.jar"/>
<auxClasspath walk="lib/run/log4j/log4j-1.2.15.jar"/>
<sourcePath walk="src/main/java/" />
<sourcePath walk="src/test/java/" />
<class location="build/jar/dann.jar" />
</findbugs>
</target>
......
......@@ -24,7 +24,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
public abstract class AbstractBidirectedAdjacencyGraph<N, E extends BidirectedEdge<N>> extends AbstractAdjacencyGraph<N, E> implements BidirectedGraph<N, E>
public abstract class AbstractBidirectedAdjacencyGraph<N, E extends BidirectedEdge<N>> extends AbstractCloudGraph<N, E> implements BidirectedGraph<N, E>
{
protected AbstractBidirectedAdjacencyGraph()
{
......
......@@ -18,351 +18,18 @@
******************************************************************************/
package com.syncleus.dann.graph;
import java.util.*;
import com.syncleus.dann.graph.xml.*;
import com.syncleus.dann.xml.NamedValueXml;
import com.syncleus.dann.xml.Namer;
import com.syncleus.dann.xml.XmlSerializable;
public abstract class AbstractBidirectedEdge<N, LN extends N, RN extends N> extends AbstractEdge<N> implements MixableBidirectedEdge<N, LN,RN>
public abstract class AbstractBidirectedEdge<E extends BidirectedEdge.Endpoint<?>> extends AbstractMixableBidirectedEdge<E,E,E> implements BidirectedEdge<E>
{
@Override
public abstract AbstractEndpoint<LN,RN> getLeftEndPoint();
@Override
public abstract AbstractEndpoint<RN,LN> getRightEndPoint();
@Override
public final Set<Endpoint<N, N>> getEndpoints()
{
return new EndPointsSet();
}
private static <N> List<N> packNodes(final N leftNode, final N rightNode)
{
final List<N> pack = new ArrayList<N>();
pack.add(leftNode);
pack.add(rightNode);
return pack;
}
@Override
public boolean isIntroverted()
{
return (this.getRightEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.INWARD) && (this.getLeftEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.INWARD);
}
@Override
public boolean isExtroverted()
{
return (this.getRightEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.OUTWARD) && (this.getLeftEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.OUTWARD);
}
@Override
public boolean isDirected()
{
if( (this.getRightEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.INWARD) && (this.getLeftEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.OUTWARD) )
return true;
else if( (this.getRightEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.OUTWARD) && (this.getLeftEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.INWARD) )
return true;
return false;
}
@Override
public boolean isHalfEdge()
{
if( (this.getRightEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.NONE) && (this.getLeftEndPoint().getDirection() != MixableBidirectedEdge.Endpoint.Direction.NONE) )
return true;
else if( (this.getRightEndPoint().getDirection() != MixableBidirectedEdge.Endpoint.Direction.NONE) && (this.getLeftEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.NONE) )
return true;
return false;
}
@Override
public boolean isLooseEdge()
{
return (this.getRightEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.NONE) && (this.getLeftEndPoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.NONE);
}
@Override
public boolean isOrdinaryEdge()
{
return (!this.isHalfEdge()) && (!this.isLooseEdge());
}
@Override
public boolean isLoop()
{
return this.getLeftEndPoint().getDirection().equals(this.getRightEndPoint().getDirection());
}
@Override
public String toString()
{
return this.getLeftEndPoint().getTarget().toString()
+ endStateToString(this.getLeftEndPoint().getDirection(), true)
+ '-'
+ endStateToString(this.getRightEndPoint().getDirection(), false)
+ this.getRightEndPoint().getTarget();
}
private static String endStateToString(final MixableBidirectedEdge.Endpoint.Direction state, final boolean isLeft)
{
switch(state)
{
case INWARD:
return (isLeft ? ">" : "<");
case OUTWARD:
return (isLeft ? "<" : ">");
default:
return "";
}
}
@Override
protected AbstractBidirectedEdge<N, LN,RN> clone()
{
return (AbstractBidirectedEdge<N, LN,RN>) super.clone();
}
@Override
public BidirectedEdgeXml toXml()
protected abstract class AbstractEndpoint<T> extends AbstractMixableBidirectedEdge<E,E,E>.AbstractEndpoint<T> implements BidirectedEdge.Endpoint<T>
{
final Namer namer = new Namer();
final BidirectedEdgeElementXml xml = new BidirectedEdgeElementXml();
xml.setNodeInstances(new BidirectedEdgeElementXml.NodeInstances());
final Set<N> writtenNodes = new HashSet<N>();
for (N node : this.getTargets())
{
if (writtenNodes.add(node))
{
final NamedValueXml named = new NamedValueXml();
named.setName(namer.getNameOrCreate(node));
if (node instanceof XmlSerializable)
{
named.setValue(((XmlSerializable) node).toXml(namer));
}
else
{
named.setValue(node);
}
xml.getNodeInstances().getNodes().add(named);
}
}
return xml;
}
@Override
public BidirectedEdgeXml toXml(final Namer<Object> nodeNames)
{
if (nodeNames == null)
{
throw new IllegalArgumentException("nodeNames can not be null");
}
final BidirectedEdgeXml xml = new BidirectedEdgeXml();
this.toXml(xml, nodeNames);
return xml;
}
@Override
public void toXml(final EdgeXml jaxbObject, final Namer<Object> nodeNames)
{
if (nodeNames == null)
{
throw new IllegalArgumentException("nodeNames can not be null");
}
if (jaxbObject == null)
{
throw new IllegalArgumentException("jaxbObject can not be null");
}
super.toXml(jaxbObject, nodeNames);
if (jaxbObject instanceof BidirectedEdgeXml)
{
((BidirectedEdgeXml) jaxbObject).setLeftNode(nodeNames.getNameOrCreate(this.getLeftEndPoint().getTarget()));
((BidirectedEdgeXml) jaxbObject).setRightNode(nodeNames.getNameOrCreate(this.getRightEndPoint().getTarget()));
((BidirectedEdgeXml) jaxbObject).setLeftDirection(this.getLeftEndPoint().getDirection().toString().toLowerCase());
((BidirectedEdgeXml) jaxbObject).setRightDirection(this.getRightEndPoint().getDirection().toString().toLowerCase());
}
}
private final class EndPointsSet implements Set<Endpoint<N, N>>
{
public EndPointsSet()
{
}
@Override
public int size()
{
return 2;
}
@Override
public boolean isEmpty()
{
return false;
}
@Override
public boolean contains(Object o)
{
if( (getLeftEndPoint().equals(o)) || (getRightEndPoint().equals(o)) )
return true;
return false;
}
@Override
public Iterator<Endpoint<N, N>> iterator()
{
return new EndPointIterator();
}
@Override
public Endpoint<N, N>[] toArray()
{
return new Endpoint[]{getLeftEndPoint(),getRightEndPoint()};
}
@Override
public <T> T[] toArray(T[] a)
{
a[0] = (T) getLeftEndPoint();
a[1] = (T) getRightEndPoint();
return a;
}
@Override
public boolean add(Endpoint<N, N> nnEndpoint)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public boolean remove(Object o)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public boolean containsAll(Collection<?> c)
{
for(Object object : c)
if( !this.contains(object) )
return false;
return true;
}
@Override
public boolean addAll(Collection<? extends Endpoint<N, N>> c)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public boolean retainAll(Collection<?> c)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public boolean removeAll(Collection<?> c)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public void clear()
{
throw new UnsupportedOperationException("This Set is read-only!");
}
private class EndPointIterator implements Iterator<Endpoint<N, N>>
{
private Boolean stage = Boolean.TRUE;
public EndPointIterator()
{
}
@Override
public boolean hasNext()
{
if(stage == null)
return false;
return true;
}
@Override
public Endpoint<N, N> next()
{
if(stage == Boolean.TRUE)
{
stage = false;
return getLeftEndPoint();
}
else if(stage == Boolean.FALSE)
{
stage = null;
return getRightEndPoint();
}
throw new NoSuchElementException("no elements left!");
}
@Override
public void remove()
{
throw new UnsupportedOperationException("This iterator is read-only!");
}
};
}
protected abstract class AbstractEndpoint<EN extends N, ON extends N> extends AbstractEdge<N>.AbstractEndpoint<EN> implements MixableBidirectedEdge.Endpoint<N, EN,ON>
{
private EN node = null;
private Direction direction;
protected AbstractEndpoint(Direction direction)
{
super();
if( direction == null )
throw new IllegalArgumentException("direction can not be null!");
this.direction = direction;
}
protected AbstractEndpoint(EN node, Direction direction)
{
this(direction);
this.node = node;
}
@Override
public EN getTarget()
{
return this.node;
}
public void setTarget(final EN node)
{
this.node = node;
}
@Override
public Direction getDirection()
{
return this.direction;
super(direction);
}
public void setDirection(final Direction direction)
protected AbstractEndpoint(T target, Direction direction)
{
this.direction = direction;
super(target, direction);
}
};
}
......@@ -19,25 +19,24 @@
package com.syncleus.dann.graph;
import java.util.*;
import com.syncleus.dann.graph.xml.EdgeElementXml;
import com.syncleus.dann.graph.xml.EdgeXml;
import com.syncleus.dann.xml.NameXml;
import com.syncleus.dann.xml.NamedValueXml;
import com.syncleus.dann.xml.Namer;
import com.syncleus.dann.xml.XmlSerializable;
import org.apache.log4j.Logger;
public abstract class AbstractCloud<
T,
EP extends Cloud.Endpoint<T,? extends T>
> implements Cloud<T,EP>
E extends Cloud.Endpoint<?>
> implements Cloud<E>
{
private static final Logger LOGGER = Logger.getLogger(AbstractCloud.class);
@Override
public final boolean isFinite()
{
return true;
}
@Override
public boolean containsTarget(final Object node)
{
for( EP endpoint : this.getEndpoints() )
for( E endpoint : this.getEndpoints() )
if( endpoint.getTarget().equals(node))
return true;
return false;
......@@ -62,47 +61,37 @@ public abstract class AbstractCloud<
}
@Override
public boolean contains(final Object endpoint)
public boolean contains(final Cloud.Endpoint<?> endpoint)
{
for( EP otherEndpoint : this.getEndpoints() )
for( E otherEndpoint : this.getEndpoints() )
if( otherEndpoint.equals(endpoint))
return true;
return false;
}
@Override
public boolean containsAll(final Collection<? extends Endpoint<?,?>> endpoints)
public boolean containsAll(final Collection<? extends Cloud.Endpoint<?>> endpoints)
{
for( Object endpoint : endpoints )
for( Endpoint<?> endpoint : endpoints )
if( !this.contains(endpoint) )
return false;
return true;
}
@Override
public boolean containsAny(final Collection<? extends Endpoint<?,?>> endpoints)
public boolean containsAny(final Collection<? extends Cloud.Endpoint<?>> endpoints)
{
for( Object endpoint : endpoints )
for( Endpoint<?> endpoint : endpoints )
if( this.contains(endpoint) )
return true;
return false;
}
@Override
public Set<T> getTargets()
public Set<E> getEndpoints(Object node)
{
final Set<T> nodes = new HashSet<T>();
for( EP endpoint : this.getEndpoints() )
nodes.add(endpoint.getTarget());
return Collections.unmodifiableSet(nodes);
}
@Override
public Set<EP> getEndpoints(Object node)
{
final Set<EP> nodesEndpoints = new HashSet<EP>();
for( EP endpoint : this.getEndpoints() )
final Set<E> nodesEndpoints = new HashSet<E>();
for( E endpoint : this.getEndpoints() )
if( endpoint.getTarget().equals(node))
nodesEndpoints.add(endpoint);
......@@ -110,39 +99,34 @@ public abstract class AbstractCloud<
}
@Override
public Set<T> getNeighbors(final Object source)
public boolean areNeighbors(Cloud.Endpoint<?> neighbor, Cloud.Endpoint<?> otherNeighbor)
{
final Set<T> nodes = new HashSet<T>();
for( final EP sourceEndpoint : this.getEndpoints(source) )
for( final Cloud.Endpoint<? extends T,? extends T> fromEndpoint : sourceEndpoint.getNeighbors())
nodes.add(fromEndpoint.getTarget());
return Collections.unmodifiableSet(nodes);
return this.getNeighbors(neighbor).contains(otherNeighbor);
}
@Override
public int getDegree()
{
return this.getTargets().size();
return this.getEndpoints().size();
}
@Override
public String toString()
{
final StringBuilder outString = new StringBuilder(this.getTargets().size() * 10);
for(final T node : this.getTargets())
final StringBuilder outString = new StringBuilder(this.getDegree() * 10);
for(final E endpoint : this.getEndpoints())
{
outString.append(':').append(node);
outString.append(':').append(endpoint);
}
return outString.toString();
}
@Override
protected AbstractCloud<T,EP> clone()
protected AbstractCloud<E> clone()
{
try
{
return (AbstractCloud<T,EP>) super.clone();
return (AbstractCloud<E>) super.clone();
}
catch(CloneNotSupportedException caught)
{
......@@ -151,27 +135,29 @@ public abstract class AbstractCloud<
}
}
// TODO : Clean this
/*
@Override
public EdgeXml toXml()
{
final Namer namer = new Namer();
final Namer<Object> namer = new Namer();
final EdgeElementXml xml = new EdgeElementXml();
xml.setNodeInstances(new EdgeElementXml.NodeInstances());
final Set<T> writtenNodes = new HashSet<T>();
for (T node : this.getTargets())
final Set<E> writtenNodes = new HashSet<E>();
for (E endpoint : this.getEndpoints())
{
if (writtenNodes.add(node))
if (writtenNodes.add(endpoint))
{
final NamedValueXml named = new NamedValueXml();
named.setName(namer.getNameOrCreate(node));
if (node instanceof XmlSerializable)
named.setName(namer.getNameOrCreate(endpoint));
if (endpoint instanceof XmlSerializable)
{
named.setValue(((XmlSerializable) node).toXml(namer));
named.setValue(((XmlSerializable) endpoint).toXml(namer));
}
else
{
named.setValue(node);
named.setValue(endpoint);
}
xml.getNodeInstances().getNodes().add(named);
}
......@@ -217,182 +203,206 @@ public abstract class AbstractCloud<
jaxbObject.getConnections().getNodes().add(connection);
}
}
*/
protected abstract class AbstractEndpoint implements Cloud.Endpoint<T, T>
private class NeighborSet implements Set<E>
{
protected abstract boolean isTargetEquals();
private final E target;
public NeighborSet(E target)
{
this.target = target;
}
/**
* By default this relies on the target to define equals, this means there can be only one instance of any
* endpoint. This should be overridden to allow for an edge to have the same element more than once.
*/
@Override
public int hashCode()
public int size()
{
if(!this.isTargetEquals())
return super.hashCode();
else if(this.getTarget() == null)
return 0;
else
return this.getTarget().hashCode();
return getDegree() - 1;
}
/**
* By default this relies on the target to define equals, this means there can be only one instance of any
* endpoint. This should be overridden to allow for an edge to have the same element more than once.
*/
@Override
public boolean equals(Object obj)
public boolean isEmpty()
{
if(!this.isTargetEquals())
return super.equals(obj);
else if( obj == null )
if( this.getTarget() == null )
return true;
else
return false;
else if( this.getTarget() == null)
assert !getEndpoints().isEmpty();
return ( getDegree() <= 1 ? true : false );
}
@Override
public boolean contains(Object o)
{
if( this.target.equals(o) )
return false;
else if( obj instanceof Cloud.Endpoint )
return ((Cloud.Endpoint<?,?>)obj).equals(this.getTarget());
else
return this.getTarget().equals(obj);
return getEndpoints().contains(o);
}
@Override
public Set<Cloud.Endpoint<P,P>> getNeighbors()
public Iterator<E> iterator()
{
return new NeighborSet();
return new NeighborIterator();
}
private class NeighborSet implements Set<Cloud.Endpoint<P,P>>
@Override
public Object[] toArray()
{
@Override
public int size()
{
return getTargets().size() - 1;
}
final Set<E> copiedNodes = new HashSet<E>(getEndpoints());
copiedNodes.remove(this.target);
return copiedNodes.toArray();
}
@Override
public boolean isEmpty()
{
assert !getTargets().isEmpty();
return ( getEndpoints().size() <= 1 ? true : false );
}
@Override
public <PA> PA[] toArray(PA[] a)
{
final Set<E> copiedNodes = new HashSet<E>(getEndpoints());
copiedNodes.remove(this.target);
return copiedNodes.toArray(a);
}
@Override
public boolean contains(Object o)
{
if( getTarget().equals(o) )
return false;
return getEndpoints().contains(o);
}
@Override
public boolean add(E nEndpoint)
{
throw new UnsupportedOperationException("This set is read-only!");
}
@Override
public Iterator<Cloud.Endpoint<P,P>> iterator()
{
return new NeighborIterator();
}
@Override
public boolean remove(Object o)
{
throw new UnsupportedOperationException("This set is read-only!");
}
@Override
public Object[] toArray()
{
final Set<EP> copiedNodes = new HashSet<EP>(getEndpoints());
copiedNodes.remove(getTarget());
return copiedNodes.toArray();
}
@Override
public boolean containsAll(Collection<?> c)
{
if( c.contains(this.target) )
return false;
return getEndpoints().containsAll(c);
}
@Override
public <PA> PA[] toArray(PA[] a)
{
final Set<EP> copiedNodes = new HashSet<EP>(getEndpoints());
copiedNodes.remove(getTarget());
return copiedNodes.toArray(a);
}
@Override
public boolean addAll(Collection<? extends E> c)
{
throw new UnsupportedOperationException("This set is read-only!");
}
@Override
public boolean add(Cloud.Endpoint<P,P> nEndpoint)
{
throw new UnsupportedOperationException("This set is read-only!");
}
@Override
public boolean retainAll(Collection<?> c)
{
if( this.containsAll(c) )
return false;
throw new UnsupportedOperationException("This set is read-only!");
}
@Override
public boolean remove(Object o)
{
throw new UnsupportedOperationException("This set is read-only!");
}
@Override
public boolean removeAll(Collection<?> c)
{
if( Collections.disjoint(this, c) )
return false;
throw new UnsupportedOperationException("This set is read-only!");
}
@Override
public boolean containsAll(Collection<?> c)
{
if( c.contains(AbstractEndpoint.this) )
return false;
return getEndpoints().containsAll(c);
}
@Override
public void clear()
{
if( this.size() <= 0 )
return;
throw new UnsupportedOperationException("This set is read-only!");
}
@Override
public boolean addAll(Collection<? extends Cloud.Endpoint<P,P>> c)
private class NeighborIterator implements Iterator<E>
{
private int nextLeft = (getEndpoints().size()-1);
final private Iterator<E> iterator;
public NeighborIterator()
{
throw new UnsupportedOperationException("This set is read-only!");
this.iterator = getEndpoints().iterator();
}
@Override
public boolean retainAll(Collection<?> c)
public boolean hasNext()
{
if( c.containsAll(this) )
return false;
throw new UnsupportedOperationException("This set is read-only!");
return (nextLeft > 0 ? true : false);
}
@Override
public boolean removeAll(Collection<?> c)
public E next()
{
if( Collections.disjoint(this, c) )
return false;
throw new UnsupportedOperationException("This set is read-only!");
E nextEndpoint = this.iterator.next();
this.nextLeft--;
if( !target.equals(nextEndpoint) )
return nextEndpoint;
return this.iterator.next();
}
@Override
public void clear()
public void remove()
{
if( getEndpoints().size() <= 1 )
return;
throw new UnsupportedOperationException("This set is read-only!");
throw new UnsupportedOperationException("This iterator is read-only!");
}
};
};
private class NeighborIterator implements Iterator<Cloud.Endpoint<P,P>>
{
private int nextLeft = (getEndpoints().size()-1);
final private Iterator<? extends Endpoint<?,?>> iterator;
protected abstract class AbstractEndpoint<T> implements Cloud.Endpoint<T>
{
private T target = null;
public NeighborIterator()
{
this.iterator = getEndpoints().iterator();
}
protected AbstractEndpoint()
{
}
@Override
public boolean hasNext()
{
return (nextLeft > 0 ? true : false);
}
protected AbstractEndpoint(T target)
{
this.target = target;
}
@Override
public Cloud.Endpoint<P,P> next()
{
Cloud.Endpoint<?,?> nextEndpoint = this.iterator.next();
this.nextLeft--;
protected abstract boolean isTargetEquals();
if( !AbstractEndpoint.this.equals(nextEndpoint) )
return (Cloud.Endpoint<P,P>) nextEndpoint;
return next();
}
@Override
public T getTarget()
{
return this.target;
}
@Override
public void remove()
{
throw new UnsupportedOperationException("This iterator is read-only!");
}
};
};
protected void setTarget(final T target)
{
this.target = target;
}
/**
* By default this relies on the target to define equals, this means there can be only one instance of any
* endpoint. This should be overridden to allow for an edge to have the same element more than once.
*/
@Override
public int hashCode()
{
if(!this.isTargetEquals())
return super.hashCode();
else if(this.getTarget() == null)
return 0;
else
return this.getTarget().hashCode();
}
/**
* By default this relies on the target to define equals, this means there can be only one instance of any
* endpoint. This should be overridden to allow for an edge to have the same element more than once.
*/
@Override
public boolean equals(Object obj)
{
if(!this.isTargetEquals())
return super.equals(obj);
else if( obj == null )
if( this.getTarget() == null )
return true;
else
return false;
else if( this.getTarget() == null)
return false;
else if( obj instanceof Cloud.Endpoint )
return ((Cloud.Endpoint<?>)obj).equals(this.getTarget());
else
return this.getTarget().equals(obj);
}
};
}
......@@ -18,32 +18,19 @@
******************************************************************************/
package com.syncleus.dann.graph;
import com.syncleus.dann.graph.search.pathfinding.DijkstraPathFinder;
import com.syncleus.dann.graph.search.pathfinding.PathFinder;
import com.syncleus.dann.graph.xml.*;
import com.syncleus.dann.xml.NamedValueXml;
import com.syncleus.dann.xml.Namer;
import com.syncleus.dann.xml.XmlSerializable;
import org.apache.log4j.Logger;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.*;
/**
* An AbstractAdjacencyGraph is a CloudGraph implemented using adjacency lists.
* @param <N> The node type
* @param <E> The type of edge for the given node type
*/
@XmlJavaTypeAdapter( com.syncleus.dann.xml.XmlSerializableAdapter.class )
public abstract class AbstractAdjacencyGraph<
N,
E extends Cloud<N,? extends Cloud.Endpoint<? extends N>>,
NE extends CloudGraph.NodeEndpoint<N, E>,
EE extends CloudGraph.EdgeEndpoint<N, E>
> extends AbstractCloud<Object,CloudGraph.Endpoint<?, N,E>> implements CloudGraph<N, E, NE, EE>
public abstract class AbstractCloudGraph<
NE extends CloudGraph.NodeEndpoint<?>,
EE extends CloudGraph.EdgeEndpoint<? extends Cloud<?>>
> extends AbstractCloud<NE> implements CloudGraph<NE, EE>
{
private static final Logger LOGGER = Logger.getLogger(AbstractAdjacencyGraph.class);
protected abstract Set<EdgeEndpoint<N,E>> getAdjacentEdgeEndpoints(CloudGraph.NodeEndpoint<?, ?> nodeEndpoint);
private static final Logger LOGGER = Logger.getLogger(AbstractCloudGraph.class);
/*
protected PathFinder<N,E> getPathFinder()
{
return new DijkstraPathFinder<N,E>(this);
......@@ -66,9 +53,16 @@ public abstract class AbstractAdjacencyGraph<
edges.add(destinationEndpoint.getTarget());
return Collections.unmodifiableSet(edges);
}
*/
@Override
public final boolean areEdgesFinite()
{
return true;
}
@Override
public Set<EE> getEdgeEndpoints(Cloud<?,? extends Cloud.Endpoint<?>> cloud)
public Set<EE> getEdgeEndpoints(Cloud<?> cloud)
{
Set<EE> matchingEndpoints = new HashSet<EE>();
for(final EE endpoint : this.getEdgeEndpoints() )
......@@ -81,18 +75,60 @@ public abstract class AbstractAdjacencyGraph<
}
@Override
public Set<NE> getNodeEndpoints(Object node)
public boolean containsEdgeTarget(final Cloud<?> edge)
{
Set<NE> matchingEndpoints = new HashSet<NE>();
for(NE endpoint : this.getNodeEndpoints() )
{
if( endpoint.getTarget().equals(node))
matchingEndpoints.add(endpoint);
}
for( EE endpoint : this.getEdgeEndpoints() )
if( endpoint.getTarget().equals(edge))
return true;
return false;
}
return Collections.unmodifiableSet(matchingEndpoints);
@Override
public boolean containsAllEdgeTargets(final Collection<? extends Cloud<?>> edges)
{
for( Cloud<?> edge : edges )
if( !this.containsEdgeTarget(edge) )
return false;
return true;
}
@Override
public boolean containsAnyEdgeTargets(final Collection<? extends Cloud<?>> edges)
{
for( Cloud<?> edge : edges )
if( this.containsTarget(edge) )
return true;
return false;
}
@Override
public boolean containsEdge(final Cloud.Endpoint<?> endpoint)
{
for( EE otherEndpoint : this.getEdgeEndpoints() )
if( otherEndpoint.equals(endpoint))
return true;
return false;
}
@Override
public boolean containsAllEdges(final Collection<? extends Cloud.Endpoint<?>> endpoints)
{
for( Cloud.Endpoint<?> endpoint : endpoints )
if( !this.containsEdge(endpoint) )
return false;
return true;
}
@Override
public boolean containsAnyEdges(final Collection<? extends Cloud.Endpoint<?>> endpoints)
{
for( Cloud.Endpoint<?> endpoint : endpoints )
if( this.containsEdge(endpoint) )
return true;
return false;
}
/*
@Override
public Set<N> getAdjacentNodes(Object node)
{
......@@ -127,6 +163,7 @@ public abstract class AbstractAdjacencyGraph<
return Collections.<CloudGraph.Endpoint<?, N, E>>unmodifiableSet(endpoints);
}
@Override
public boolean isTraversable(Object source, Object destination)
{
......@@ -386,114 +423,67 @@ public abstract class AbstractAdjacencyGraph<
return Collections.unmodifiableSet(sourceNodes);
}
*/
/**
* Clones the current object.
* @return A clone of the current object, with no changes
*/
@Override
protected AbstractAdjacencyGraph<N, E, NE, EE> clone()
protected AbstractCloudGraph<NE, EE> clone()
{
return (AbstractAdjacencyGraph<N, E, NE, EE>) super.clone();
return (AbstractCloudGraph<NE, EE>) super.clone();
}
/**
* Converts the current AbstractAdjacencyGraph to a GraphXML.
* @return The GraphXML representation of this AbstractAdjacencyGraph
*/
@Override
public GraphXml toXml()
protected class Endpoints implements CloudGraph.Endpoints<NE,EE>
{
final GraphElementXml xml = new GraphElementXml();
final Namer<Object> namer = new Namer<Object>();
private final Set<NE> nodeEndpoints;
private final Set<EE> edgeEndpoints;
xml.setNodeInstances(new GraphElementXml.NodeInstances());
for(N node : this.getNodes())
public Endpoints(final Set<NE> nodeEndpoints, final Set<EE> edgeEndpoints)
{
final String nodeName = namer.getNameOrCreate(node);
final Object nodeXml;
if(node instanceof XmlSerializable)
nodeXml = ((XmlSerializable)node).toXml(namer);
else
//if the object isnt XmlSerializable lets try to just serialize it as a regular JAXB object
nodeXml = node;
final NamedValueXml encapsulation = new NamedValueXml();
encapsulation.setName(nodeName);
encapsulation.setValue(nodeXml);
this.nodeEndpoints = nodeEndpoints;
this.edgeEndpoints = edgeEndpoints;
}
xml.getNodeInstances().getNodes().add(encapsulation);
@Override
public Set<NE> getNodeEndpoints()
{
return nodeEndpoints;
}
this.toXml(xml, namer);
return xml;
@Override
public Set<EE> getEdgeEndpoints()
{
return edgeEndpoints;
}
}
/**
* Converts a given Namer to its GraphXML representation.
* @param namer The namer to convert
* @return The GraphXML representation of this namer
*/
@Override
public GraphXml toXml(final Namer<Object> namer)
{
if(namer == null)
throw new IllegalArgumentException("namer can not be null");
final GraphXml xml = new GraphXml();
this.toXml(xml, namer);
return xml;
}
/*
/**
* Adds a current Namer to the given GraphXML object.
* @param jaxbObject The graph to add the object to
* @param namer THe namer to add to the GraphXML
*/
/*
@Override
public void toXml(final GraphXml jaxbObject, final Namer<Object> namer)
protected abstract class AbstractNodeEndpoint<T> extends AbstractCloud<NE>.AbstractEndpoint<T> implements CloudGraph.NodeEndpoint<T>
{
if(namer == null)
throw new IllegalArgumentException("nodeNames can not be null");
if(jaxbObject == null)
throw new IllegalArgumentException("jaxbObject can not be null");
for(N node : this.getNodes())
protected AbstractNodeEndpoint()
{
final String nodeName = namer.getNameOrCreate(node);
final Object nodeXml;
if(node instanceof XmlSerializable)
nodeXml = ((XmlSerializable)node).toXml(namer);
else
// if the object isnt XmlSerializable lets try to just serialize
// it as a regular JAXB object
nodeXml = node;
final NameXml encapsulation = new NameXml();
encapsulation.setName(nodeName);
if( jaxbObject.getNodes() == null )
jaxbObject.setNodes(new GraphXml.Nodes());
jaxbObject.getNodes().getNodes().add(encapsulation);
}
for(E edge : this.getEdges())
protected AbstractNodeEndpoint(T target)
{
final EdgeXml edgeXml = edge.toXml(namer);
super(target);
}
if( jaxbObject.getEdges() == null )
jaxbObject.setEdges(new GraphXml.Edges());
jaxbObject.getEdges().getEdges().add(edgeXml);
@Override
public final boolean isNodeEndpoint()
{
return true;
}
}
*/
protected abstract class AbstractNodeEndpoint extends AbstractCloud<? super N,CloudGraph.Endpoint<? super N, N,E>>.AbstractEndpoint<N> implements CloudGraph.NodeEndpoint<N,E>
{
@Override
public boolean isEdgeEndpoint()
{
return false;
}
/*
@Override
public Set<CloudGraph.EdgeEndpoint<N, E>> getAdjacentEdges()
{
......@@ -526,7 +516,7 @@ public abstract class AbstractAdjacencyGraph<
for(CloudGraph.EdgeEndpoint<N, E> adjacentEndpoint : this.getAdjacentEdges() )
for( Cloud.Endpoint<? extends N> nodeEndpoint : adjacentEndpoint.getTarget().getEndpoints(this.getTarget()) )
for( Cloud.Endpoint<? extends N> adjacentNodeEndpoint : nodeEndpoint.getNeighbors() )
adjacentNodes.addAll(AbstractAdjacencyGraph.this.getNodeEndpoints(adjacentNodeEndpoint.getTarget()));
adjacentNodes.addAll(AbstractCloudGraph.this.getNodeEndpoints(adjacentNodeEndpoint.getTarget()));
return Collections.<CloudGraph.NodeEndpoint<N, E>>unmodifiableSet(adjacentNodes);
}
......@@ -539,7 +529,7 @@ public abstract class AbstractAdjacencyGraph<
for(CloudGraph.EdgeEndpoint<N, E> adjacentEndpoint : this.getAdjacentEdges() )
for( Cloud.Endpoint<? extends N> nodeEndpoint : adjacentEndpoint.getTarget().getEndpoints(this.getTarget()) )
for( Cloud.Endpoint<? extends N> adjacentNodeEndpoint : nodeEndpoint.getTraversableNeighborsTo() )
adjacentNodes.addAll(AbstractAdjacencyGraph.this.getNodeEndpoints(adjacentNodeEndpoint.getTarget()));
adjacentNodes.addAll(AbstractCloudGraph.this.getNodeEndpoints(adjacentNodeEndpoint.getTarget()));
return Collections.unmodifiableSet(adjacentNodes);
}
......@@ -552,7 +542,7 @@ public abstract class AbstractAdjacencyGraph<
for(CloudGraph.EdgeEndpoint<N, E> adjacentEndpoint : this.getAdjacentEdges() )
for( Cloud.Endpoint<? extends N> nodeEndpoint : adjacentEndpoint.getTarget().getEndpoints(this.getTarget()) )
for( Cloud.Endpoint<? extends N> adjacentNodeEndpoint : nodeEndpoint.getTraversableNeighborsFrom() )
adjacentNodes.addAll(AbstractAdjacencyGraph.this.getNodeEndpoints(adjacentNodeEndpoint.getTarget()));
adjacentNodes.addAll(AbstractCloudGraph.this.getNodeEndpoints(adjacentNodeEndpoint.getTarget()));
return Collections.unmodifiableSet(adjacentNodes);
}
......@@ -582,10 +572,33 @@ public abstract class AbstractAdjacencyGraph<
return Collections.unmodifiableSet(adjacentEdges);
}
*/
};
protected abstract class AbstractEdgeEndpoint extends AbstractCloud<? super E,CloudGraph.Endpoint<? super E, N,E>>.AbstractEndpoint<E> implements CloudGraph.EdgeEndpoint<N,E>
protected abstract class AbstractEdgeEndpoint<T extends Cloud<?>> extends AbstractCloud<NE>.AbstractEndpoint<T> implements CloudGraph.EdgeEndpoint<T>
{
protected AbstractEdgeEndpoint()
{
}
protected AbstractEdgeEndpoint(T target)
{
super(target);
}
@Override
public boolean isNodeEndpoint()
{
return false;
}
@Override
public final boolean isEdgeEndpoint()
{
return true;
}
/*
@Override
public Set<CloudGraph.NodeEndpoint<N, E>> getAdjacent()
{
......@@ -610,7 +623,7 @@ public abstract class AbstractAdjacencyGraph<
final Set<CloudGraph.NodeEndpoint<N, E>> adjacentNodes = new HashSet<CloudGraph.NodeEndpoint<N, E>>();
for(Endpoint<? extends N> adjacentEndpoint : this.getTarget().getEndpoints())
adjacentNodes.addAll(AbstractAdjacencyGraph.this.getNodeEndpoints(adjacentEndpoint.getTarget()));
adjacentNodes.addAll(AbstractCloudGraph.this.getNodeEndpoints(adjacentEndpoint.getTarget()));
return Collections.unmodifiableSet(adjacentNodes);
}
......@@ -621,8 +634,8 @@ public abstract class AbstractAdjacencyGraph<
final Set<CloudGraph.EdgeEndpoint<N, E>> adjacentEdges = new HashSet<CloudGraph.EdgeEndpoint<N, E>>();
for(Endpoint<? extends N> sourceEndpoint : this.getTarget().getEndpoints())
for( NE neighborNode : AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()) )
adjacentEdges.addAll(AbstractAdjacencyGraph.this.getAdjacentEdgeEndpoints(neighborNode));
for( NE neighborNode : AbstractCloudGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()) )
adjacentEdges.addAll(AbstractCloudGraph.this.getAdjacentEdgeEndpoints(neighborNode));
adjacentEdges.remove(this);
return Collections.unmodifiableSet(adjacentEdges);
......@@ -635,8 +648,8 @@ public abstract class AbstractAdjacencyGraph<
for(Endpoint<? extends N> sourceEndpoint : this.getTarget().getEndpoints())
if( sourceEndpoint.getTraversableNeighborsFrom().size() > 0 )
for( NE adjacentNode : AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()))
for( CloudGraph.EdgeEndpoint<N, E> adjacentEdge : AbstractAdjacencyGraph.this.getAdjacentEdgeEndpoints(adjacentNode) )
for( NE adjacentNode : AbstractCloudGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()))
for( CloudGraph.EdgeEndpoint<N, E> adjacentEdge : AbstractCloudGraph.this.getAdjacentEdgeEndpoints(adjacentNode) )
if( adjacentEdge.getTarget().getTraversableFrom(adjacentNode.getTarget()).size() > 0 )
adjacentEdges.add(adjacentEdge);
......@@ -650,8 +663,8 @@ public abstract class AbstractAdjacencyGraph<
for(Endpoint<? extends N> sourceEndpoint : this.getTarget().getEndpoints())
if( sourceEndpoint.getTraversableNeighborsTo().size() > 0 )
for( NE adjacentNode : AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()))
for( CloudGraph.EdgeEndpoint<N, E> adjacentEdge : AbstractAdjacencyGraph.this.getAdjacentEdgeEndpoints(adjacentNode) )
for( NE adjacentNode : AbstractCloudGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()))
for( CloudGraph.EdgeEndpoint<N, E> adjacentEdge : AbstractCloudGraph.this.getAdjacentEdgeEndpoints(adjacentNode) )
if( adjacentEdge.getTarget().getTraversableTo(adjacentNode.getTarget()).size() > 0 )
adjacentEdges.add(adjacentEdge);
......@@ -665,7 +678,7 @@ public abstract class AbstractAdjacencyGraph<
for(Endpoint<? extends N> sourceEndpoint : this.getTarget().getEndpoints())
if( sourceEndpoint.getTraversableNeighborsFrom().size() > 0 )
adjacentNodes.addAll(AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()));
adjacentNodes.addAll(AbstractCloudGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()));
return Collections.unmodifiableSet(adjacentNodes);
}
......@@ -677,9 +690,10 @@ public abstract class AbstractAdjacencyGraph<
for(Endpoint<? extends N> sourceEndpoint : this.getTarget().getEndpoints())
if( sourceEndpoint.getTraversableNeighborsTo().size() > 0 )
adjacentNodes.addAll(AbstractAdjacencyGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()));
adjacentNodes.addAll(AbstractCloudGraph.this.getNodeEndpoints(sourceEndpoint.getTarget()));
return Collections.unmodifiableSet(adjacentNodes);
}
*/
};
}
......@@ -22,7 +22,7 @@ import java.util.List;
// TODO refine the verify and equals method to match a cycles definition of
// unique. i.e. no repeat in nodes or edges, sequence matters but starting point doesnt.
public abstract class AbstractCycle<N, E extends Cloud<N>> extends AbstractWalk<N, E> implements Cycle<N, E>
public abstract class AbstractCycle<N, E extends Cloud<N>> extends AbstractPath<N, E> implements Cycle<N, E>
{
@Override
protected boolean verify(final List<N> nodeSteps, final List<E> edgeSteps)
......
......@@ -20,186 +20,18 @@ package com.syncleus.dann.graph;
import java.util.*;
public abstract class AbstractDirectedEdge<N, SN extends N, DN extends N> extends AbstractBidirectedEdge<N, SN,DN> implements MixableDirectedEdge<N, SN,DN>
public abstract class AbstractDirectedEdge<E extends DirectedEdge.Endpoint<?>> extends AbstractMixableDirectedEdge<E,E,E> implements DirectedEdge<E>
{
private static final long serialVersionUID = -7589242369886611386L;
@Override
public final AbstractSourceEndpoint getLeftEndPoint()
{
return this.getSourceEndPoint();
}
@Override
public final AbstractDestinationEndpoint getRightEndPoint()
{
return this.getDestinationEndPoint();
}
@Override
public abstract AbstractSourceEndpoint getSourceEndPoint();
@Override
public abstract AbstractDestinationEndpoint getDestinationEndPoint();
@Override
public final boolean isIntroverted()
{
return false;
}
@Override
public final boolean isExtroverted()
{
return false;
}
@Override
public final boolean isDirected()
{
return true;
}
@Override
public final boolean isHalfEdge()
{
return false;
}
@Override
public final boolean isLooseEdge()
{
return false;
}
@Override
public final boolean isOrdinaryEdge()
{
return true;
}
@Override
public String toString()
{
return this.getSourceEndPoint().getTarget() + "->" + this.getDestinationEndPoint().getTarget();
}
@Override
protected AbstractDirectedEdge<N, SN,DN> clone()
protected abstract class AbstractEndpoint<T> extends AbstractMixableDirectedEdge<E,E,E>.AbstractEndpoint<T> implements DirectedEdge.Endpoint<T>
{
return (AbstractDirectedEdge<N, SN,DN>) super.clone();
}
protected abstract class AbstractSourceEndpoint extends AbstractEndpoint<SN,DN> implements MixableDirectedEdge.Endpoint<N, SN,DN>
{
public AbstractSourceEndpoint()
{
super(Direction.INWARD);
}
public AbstractSourceEndpoint(SN node)
{
super(node, Direction.INWARD);
}
@Override
public final MixableBidirectedEdge.Endpoint<N, DN,SN> getNeighbor()
{
return getDestinationEndPoint();
}
@Override
public final Set<Endpoint<N, N>> getTraversableNeighborsTo()
{
return Collections.<Endpoint<N, N>>singleton(getDestinationEndPoint());
}
@Override
public final Set<Endpoint<N, N>> getTraversableNeighborsFrom()
{
return Collections.emptySet();
}
@Override
public final boolean isTraversable()
{
return true;
}
@Override
public final boolean isTraversable(Endpoint<N, N> destination)
{
if( destination == null )
throw new IllegalArgumentException("destination can not be null");
return destination.equals(this.getNeighbor());
}
@Override
public final boolean isTraversable(N destination)
{
if(destination == null)
{
if(this.getNeighbor().getTarget() == null)
return true;
else
return false;
}
else if(this.getNeighbor().getTarget() == null)
return false;
return destination.equals(this.getNeighbor().getTarget());
}
};
protected abstract class AbstractDestinationEndpoint extends AbstractEndpoint<DN,SN> implements MixableDirectedEdge.Endpoint<N, DN,SN>
{
public AbstractDestinationEndpoint()
{
super(Direction.OUTWARD);
}
public AbstractDestinationEndpoint(DN node)
{
super(node, Direction.OUTWARD);
}
@Override
public final MixableBidirectedEdge.Endpoint<N, SN,DN> getNeighbor()
{
return getDestinationEndPoint();
}
@Override
public final Set<Endpoint<N, N>> getTraversableNeighborsTo()
{
return Collections.emptySet();
}
@Override
public final Set<Endpoint<N, N>> getTraversableNeighborsFrom()
{
return Collections.<Endpoint<N, N>>singleton(getSourceEndPoint());
}
@Override
public final boolean isTraversable()
{
return false;
}
@Override
public final boolean isTraversable(Endpoint<N, N> destination)
protected AbstractEndpoint(Direction direction)
{
return false;
super(direction);
}
@Override
public final boolean isTraversable(N destination)
protected AbstractEndpoint(T target, Direction direction)
{
return false;
super(target, direction);
}
};
}
}
\ No newline at end of file
......@@ -19,15 +19,10 @@
package com.syncleus.dann.graph;
public abstract class AbstractEdge<
T,
EP extends Edge.Endpoint<? extends T>
> extends AbstractCloud<T,EP> implements Edge<T,EP>
E extends Edge.Endpoint<?>
> extends AbstractMixableEdge<E,E,E> implements Edge<E>
{
protected abstract class AbstractEndpoint<TT> extends AbstractCloud<T,EP>.AbstractEndpoint<TT>
protected abstract class AbstractEndpoint<T> extends AbstractMixableEdge<E,E,E>.AbstractEndpoint<T> implements Edge.Endpoint<T>
{
protected AbstractEndpoint(final boolean isTargetEquals)
{
super(isTargetEquals);
}
}
}
......@@ -18,7 +18,7 @@
******************************************************************************/
package com.syncleus.dann.graph;
public abstract class AbstractHyperedge<N> extends AbstractEdge<N> implements Hyperedge<N>
public abstract class AbstractHyperedge<E extends Hyperedge.Endpoint<?>> extends AbstractCloud<E> implements Hyperedge<E>
{
private static final long serialVersionUID = -3657973823101515199L;
......@@ -118,65 +118,21 @@ public abstract class AbstractHyperedge<N> extends AbstractEdge<N> implements Hy
}
@Override
protected AbstractHyperedge<N> clone()
protected AbstractHyperedge<E> clone()
{
return (AbstractHyperedge<N>) super.clone();
/*
final AbstractHyperedge<N> clonedEdge = (AbstractHyperedge<N>) super.clone();
if( !this.contextEnabled )
return clonedEdge;
List<ContextNode> connectedNodes = new ArrayList<ContextNode>();
try
{
for(N node : this.nodes)
{
if( node instanceof ContextNode )
{
ContextNode contextNode = (ContextNode)node;
contextNode.connectingEdge(clonedEdge);
contextNode.connectedEdge(clonedEdge);
connectedNodes.add(contextNode);
}
}
}
catch(RejectedContextException caught)
{
//we need to leave all the connections we made
for(ContextNode connectedNode : connectedNodes)
connectedNode.disconnectedEdge(clonedEdge);
throw new InvalidContextException(caught);
}
return clonedEdge;
*/
return (AbstractHyperedge<E>) super.clone();
}
protected abstract class AbstractEndpoint<EN extends N, ON extends N> extends AbstractEdge.AbstractEndpoint<EN> implements Hyperedge.Endpoint<N, EN>
protected abstract class AbstractEndpoint<T> extends AbstractCloud<E>.AbstractEndpoint<T> implements Hyperedge.Endpoint<T>
{
private EN node = null;
protected AbstractEndpoint()
{
super();
}
protected AbstractEndpoint(EN node)
{
super();
this.node = node;
}
@Override
public EN getTarget()
{
return this.node;
}
public void setTarget(final EN node)
protected AbstractEndpoint(T target)
{
this.node = node;
super(target);
}
};
}
......@@ -20,7 +20,7 @@ package com.syncleus.dann.graph;
import java.util.Set;
public abstract class AbstractHypergraph<N, E extends Hyperedge<N>> extends AbstractAdjacencyGraph<N, E> implements Hypergraph<N, E>
public abstract class AbstractHypergraph<N, E extends Hyperedge<N>> extends AbstractCloudGraph<N, E> implements Hypergraph<N, E>
{
protected AbstractHypergraph()
{
......
/******************************************************************************
* *
* Copyright: (c) Syncleus, Inc. *
* *
* You may redistribute and modify this source code under the terms and *
* conditions of the Open Source Community License - Type C version 1.0 *
* or any later version as published by Syncleus, Inc. at www.syncleus.com. *
* There should be a copy of the license included with this file. If a copy *
* of the license is not included you are granted no right to distribute or *
* otherwise use this file except through a legal and valid license. You *
* should also contact Syncleus, Inc. at the information below if you cannot *
* find a license: *
* *
* Syncleus, Inc. *
* 2604 South 12th Street *
* Philadelphia, PA 19148 *
* *
******************************************************************************/
package com.syncleus.dann.graph;
import java.util.*;
public abstract class AbstractMixableBidirectedEdge<
E extends MixableBidirectedEdge.Endpoint<?>,
LE extends E,
RE extends E
> extends AbstractMixableEdge<E, LE, RE> implements MixableBidirectedEdge<E, LE, RE>
{
@Override
public boolean isIntroverted()
{
return (this.getRightEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.INWARD) && (this.getLeftEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.INWARD);
}
@Override
public boolean isExtroverted()
{
return (this.getRightEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.OUTWARD) && (this.getLeftEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.OUTWARD);
}
@Override
public boolean isDirected()
{
if( (this.getRightEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.INWARD) && (this.getLeftEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.OUTWARD) )
return true;
else if( (this.getRightEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.OUTWARD) && (this.getLeftEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.INWARD) )
return true;
return false;
}
@Override
public boolean isHalfEdge()
{
if( (this.getRightEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.NONE) && (this.getLeftEndpoint().getDirection() != MixableBidirectedEdge.Endpoint.Direction.NONE) )
return true;
else if( (this.getRightEndpoint().getDirection() != MixableBidirectedEdge.Endpoint.Direction.NONE) && (this.getLeftEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.NONE) )
return true;
return false;
}
@Override
public boolean isLooseEdge()
{
return (this.getRightEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.NONE) && (this.getLeftEndpoint().getDirection() == MixableBidirectedEdge.Endpoint.Direction.NONE);
}
@Override
public boolean isOrdinaryEdge()
{
return (!this.isHalfEdge()) && (!this.isLooseEdge());
}
@Override
public boolean isLoop()
{
return this.getLeftEndpoint().getDirection().equals(this.getRightEndpoint().getDirection());
}
@Override
public Set<E> getTraversableFrom(TraversableCloud.Endpoint<?> source)
{
final Set<E> traversableEndpoints = new HashSet<E>();
for( final E toEndpoint : getNeighbors(source))
if( this.isTraversable(source, toEndpoint) )
traversableEndpoints.add(toEndpoint);
return Collections.unmodifiableSet(traversableEndpoints);
}
@Override
public Set<E> getTraversableTo(TraversableCloud.Endpoint<?> destination)
{
final Set<E> traversableEndpoints = new HashSet<E>();
for( final E fromEndpoint : getNeighbors(destination) )
if( this.isTraversable(fromEndpoint, destination))
traversableEndpoints.add(fromEndpoint);
return Collections.unmodifiableSet(traversableEndpoints);
}
@Override
public boolean isTraversableFrom(TraversableCloud.Endpoint<?> source)
{
return !this.getTraversableFrom(source).isEmpty();
}
@Override
public boolean isTraversableTo(TraversableCloud.Endpoint<?> destination)
{
return !this.getTraversableTo(destination).isEmpty();
}
@Override
public String toString()
{
return this.getLeftEndpoint().getTarget().toString()
+ endStateToString(this.getLeftEndpoint().getDirection(), true)
+ '-'
+ endStateToString(this.getRightEndpoint().getDirection(), false)
+ this.getRightEndpoint().getTarget();
}
private static String endStateToString(final MixableBidirectedEdge.Endpoint.Direction state, final boolean isLeft)
{
switch(state)
{
case INWARD:
return (isLeft ? ">" : "<");
case OUTWARD:
return (isLeft ? "<" : ">");
default:
return "";
}
}
@Override
protected AbstractMixableBidirectedEdge<E,LE,RE> clone()
{
return (AbstractMixableBidirectedEdge<E,LE,RE>) super.clone();
}
/*
@Override
public BidirectedEdgeXml toXml()
{
final Namer namer = new Namer();
final BidirectedEdgeElementXml xml = new BidirectedEdgeElementXml();
xml.setNodeInstances(new BidirectedEdgeElementXml.NodeInstances());
final Set<N> writtenNodes = new HashSet<N>();
for (N node : this.getTargets())
{
if (writtenNodes.add(node))
{
final NamedValueXml named = new NamedValueXml();
named.setName(namer.getNameOrCreate(node));
if (node instanceof XmlSerializable )
{
named.setValue(((XmlSerializable) node).toXml(namer));
}
else
{
named.setValue(node);
}
xml.getNodeInstances().getNodes().add(named);
}
}
return xml;
}
@Override
public BidirectedEdgeXml toXml(final Namer<Object> nodeNames)
{
if (nodeNames == null)
{
throw new IllegalArgumentException("nodeNames can not be null");
}
final BidirectedEdgeXml xml = new BidirectedEdgeXml();
this.toXml(xml, nodeNames);
return xml;
}
@Override
public void toXml(final EdgeXml jaxbObject, final Namer<Object> nodeNames)
{
if (nodeNames == null)
{
throw new IllegalArgumentException("nodeNames can not be null");
}
if (jaxbObject == null)
{
throw new IllegalArgumentException("jaxbObject can not be null");
}
super.toXml(jaxbObject, nodeNames);
if (jaxbObject instanceof BidirectedEdgeXml)
{
((BidirectedEdgeXml) jaxbObject).setLeftNode(nodeNames.getNameOrCreate(this.getLeftEndpoint().getTarget()));
((BidirectedEdgeXml) jaxbObject).setRightNode(nodeNames.getNameOrCreate(this.getRightEndpoint().getTarget()));
((BidirectedEdgeXml) jaxbObject).setLeftDirection(this.getLeftEndpoint().getDirection().toString().toLowerCase());
((BidirectedEdgeXml) jaxbObject).setRightDirection(this.getRightEndpoint().getDirection().toString().toLowerCase());
}
}
*/
protected abstract class AbstractEndpoint<T> extends AbstractMixableEdge<E,LE,RE>.AbstractEndpoint<T> implements MixableBidirectedEdge.Endpoint<T>
{
private Direction direction;
protected AbstractEndpoint(Direction direction)
{
super();
if( direction == null )
throw new IllegalArgumentException("direction can not be null!");
this.direction = direction;
}
protected AbstractEndpoint(T target, Direction direction)
{
super(target);
if( direction == null )
throw new IllegalArgumentException("direction can not be null!");
this.direction = direction;
}
@Override
public Direction getDirection()
{
return this.direction;
}
protected void setDirection(final Direction direction)
{
this.direction = direction;
}
@Override
public boolean isTraversableFrom(TraversableCloud.Endpoint<?> target)
{
return isTraversable(target, this);
}
@Override
public boolean isTraversableTo(TraversableCloud.Endpoint<?> target)
{
return isTraversable(this, target);
}
@Override
public boolean isTraversableFrom()
{
return isTraversableFrom(this);
}
@Override
public boolean isTraversableTo()
{
return isTraversableTo(this);
}
};
}
\ No newline at end of file
/******************************************************************************
* *
* Copyright: (c) Syncleus, Inc. *
* *
* You may redistribute and modify this source code under the terms and *
* conditions of the Open Source Community License - Type C version 1.0 *
* or any later version as published by Syncleus, Inc. at www.syncleus.com. *
* There should be a copy of the license included with this file. If a copy *
* of the license is not included you are granted no right to distribute or *
* otherwise use this file except through a legal and valid license. You *
* should also contact Syncleus, Inc. at the information below if you cannot *
* find a license: *
* *
* Syncleus, Inc. *
* 2604 South 12th Street *
* Philadelphia, PA 19148 *
* *
******************************************************************************/
package com.syncleus.dann.graph;
public abstract class AbstractMixableDirectedEdge<
E extends MixableDirectedEdge.Endpoint<?>,
SE extends E,
DE extends E
> extends AbstractMixableBidirectedEdge<E,SE,DE> implements MixableDirectedEdge<E,SE,DE>
{
private static final long serialVersionUID = -5892401329886611386L;
@Override
public final SE getLeftEndpoint()
{
return this.getSourceEndpoint();
}
@Override
public final DE getRightEndpoint()
{
return this.getDestinationEndpoint();
}
@Override
public final boolean isIntroverted()
{
return false;
}
@Override
public final boolean isExtroverted()
{
return false;
}
@Override
public final boolean isDirected()
{
return true;
}
@Override
public final boolean isHalfEdge()
{
return false;
}
@Override
public final boolean isLooseEdge()
{
return false;
}
@Override
public final boolean isOrdinaryEdge()
{
return true;
}
@Override
public String toString()
{
return this.getSourceEndpoint().getTarget() + "->" + this.getDestinationEndpoint().getTarget();
}
@Override
protected AbstractMixableDirectedEdge<E,SE,DE> clone()
{
return (AbstractMixableDirectedEdge<E,SE,DE>) super.clone();
}
protected abstract class AbstractEndpoint<T> extends AbstractMixableBidirectedEdge<E,SE,DE>.AbstractEndpoint<T> implements MixableDirectedEdge.Endpoint<T>
{
protected AbstractEndpoint(Direction direction)
{
super(direction);
}
protected AbstractEndpoint(T target, Direction direction)
{
super(target,direction);
}
};
}
\ No newline at end of file
/******************************************************************************
* *
* Copyright: (c) Syncleus, Inc. *
* *
* You may redistribute and modify this source code under the terms and *
* conditions of the Open Source Community License - Type C version 1.0 *
* or any later version as published by Syncleus, Inc. at www.syncleus.com. *
* There should be a copy of the license included with this file. If a copy *
* of the license is not included you are granted no right to distribute or *
* otherwise use this file except through a legal and valid license. You *
* should also contact Syncleus, Inc. at the information below if you cannot *
* find a license: *
* *
* Syncleus, Inc. *
* 2604 South 12th Street *
* Philadelphia, PA 19148 *
* *
******************************************************************************/
package com.syncleus.dann.graph;
import java.util.*;
public abstract class AbstractMixableEdge<
E extends MixableEdge.Endpoint<?>,
LE extends E,
RE extends E
> extends AbstractHyperedge<E> implements MixableEdge<E,LE,RE>
{
@Override
public Set<E> getEndpoints()
{
return new PairSet();
}
@Override
public Set<E> getNeighbors(Endpoint<?> endpoint)
{
if(this.getLeftEndpoint().equals(endpoint))
return Collections.singleton(this.getRightEndpoint());
else if(this.getRightEndpoint().equals(endpoint))
return Collections.singleton(this.getLeftEndpoint());
else
return Collections.emptySet();
}
private class PairSet extends AbstractSet<E>
{
@Override
public Iterator<E> iterator()
{
return new PairIterator();
}
@Override
public int size()
{
return 2;
}
@Override
public boolean contains(Object o)
{
if( (getLeftEndpoint().equals(o)) || (getRightEndpoint().equals(o)) )
return true;
return false;
}
@Override
public Endpoint<?>[] toArray()
{
return new Endpoint<?>[]{getLeftEndpoint(),getRightEndpoint()};
}
@Override
public <T> T[] toArray(T[] a)
{
a[0] = (T) getLeftEndpoint();
a[1] = (T) getRightEndpoint();
return a;
}
@Override
public boolean add(E nnEndpoint)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public boolean remove(Object o)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public boolean containsAll(Collection<?> c)
{
for(Object object : c)
if( !this.contains(object) )
return false;
return true;
}
@Override
public boolean addAll(Collection<? extends E> c)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public boolean retainAll(Collection<?> c)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public boolean removeAll(Collection<?> c)
{
throw new UnsupportedOperationException("This Set is read-only!");
}
@Override
public void clear()
{
throw new UnsupportedOperationException("This Set is read-only!");
}
private class PairIterator implements Iterator<E>
{
private Boolean beforeRight = false;
@Override
public boolean hasNext()
{
return (beforeRight != null);
}
@Override
public E next()
{
if(beforeRight == null)
throw new NoSuchElementException("no elements left");
else if(!beforeRight)
{
beforeRight = true;
return getLeftEndpoint();
}
else
{
beforeRight = null;
return getRightEndpoint();
}
}
@Override
public void remove()
{
throw new UnsupportedOperationException("This is a read-only iterator!");
}
}
}
protected abstract class AbstractEndpoint<T> extends AbstractCloud<E>.AbstractEndpoint<T>
{
protected AbstractEndpoint()
{
super();
}
protected AbstractEndpoint(T target)
{
super(target);
}
}
}
\ No newline at end of file
/******************************************************************************
* *
* Copyright: (c) Syncleus, Inc. *
* *
* You may redistribute and modify this source code under the terms and *
* conditions of the Open Source Community License - Type C version 1.0 *
* or any later version as published by Syncleus, Inc. at www.syncleus.com. *
* There should be a copy of the license included with this file. If a copy *
* of the license is not included you are granted no right to distribute or *
* otherwise use this file except through a legal and valid license. You *
* should also contact Syncleus, Inc. at the information below if you cannot *
* find a license: *
* *
* Syncleus, Inc. *
* 2604 South 12th Street *
* Philadelphia, PA 19148 *
* *
******************************************************************************/
package com.syncleus.dann.graph;
public abstract class AbstractMixableUndirectedEdge<
E extends MixableBidirectedEdge.Endpoint<?>,
LE extends E,
RE extends E
> extends AbstractMixableBidirectedEdge<E,LE,RE> implements MixableBidirectedEdge<E,LE,RE>
{
private static final long serialVersionUID = 20943589023542L;
@Override
public final boolean isIntroverted()
{
return false;
}
@Override
public final boolean isExtroverted()
{
return false;
}
@Override
public final boolean isDirected()
{
return false;
}
@Override
public final boolean isHalfEdge()
{
return false;
}
@Override
public final boolean isLooseEdge()
{
return true;
}
@Override
public final boolean isOrdinaryEdge()
{
return false;
}
@Override
protected AbstractMixableUndirectedEdge<E,LE,RE> clone()
{
return (AbstractMixableUndirectedEdge<E,LE,RE>) super.clone();
}
}
......@@ -28,7 +28,7 @@ public abstract class AbstractMutableAdjacencyGraph<
NE extends MutableCloudGraph.NodeEndpoint<N, E>,
EE extends MutableCloudGraph.EdgeEndpoint<N, E>
>
extends AbstractAdjacencyGraph<N, E, NE, EE>
extends AbstractCloudGraph<N, E, NE, EE>
implements MutableCloudGraph<N, E, NE, EE>
{
private static final long serialVersionUID = -4613327727609060678L;
......@@ -216,7 +216,7 @@ public abstract class AbstractMutableAdjacencyGraph<
}
protected abstract class AbstractNodeEndpoint extends AbstractAdjacencyGraph<N,E,NE,EE>.AbstractNodeEndpoint implements MutableCloudGraph.NodeEndpoint<N, E>
protected abstract class AbstractNodeEndpoint extends AbstractCloudGraph<N,E,NE,EE>.AbstractNodeEndpoint implements MutableCloudGraph.NodeEndpoint<N, E>
{
private N target;
......@@ -246,7 +246,7 @@ public abstract class AbstractMutableAdjacencyGraph<
}
};
protected abstract class AbstractEdgeEndpoint extends AbstractAdjacencyGraph<N,E,NE,EE>.AbstractEdgeEndpoint implements MutableCloudGraph.EdgeEndpoint<N, E>
protected abstract class AbstractEdgeEndpoint extends AbstractCloudGraph<N,E,NE,EE>.AbstractEdgeEndpoint implements MutableCloudGraph.EdgeEndpoint<N, E>
{
private E target;
......
......@@ -18,99 +18,128 @@
******************************************************************************/
package com.syncleus.dann.graph;
import java.util.ArrayList;
import com.syncleus.dann.graph.cycle.CycleFinder;
import com.syncleus.dann.graph.cycle.ExhaustiveDepthFirstSearchCycleFinder;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public abstract class AbstractPath<N, E extends Cloud<N>> extends AbstractWalk<N, E> implements Path<N, E>
public abstract class AbstractPath<N, E extends Cloud<N>> implements Path<N, E>
{
@Override
protected boolean verify(final List<N> nodeSteps, final List<E> edgeSteps)
{
return ((super.verify(nodeSteps, edgeSteps)) && (verifyUtility(nodeSteps, edgeSteps)));
}
static <N, E extends Cloud<N>> boolean verifyUtility(final List<N> nodeSteps, final List<E> edgeSteps)
{
if( nodeSteps.size() < 2 )
if( edgeSteps == null )
throw new IllegalArgumentException("steps can not be null");
if( edgeSteps.contains(null) )
throw new IllegalArgumentException("steps can not contain a null");
if( nodeSteps == null )
throw new IllegalArgumentException("nodeSteps can not be null");
if( nodeSteps.contains(null) )
throw new IllegalArgumentException("nodeSteps can not contain a null");
if( (nodeSteps.size() != (edgeSteps.size() + 1)) || (nodeSteps.size() < 2) || (edgeSteps.size() < 1) )
throw new IllegalArgumentException("Wrong number of nodes or steps");
return !(nodeSteps.get(0).equals(nodeSteps.get(nodeSteps.size() - 1)));
int nextNodeIndex = 0;
for(final E edgeStep : edgeSteps)
{
if( !edgeStep.getTargets().contains(nodeSteps.get(nextNodeIndex)) )
return false;
nextNodeIndex++;
}
return edgeSteps.get(edgeSteps.size() - 1).getTargets().contains(nodeSteps.get(nextNodeIndex));
}
@Override
public boolean isChain()
public boolean isClosed()
{
return isChain(this);
return this.getNodeSteps().get(0).equals(this.getNodeSteps().get(this.getNodeSteps().size() - 1));
}
protected static <N, E extends Cloud<N>> boolean isChain(final Path<N, E> path)
@Override
public int getLength()
{
final Set<N> uniqueNodes = new HashSet<N>(path.getNodeSteps());
final Set<E> uniqueEdges = new HashSet<E>(path.getSteps());
if( uniqueNodes.size() < path.getNodeSteps().size() )
return false;
return !(uniqueEdges.size() < path.getSteps().size());
return this.getSteps().size();
}
@Override
public boolean isIndependent(final Path<N, E> path)
public boolean isTrail()
{
return AbstractPath.isIndependentUtility(this, path);
final Set<E> edgeSet = new HashSet<E>(this.getSteps());
return edgeSet.size() >= this.getSteps().size();
}
static <N, E extends Cloud<N>> boolean isIndependentUtility(final Path<N, E> firstPath, final Path<N, E> secondPath)
@Override
public boolean isTour()
{
if( !firstPath.getFirstNode().equals(secondPath.getFirstNode()) )
return false;
if( !firstPath.getLastNode().equals(secondPath.getLastNode()) )
return false;
final List<N> exclusiveFirstNodes = new ArrayList<N>(firstPath.getNodeSteps());
exclusiveFirstNodes.remove(exclusiveFirstNodes.size() - 1);
exclusiveFirstNodes.remove(0);
final List<N> secondNodes = new ArrayList<N>(secondPath.getNodeSteps());
secondNodes.remove(secondNodes.size() - 1);
secondNodes.remove(0);
exclusiveFirstNodes.removeAll(secondNodes);
return !(exclusiveFirstNodes.size() < firstPath.getNodeSteps().size());
return (this.isTrail()) && (this.isClosed());
}
@Override
public boolean isCycle()
{
return false;
return this.getNodeSteps().get(0).equals(this.getNodeSteps().get(this.getNodeSteps().size() - 1));
}
static int hashCodeUtility(final Path path)
@Override
public boolean hasChildCycles()
{
return (path.getNodeSteps().hashCode() + path.getSteps().hashCode()) * path.getSteps().hashCode();
final CloudGraph<N, E> graph = new ImmutableAdjacencyGraph<N, E>(new HashSet<N>(this.getNodeSteps()), new HashSet<E>(this.getSteps()));
final CycleFinder<N, E> finder = new ExhaustiveDepthFirstSearchCycleFinder<N, E>();
if( this.isCycle() )
if( finder.cycleCount(graph) > 1 )
return true;
else if( finder.hasCycle(graph) )
return true;
return false;
}
static boolean equalsUtility(final Path path, final Object object)
protected double calculateWeight(final double defaultWeight)
{
if( (path == null) || (object == null) )
return false;
final Path secondPath = (Path) object;
if( !(secondPath.getNodeSteps().equals(path.getNodeSteps())) )
return false;
return secondPath.getSteps().equals(path.getSteps());
double newTotalWeight = 0.0;
for(final E step : this.getSteps())
{
if( step instanceof Weighted )
newTotalWeight += ((Weighted) step).getWeight();
else
newTotalWeight += defaultWeight;
}
for(final N step : this.getNodeSteps())
{
if( step instanceof Weighted )
newTotalWeight += ((Weighted) step).getWeight();
else
newTotalWeight += defaultWeight;
}
return newTotalWeight;
}
@Override
public int hashCode()
{
return AbstractPath.hashCodeUtility(this);
final Set<N> uniqueNodes = new HashSet<N>(this.getNodeSteps());
final Set<E> uniqueEdges = new HashSet<E>(this.getSteps());
return (uniqueNodes.hashCode() + uniqueEdges.hashCode()) * uniqueEdges.hashCode();
}
@Override
@SuppressWarnings("unchecked")
public boolean equals(final Object object)
{
if( object == null )
return false;
if( !(object instanceof Path) )
if( object.getClass() != this.getClass() )
return false;
final Path path = (Path) object;
final Set uniqueNodes = new HashSet<N>(this.getNodeSteps());
final Set uniqueEdges = new HashSet<E>(this.getSteps());
final Set otherUniqueNodes = new HashSet(path.getNodeSteps());
final Set otherUniqueEdges = new HashSet(path.getSteps());
if( !(uniqueNodes.equals(otherUniqueNodes)) )
return false;
return uniqueEdges.equals(otherUniqueEdges);
}
return AbstractPath.equalsUtility(this, object);
@Override
public String toString()
{
return this.getSteps().toString();
}
}
......@@ -21,42 +21,59 @@ package com.syncleus.dann.graph;
import java.util.*;
public abstract class AbstractTraversableCloud<
T,
EP extends TraversableCloud.Endpoint<T,? extends T>
> extends AbstractCloud<T, EP> implements TraversableCloud<T,EP>
E extends TraversableCloud.Endpoint<?>
> extends AbstractCloud<E> implements TraversableCloud<E>
{
@Override
public Set<T> getTraversableFrom(Object source)
public Set<E> getTraversableFrom(TraversableCloud.Endpoint<?> source)
{
final Set<T> nodes = new HashSet<T>();
for( final EP sourceEndpoint : this.getEndpoints(source) )
for( final TraversableCloud.Endpoint<T,? extends T> fromEndpoint : sourceEndpoint.getTraversableNeighborsFrom())
nodes.add(fromEndpoint.getTarget());
final Set<E> traversableEndpoints = new HashSet<E>();
for( final E toEndpoint : getNeighbors(source))
if( this.isTraversable(source, toEndpoint) )
traversableEndpoints.add(toEndpoint);
return Collections.unmodifiableSet(nodes);
return Collections.unmodifiableSet(traversableEndpoints);
}
@Override
public Set<T> getTraversableTo(Object destination)
public Set<E> getTraversableTo(TraversableCloud.Endpoint<?> destination)
{
final Set<T> nodes = new HashSet<T>();
for( final EP destinationEndpoint : this.getEndpoints(destination) )
for( final TraversableCloud.Endpoint<T,? extends T> fromEndpoint : destinationEndpoint.getTraversableNeighborsTo())
nodes.add(fromEndpoint.getTarget());
final Set<E> traversableEndpoints = new HashSet<E>();
for( final E fromEndpoint : getNeighbors(destination) )
if( this.isTraversable(fromEndpoint, destination))
traversableEndpoints.add(fromEndpoint);
return Collections.unmodifiableSet(nodes);
return Collections.unmodifiableSet(traversableEndpoints);
}
protected abstract class AbstractEndpoint<P,T> extends AbstractEndpoint<P,T> implements TraversableCloud.Endpoint<P,T>
@Override
public boolean isTraversableFrom(TraversableCloud.Endpoint<?> source)
{
return !this.getTraversableFrom(source).isEmpty();
}
@Override
public boolean isTraversableTo(TraversableCloud.Endpoint<?> destination)
{
return !this.getTraversableTo(destination).isEmpty();
}
protected abstract class AbstractEndpoint<T> extends AbstractCloud<E>.AbstractEndpoint<T> implements TraversableCloud.Endpoint<T>
{
protected AbstractEndpoint()
{
super();
}
/*
@Override
public Set<TraversableCloud.Endpoint<P,P>> getTraversableNeighborsTo()
public Set<TraversableCloud.Endpoint<T>> TraversableNeighborsTo()
{
final Set<TraversableCloud.Endpoint<P,P>> traversables = new HashSet<TraversableCloud.Endpoint<P,P>>();
for(EP neighbor : AbstractTraversableCloud.this.getEndpoints())
for(E neighbor : AbstractTraversableCloud.this.getEndpoints())
if( AbstractTraversableCloud.this.isTraversable(this.getTarget(),neighbor.getTarget()) )
traversables.add(neighbor);
return Collections.unmodifiableSet(traversables);
return null;
}
@Override
......@@ -80,5 +97,30 @@ public abstract class AbstractTraversableCloud<
{
return AbstractCloud.this.isTraversable(this.getTarget(), destination.getTarget());
}
*/
@Override
public boolean isTraversableFrom(TraversableCloud.Endpoint<?> target)
{
return isTraversable(target, this);
}
@Override
public boolean isTraversableTo(TraversableCloud.Endpoint<?> target)
{
return isTraversable(this, target);
}
@Override
public boolean isTraversableFrom()
{
return isTraversableFrom(this);
}
@Override
public boolean isTraversableTo()
{
return isTraversableTo(this);
}
}
}
/******************************************************************************
* *
* Copyright: (c) Syncleus, Inc. *
* *
* You may redistribute and modify this source code under the terms and *
* conditions of the Open Source Community License - Type C version 1.0 *
* or any later version as published by Syncleus, Inc. at www.syncleus.com. *
* There should be a copy of the license included with this file. If a copy *
* of the license is not included you are granted no right to distribute or *
* otherwise use this file except through a legal and valid license. You *
* should also contact Syncleus, Inc. at the information below if you cannot *
* find a license: *
* *
* Syncleus, Inc. *
* 2604 South 12th Street *
* Philadelphia, PA 19148 *
* *
******************************************************************************/
package com.syncleus.dann.graph;
import java.util.HashSet;
import java.util.Set;
import com.syncleus.dann.graph.search.pathfinding.*;
public abstract class AbstractTraversableCloudGraph<
NE extends TraversableCloudGraph.NodeEndpoint<?>,
EE extends TraversableCloudGraph.EdgeEndpoint<? extends Cloud<?>>
> extends AbstractCloudGraph<NE,EE> implements TraversableCloudGraph<NE, EE>
{
private final CloudTraverser<? super Cloud<?>> traverser;
protected AbstractTraversableCloudGraph()
{
this.traverser = null;
}
protected AbstractTraversableCloudGraph(final CloudTraverser<? super Cloud<?>> traverser)
{
this.traverser = traverser;
}
public CloudTraverser<? super Cloud<?>> getCloudTraverser()
{
return this.traverser;
}
@Override
public CloudGraph.Endpoints<NE, EE> getGraphTraversableFrom(Cloud.Endpoint<?> source)
{
if( !this.contains(source) )
throw new IllegalArgumentException("target does not belong to this graph as a node");
this.getAdjacent(source);
final WalkFinder<?> pathFinder = this.getWalkFinder();
final Set<NE> traversables = new HashSet<NE>();
for(N neighbor : this.getNodes())
if( this.isTraversable(source,neighbor,pathFinder) )
traversables.add(neighbor);
return Collections.unmodifiableSet(traversables);
}
@Override
public CloudGraph.Endpoints<NE, EE> getGraphTraversableTo(Cloud.Endpoint<?> destination)
{
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public CloudGraph.Endpoints<NE, EE> getTraversableAdjacentTo(Cloud.Endpoint<?> destination)
{
if( !this.contains(destination) )
throw new IllegalArgumentException("target does not belong to this graph as a node");
CloudGraph.Endpoints<NE,EE> adjacentEndpoints = this.getAdjacent(destination);
Set<EE> traversableAdjacentEdges = new HashSet<EE>();
for( EE adjacentEdgeEndpoint : adjacentEndpoints.getEdgeEndpoints() )
{
traversableAdjacentEdges.add(adjacentEdgeEndpoint);
}
final Set<NE> traversables = new HashSet<NE>();
for(N neighbor : this.getNodes())
if( this.isTraversable(source,neighbor,pathFinder) )
traversables.add(neighbor);
return Collections.unmodifiableSet(traversables);
}
@Override
public CloudGraph.Endpoints<NE, EE> getTraversableAdjacentFrom(Cloud.Endpoint<?> destination)
{
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public Set<NE> getTraversableFrom(Cloud.Endpoint<?> source)
{
return this.getGraphTraversableFrom(source).getNodeEndpoints();
}
@Override
public Set<NE> getTraversableTo(Cloud.Endpoint<?> destination)
{
return this.getGraphTraversableTo(destination).getNodeEndpoints();
}
@Override
public boolean isTraversable(Cloud.Endpoint<?> sourceTarget, Cloud.Endpoint<?> destinationTarget)
{
if(this.getCloudTraverser() != null)
if(this.getCloudTraverser().isTraversable(this,sourceTarget,destinationTarget))
return true;
else
return false
else
if()
}
@Override
public boolean isTraversableFrom(Cloud.Endpoint<?> source)
{
return false; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean isTraversableTo(Cloud.Endpoint<?> destination)
{
return false; //To change body of implemented methods use File | Settings | File Templates.
}
protected abstract class AbstractNodeEndpoint<T> extends AbstractCloudGraph<NE,EE>.AbstractNodeEndpoint<T> implements TraversableCloudGraph.NodeEndpoint<T>
{
protected AbstractNodeEndpoint()
{
}
protected AbstractNodeEndpoint(T target)
{
super(target);
}
};
protected abstract class AbstractEdgeEndpoint<T extends Cloud<?>> extends AbstractCloudGraph<NE,EE>.AbstractEdgeEndpoint<T> implements TraversableCloudGraph.EdgeEndpoint<T>
{
protected AbstractEdgeEndpoint()
{
}
protected AbstractEdgeEndpoint(T target)
{
super(target);
}
};
}
......@@ -18,72 +18,18 @@
******************************************************************************/
package com.syncleus.dann.graph;
import java.util.*;
public abstract class AbstractUndirectedEdge<N, LN extends N, RN extends N> extends AbstractBidirectedEdge<N, LN,RN> implements MixableBidirectedEdge<N, LN,RN>
public abstract class AbstractUndirectedEdge<E extends BidirectedEdge.Endpoint<?>> extends AbstractMixableUndirectedEdge<E,E,E> implements BidirectedEdge<E>
{
private static final long serialVersionUID = 83475809132709850L;
protected AbstractUndirectedEdge(final LN leftNode, final RN rightNode)
{
super(leftNode, EndState.NONE, rightNode, EndState.NONE);
}
protected AbstractUndirectedEdge(final LN leftNode, final RN rightNode, final boolean allowJoiningMultipleGraphs, final boolean contextEnabled)
{
super(leftNode, EndState.NONE, rightNode, EndState.NONE, allowJoiningMultipleGraphs, contextEnabled);
}
@Override
public List<N> getTraversableNodes(final N node)
{
if( this.getLeftNode().equals(node) )
return Collections.singletonList(this.getRightNode());
else if( this.getRightNode().equals(node) )
return Collections.singletonList(this.getLeftNode());
else
throw new IllegalArgumentException("node is not one of the end points!");
}
@Override
public final boolean isIntroverted()
{
return false;
}
@Override
public final boolean isExtroverted()
{
return false;
}
@Override
public final boolean isDirected()
{
return false;
}
@Override
public final boolean isHalfEdge()
{
return false;
}
@Override
public final boolean isLooseEdge()
{
return true;
}
@Override
public final boolean isOrdinaryEdge()
{
return false;
}
@Override
protected AbstractUndirectedEdge<N, LN,RN> clone()
{
return (AbstractUndirectedEdge<N, LN,RN>) super.clone();
}
protected abstract class AbstractEndpoint<T> extends AbstractMixableUndirectedEdge<E,E,E>.AbstractEndpoint<T> implements BidirectedEdge.Endpoint<T>
{
protected AbstractEndpoint(Direction direction)
{
super(direction);
}
protected AbstractEndpoint(T target, Direction direction)
{
super(target, direction);
}
};
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment