diff --git a/src/main/java/com/syncleus/dann/graph/AbstractHyperedge.java b/src/main/java/com/syncleus/dann/graph/AbstractHyperedge.java index 2920dcd1badfa95a9db6277e1a53b7b815ebb91b..813e3ea9919bbfa9fbe44a0ea85c80be71913dd4 100644 --- a/src/main/java/com/syncleus/dann/graph/AbstractHyperedge.java +++ b/src/main/java/com/syncleus/dann/graph/AbstractHyperedge.java @@ -111,8 +111,8 @@ public abstract class AbstractHyperedge<E extends Hyperedge.Endpoint<?>> extends } */ // TODO : Implement This! - @Override - public boolean isSymmetric(final Hyperedge symmetricEdge) + @Override + public boolean isSymmetric(Hyperedge<? extends E> symmetricEdge) { throw new UnsupportedOperationException("this operation is not yet supported"); } diff --git a/src/main/java/com/syncleus/dann/graph/AbstractHypergraph.java b/src/main/java/com/syncleus/dann/graph/AbstractHypergraph.java index 4710079ea506c55597d5f1f7b7a4466158b6b450..6d471041150ca237f205614ebd8805ba066c6034 100644 --- a/src/main/java/com/syncleus/dann/graph/AbstractHypergraph.java +++ b/src/main/java/com/syncleus/dann/graph/AbstractHypergraph.java @@ -20,22 +20,10 @@ package com.syncleus.dann.graph; import java.util.Set; -public abstract class AbstractHypergraph<N, E extends Hyperedge<N>> extends AbstractCloudGraph<N, E> implements Hypergraph<N, E> +public abstract class AbstractHypergraph< + NE extends Hypergraph.NodeEndpoint<?>, + EE extends Hypergraph.EdgeEndpoint<? extends Cloud<?>>> extends AbstractCloudGraph<NE,EE> implements Hypergraph<NE,EE> { - protected AbstractHypergraph() - { - super(); - } - - protected AbstractHypergraph(final CloudGraph<N, E> copyGraph) - { - super(copyGraph.getTargets(), copyGraph.getEdges()); - } - - protected AbstractHypergraph(final Set<N> nodes, final Set<E> edges) - { - super(nodes, edges); - } /** * This will always return false. @@ -81,8 +69,8 @@ public abstract class AbstractHypergraph<N, E extends Hyperedge<N>> extends Abst } @Override - protected AbstractHypergraph<N, E> clone() + protected AbstractHypergraph<NE, EE> clone() { - return (AbstractHypergraph<N, E>) super.clone(); + return (AbstractHypergraph<NE, EE>) super.clone(); } } diff --git a/src/main/java/com/syncleus/dann/graph/AbstractMutableAdjacencyGraph.java b/src/main/java/com/syncleus/dann/graph/AbstractMutableAdjacencyGraph.java index 42baabf2409fec8300fac07d2c9460571ab9275e..0dd21a34eb47852373bc5e0da9ee6e03ecaf8e5f 100644 --- a/src/main/java/com/syncleus/dann/graph/AbstractMutableAdjacencyGraph.java +++ b/src/main/java/com/syncleus/dann/graph/AbstractMutableAdjacencyGraph.java @@ -24,21 +24,21 @@ import com.syncleus.dann.graph.adjacency.HashAdjacencyMapping; public abstract class AbstractMutableAdjacencyGraph< N, - E extends Cloud<N,? extends Cloud.Endpoint<N>>, - NE extends MutableCloudGraph.NodeEndpoint<N, E>, - EE extends MutableCloudGraph.EdgeEndpoint<N, E> + NE extends MutableCloudGraph.NodeEndpoint<N>, + E extends Cloud<? extends Cloud.Endpoint<? extends N>>, + EE extends MutableCloudGraph.EdgeEndpoint<E> > - extends AbstractCloudGraph<N, E, NE, EE> - implements MutableCloudGraph<N, E, NE, EE> + extends AbstractCloudGraph<NE, EE> + implements MutableCloudGraph<N, NE, E, EE> { private static final long serialVersionUID = -4613327727609060678L; - private final AdjacencyMapping<MutableCloudGraph.NodeEndpoint<N, E>,MutableCloudGraph.EdgeEndpoint<N, E>,Endpoint<N>> adjacency = new HashAdjacencyMapping<MutableCloudGraph.NodeEndpoint<N, E>,MutableCloudGraph.EdgeEndpoint<N, E>,Endpoint<N>>(); + private final AdjacencyMapping<NE,EE,Cloud.Endpoint<? extends N>> adjacency = new HashAdjacencyMapping<NE,EE,Cloud.Endpoint<? extends N>>(); protected AbstractMutableAdjacencyGraph() { } - protected void internalJoinNode(final MutableCloudGraph.NodeEndpoint<N, E> endpoint) throws InvalidGraphException + protected void internalJoin(final NE endpoint) throws InvalidGraphException { if(endpoint == null) throw new IllegalArgumentException(("endpoint can not be null")); @@ -48,7 +48,7 @@ public abstract class AbstractMutableAdjacencyGraph< this.adjacency.putLeftKey(endpoint); } - protected void internalLeaveNode(MutableCloudGraph.NodeEndpoint<?, ?> endpoint) throws InvalidGraphException + protected void internalLeave(Cloud.Endpoint<?> endpoint) throws InvalidGraphException { if(endpoint == null) throw new IllegalArgumentException(("endpoint can not be null")); @@ -60,25 +60,26 @@ public abstract class AbstractMutableAdjacencyGraph< this.adjacency.removeLeftKey(endpoint); } - protected void internalJoinEdge(final MutableCloudGraph.EdgeEndpoint<N, E> endpoint) throws InvalidGraphException + protected void internalJoinEdge(final EE endpoint) throws InvalidGraphException { if(endpoint == null) throw new IllegalArgumentException(("endpoint can not be null")); //make sure all of the edge's node already belong to this graph - else if( !this.containsAllTargets(endpoint.getTarget().getTargets()) ) - throw new InvalidGraphException("All of the edge's targets must already exist in this graph"); + for(Endpoint<? extends N> targetEndpoint : endpoint.getTarget().getEndpoints()) + if( !this.containsTarget(targetEndpoint.getTarget()) ) + throw new InvalidGraphException("All of the edge's targets must already exist in this graph"); //we cant do anything if the endpoint already exists in the key, they are unique representations of //a single membership to the graph - else if(this.contains(endpoint)) + if(this.contains(endpoint)) throw new IllegalArgumentException("endpoint is already a member of this graph!"); - for( final Cloud.Endpoint<N> targetEndpoint : endpoint.getTarget().getEndpoints() ) - for( final NE nodeEndpoint : this.getNodeEndpoints(targetEndpoint.getTarget())) + for( final Cloud.Endpoint<? extends N> targetEndpoint : endpoint.getTarget().getEndpoints() ) + for( final NE nodeEndpoint : this.getEndpoints(targetEndpoint.getTarget())) this.adjacency.put(nodeEndpoint,endpoint,targetEndpoint); } - protected void internalLeaveEdge(MutableCloudGraph.EdgeEndpoint<?, ?> endpoint) throws InvalidGraphException + protected void internalLeaveEdge(Cloud.Endpoint<?> endpoint) throws InvalidGraphException { if(endpoint == null) throw new IllegalArgumentException(("endpoint can not be null")); @@ -89,82 +90,82 @@ public abstract class AbstractMutableAdjacencyGraph< } @Override - protected Set<CloudGraph.EdgeEndpoint<N,E>> getAdjacentEdgeEndpoints(CloudGraph.NodeEndpoint<?, ?> nodeEndpoint) + protected Set<EE> getAdjacentEdgeEndpoints(Cloud.Endpoint<?> nodeEndpoint) { if( !this.adjacency.getLeftKeys().contains(nodeEndpoint) ) throw new IllegalArgumentException("nodeEndpoint is not an endpoint for this graph"); - return Collections.<EdgeEndpoint<N,E>>unmodifiableSet(this.adjacency.getLeftAdjacency(nodeEndpoint)); + return Collections.<EE>unmodifiableSet(this.adjacency.getLeftAdjacency(nodeEndpoint)); } @Override - public void leaveNode(MutableCloudGraph.NodeEndpoint<?, ?> endpoint) throws InvalidGraphException + public void leave(Cloud.Endpoint<?> endpoint) throws InvalidGraphException { - this.internalLeaveNode(endpoint); + this.internalLeave(endpoint); } @Override - public void leaveEdge(MutableCloudGraph.EdgeEndpoint<?, ?> endpoint) throws InvalidGraphException + public void leaveEdge(Cloud.Endpoint<?> endpoint) throws InvalidGraphException { this.internalLeaveEdge(endpoint); } @Override - public Map<N, NE> joinNodes(Set<? extends N> nodes) throws InvalidGraphException + public Set<NE> joins(Set<? extends N> nodes) throws InvalidGraphException { - final Map<N, NE> endpoints = new HashMap<N,NE>(); + final Set<NE> endpoints = new HashSet<NE>(); for(N node : nodes) - endpoints.put(node, this.joinNode(node)); - return Collections.unmodifiableMap(endpoints); + endpoints.add(this.join(node)); + return Collections.unmodifiableSet(endpoints); } @Override - public Map<N, Set<NE>> joinNodes(Map<? extends N, ? extends Integer> nodes) throws InvalidGraphException + public Set<NE> joins(Map<? extends N, ? extends Integer> nodes) throws InvalidGraphException { - final Map<N,Set<NE>> joinMapping = new HashMap<N, Set<NE>>(nodes.size()); + final Set<NE> joinSet = new HashSet<NE>(nodes.size()); for(final Map.Entry<? extends N,? extends Integer> nodeEntry : nodes.entrySet()) { final Set<NE> newEndpoints = new HashSet<NE>(nodeEntry.getValue()); for(int count = 0; count < nodeEntry.getValue(); count++) - newEndpoints.add(this.joinNode(nodeEntry.getKey())); - joinMapping.put(nodeEntry.getKey(),newEndpoints); + newEndpoints.add(this.join(nodeEntry.getKey())); + joinSet.addAll(newEndpoints); } - return Collections.unmodifiableMap(joinMapping); + return Collections.unmodifiableSet(joinSet); } @Override - public void leaveNodes(Set<? extends MutableCloudGraph.NodeEndpoint<?, ?>> nodeEndpoints) throws InvalidGraphException + public void leave(Set<? extends Cloud.Endpoint<?>> nodeEndpoints) throws InvalidGraphException { - for(MutableCloudGraph.NodeEndpoint<?, ? extends Cloud<?,? extends Endpoint<?>>> node : nodeEndpoints) - this.leaveNode(node); + for(Cloud.Endpoint<?> node : nodeEndpoints) + this.leave(node); } @Override - public Map<E, EE> joinEdges(Set<? extends E> edges) throws InvalidGraphException + public Set<EE> joinEdges(Set<? extends E> edges) throws InvalidGraphException { - final Map<E, EE> endpoints = new HashMap<E,EE>(); + final Set<EE> endpoints = new HashSet<EE>(); for(E edge : edges) - endpoints.put(edge, this.joinEdge(edge)); - return Collections.unmodifiableMap(endpoints); + endpoints.add(this.joinEdge(edge)); + return Collections.unmodifiableSet(endpoints); } @Override - public Map<E, Set<EE>> joinEdges(Map<? extends E, ? extends Integer> edges) throws InvalidGraphException + public Set<EE> joinEdges(Map<? extends E, ? extends Integer> edges) throws InvalidGraphException { - final Map<E,Set<EE>> joinMapping = new HashMap<E, Set<EE>>(edges.size()); + final Set<EE> joinSet = new HashSet<EE>(edges.size()); for(final Map.Entry<? extends E,? extends Integer> edgeEntry : edges.entrySet()) { final Set<EE> newEndpoints = new HashSet<EE>(edgeEntry.getValue()); for(int count = 0; count < edgeEntry.getValue(); count++) newEndpoints.add(this.joinEdge(edgeEntry.getKey())); - joinMapping.put(edgeEntry.getKey(),newEndpoints); + joinSet.addAll(newEndpoints); } - return Collections.unmodifiableMap(joinMapping); + return Collections.unmodifiableSet(joinSet); } @Override - public void leaveEdges(Set<? extends MutableCloudGraph.EdgeEndpoint<?, ?>> edgeEndpoints) throws InvalidGraphException + public void leaveEdges(Set<? extends Cloud.Endpoint<?>> edgeEndpoints) throws InvalidGraphException { - for(final MutableCloudGraph.EdgeEndpoint<?, ? extends Cloud<?,? extends Endpoint<?>>> edgeEndpoint : edgeEndpoints) + for(final Cloud.Endpoint<?> edgeEndpoint : edgeEndpoints) this.leaveEdge(edgeEndpoint); } @@ -181,20 +182,45 @@ public abstract class AbstractMutableAdjacencyGraph< } @Override - public Map<?, CloudGraph.Endpoint<?, N, E>> reconfigure(Set<? extends N> addNodes, Set<? extends E> addEdges, Set<? extends CloudGraph.Endpoint<?, ?, ?>> disconnectEndpoints) throws InvalidGraphException + public CloudGraph.Endpoints<NE,EE> reconfigure(Set<? extends N> addNodes, Set<? extends E> addEdges, Set<? extends Cloud.Endpoint<?>> disconnectEndpoints) throws InvalidGraphException { if( disconnectEndpoints != null ) { - for(final CloudGraph.Endpoint<?, ?,?> disconnectEndpoint : disconnectEndpoints) + for(final Cloud.Endpoint<?> disconnectEndpoint : disconnectEndpoints) this.adjacency.remove(disconnectEndpoint.getTarget()); } - Map<Object, CloudGraph.Endpoint<?, N,E>> newEndpoints = new HashMap<Object, CloudGraph.Endpoint<?, N, E>>(); + //Map<Object, CloudGraph.Endpoint<?, N,E>> newEndpoints = new HashMap<Object, CloudGraph.Endpoint<?, N, E>>(); + Set<NE> newNodeEndpoints = new HashSet<NE>(); if( addNodes != null ) - newEndpoints.putAll(this.joinNodes(addNodes)); + newNodeEndpoints.addAll(this.joins(addNodes)); + + Set<EE> newEdgeEndpoints = new HashSet<EE>(); + if( addEdges != null ) + newEdgeEndpoints.addAll(this.joinEdges(addEdges)); + + return new Endpoints(Collections.unmodifiableSet(newNodeEndpoints), Collections.unmodifiableSet(newEdgeEndpoints) ); + } + + @Override + public CloudGraph.Endpoints<NE,EE> reconfigure(Map<? extends N,? extends Integer> addNodes, Map<? extends E,? extends Integer> addEdges, Set<? extends Cloud.Endpoint<?>> disconnectEndpoints) throws InvalidGraphException + { + if( disconnectEndpoints != null ) + { + for(final Cloud.Endpoint<?> disconnectEndpoint : disconnectEndpoints) + this.adjacency.remove(disconnectEndpoint.getTarget()); + } + + //Map<Object, CloudGraph.Endpoint<?, N,E>> newEndpoints = new HashMap<Object, CloudGraph.Endpoint<?, N, E>>(); + Set<NE> newNodeEndpoints = new HashSet<NE>(); + if( addNodes != null ) + newNodeEndpoints.addAll(this.joins(addNodes)); + + Set<EE> newEdgeEndpoints = new HashSet<EE>(); if( addEdges != null ) - newEndpoints.putAll(this.joinEdges(addEdges)); - return newEndpoints; + newEdgeEndpoints.addAll(this.joinEdges(addEdges)); + + return new Endpoints(Collections.unmodifiableSet(newNodeEndpoints), Collections.unmodifiableSet(newEdgeEndpoints) ); } @Override @@ -204,7 +230,7 @@ public abstract class AbstractMutableAdjacencyGraph< } @Override - public Set<NE> getNodeEndpoints() + public Set<NE> getEndpoints() { return Collections.unmodifiableSet(this.adjacency.getLeftKeys()); } @@ -216,7 +242,7 @@ public abstract class AbstractMutableAdjacencyGraph< } - protected abstract class AbstractNodeEndpoint extends AbstractCloudGraph<N,E,NE,EE>.AbstractNodeEndpoint implements MutableCloudGraph.NodeEndpoint<N, E> + protected abstract class AbstractNodeEndpoint extends AbstractCloudGraph<NE,EE>.AbstractNodeEndpoint implements MutableCloudGraph.NodeEndpoint<N> { private N target; @@ -234,9 +260,9 @@ public abstract class AbstractMutableAdjacencyGraph< return; } - internalLeaveNode(this); + internalLeave(this); this.target = newTarget; - internalJoinNode(this); + internalJoin(this); } @Override @@ -246,7 +272,7 @@ public abstract class AbstractMutableAdjacencyGraph< } }; - protected abstract class AbstractEdgeEndpoint extends AbstractCloudGraph<N,E,NE,EE>.AbstractEdgeEndpoint implements MutableCloudGraph.EdgeEndpoint<N, E> + protected abstract class AbstractEdgeEndpoint extends AbstractCloudGraph<NE,EE>.AbstractEdgeEndpoint implements MutableCloudGraph.EdgeEndpoint<E> { private E target; diff --git a/src/main/java/com/syncleus/dann/graph/AbstractTraversableCloud.java b/src/main/java/com/syncleus/dann/graph/AbstractTraversableCloud.java index 1160f01fdbcb15f7b4a17a434d131d260e66a3ab..b5942318e05d6ec23ce985efd641718163b60f6e 100644 --- a/src/main/java/com/syncleus/dann/graph/AbstractTraversableCloud.java +++ b/src/main/java/com/syncleus/dann/graph/AbstractTraversableCloud.java @@ -25,7 +25,7 @@ public abstract class AbstractTraversableCloud< > extends AbstractCloud<E> implements TraversableCloud<E> { @Override - public Set<E> getTraversableFrom(TraversableCloud.Endpoint<?> source) + public Set<E> getTraversableFrom(Cloud.Endpoint<?> source) { final Set<E> traversableEndpoints = new HashSet<E>(); for( final E toEndpoint : getNeighbors(source)) @@ -36,7 +36,7 @@ public abstract class AbstractTraversableCloud< } @Override - public Set<E> getTraversableTo(TraversableCloud.Endpoint<?> destination) + public Set<E> getTraversableTo(Cloud.Endpoint<?> destination) { final Set<E> traversableEndpoints = new HashSet<E>(); for( final E fromEndpoint : getNeighbors(destination) ) @@ -47,13 +47,13 @@ public abstract class AbstractTraversableCloud< } @Override - public boolean isTraversableFrom(TraversableCloud.Endpoint<?> source) + public boolean isTraversableFrom(Cloud.Endpoint<?> source) { return !this.getTraversableFrom(source).isEmpty(); } @Override - public boolean isTraversableTo(TraversableCloud.Endpoint<?> destination) + public boolean isTraversableTo(Cloud.Endpoint<?> destination) { return !this.getTraversableTo(destination).isEmpty(); } @@ -100,13 +100,13 @@ public abstract class AbstractTraversableCloud< */ @Override - public boolean isTraversableFrom(TraversableCloud.Endpoint<?> target) + public boolean isTraversableFrom(Cloud.Endpoint<?> target) { return isTraversable(target, this); } @Override - public boolean isTraversableTo(TraversableCloud.Endpoint<?> target) + public boolean isTraversableTo(Cloud.Endpoint<?> target) { return isTraversable(this, target); }