package automenta.netention.graph; /** BidirectedGraph that can be edited dynamically: adding and removing both nodes and edges. Contains code adapted from JUNG2's DirectedSparseMultigraph and its ancestry. */ public class SimpleDynamicDirectedGraph<N, E> /*extends AbstractBidirectedGraph<N, ValueDirectedEdge<N,E>> implements Serializable*/ { // //Original dANN fields: // // final private HashSet<N> nodes; // // final private HashSet<E> edges; // // final private Map<N, Set<E>> neighborEdges = new HashMap<N, Set<E>>(); // // final private Map<N, List<N>> neighborNodes = new HashMap<N, List<N>>(); // // //JUNG2's DirectedSparseMultigraph fields, for comparison: // protected final Map<N, Pair<Set<ValueDirectedEdge<N,E>>>> vertices; // Map of vertices to Pair of adjacency sets {incoming, outgoing} // //protected Map<E, Pair<N>> edges; // Map of edges to incident vertex pairs // protected final Set<ValueDirectedEdge<N,E>> edges; // // // public SimpleDynamicDirectedGraph() { // super(); // vertices = new HashMap(); // edges = new HashSet(); // } // // public SimpleDynamicDirectedGraph(SimpleDynamicDirectedGraph<N, E> copyFrom) { // super(); // this.vertices = new HashMap(copyFrom.vertices); // this.edges = new HashSet(copyFrom.edges); // } // // public synchronized void clear() { // vertices.clear(); // edges.clear(); // } // // public boolean addNode(N vertex) { // if (vertex == null) { // throw new IllegalArgumentException("vertex may not be null"); // } // if (!containsVertex(vertex)) { // vertices.put(vertex, new Pair<Set<ValueDirectedEdge<N,E>>>(new HashSet<ValueDirectedEdge<N,E>>(), new HashSet<ValueDirectedEdge<N,E>>())); // return true; // } else { // return false; // } // } // // public boolean removeVertex(N vertex) { // if (!containsVertex(vertex)) { // return false; // } // // // copy to avoid concurrent modification in removeEdge // Set<ValueDirectedEdge<N,E>> incident = new HashSet<ValueDirectedEdge<N,E>>(getIncoming_internal(vertex)); // incident.addAll(getOutgoing_internal(vertex)); // // for (ValueDirectedEdge<N,E> edge : incident) { // removeEdge(edge); // } // // vertices.remove(vertex); // // return true; // } // // // public ValueDirectedEdge<N,E> addEdge(E edgeValue, N source, N dest) { // ValueDirectedEdge<N,E> edge = new ValueDirectedEdge(edgeValue, source, dest); // final Pair<N> endpoints = new Pair<N>(edge.getSourceNode(), edge.getDestinationNode()); // final Pair<N> new_endpoints = getValidatedEndpoints(edge, endpoints); // if (new_endpoints == null) { // return null; // } // // edges.add(edge); // // if (!containsVertex(source)) { // this.addNode(source); // } // // if (!containsVertex(dest)) { // this.addNode(dest); // } // // getIncoming_internal(dest).add(edge); // getOutgoing_internal(source).add(edge); // // return edge; // } // // public boolean removeEdge(ValueDirectedEdge<N,E> edge) { // if (!containsEdge(edge)) { // return false; // } // // Pair<N> endpoints = this.getEndpoints(edge); // N source = endpoints.getFirst(); // N dest = endpoints.getSecond(); // // // remove edge from incident vertices' adjacency sets // getOutgoing_internal(source).remove(edge); // getIncoming_internal(dest).remove(edge); // // edges.remove(edge); // return true; // } // // public boolean containsVertex(N vertex) { // return vertices.keySet().contains(vertex); // } // // public boolean containsEdge(ValueDirectedEdge<N,E> edge) { // return edges.contains(edge); // } // // // protected Pair<N> getValidatedEndpoints(ValueDirectedEdge<N,E> edge, Pair<? extends N> endpoints) // { // if (edge == null) // throw new IllegalArgumentException("input edge may not be null"); // // if (endpoints == null) // throw new IllegalArgumentException("endpoints may not be null"); // // Pair<N> new_endpoints = new Pair<N>(endpoints.getFirst(), endpoints.getSecond()); // if (containsEdge(edge)) // { // Pair<N> existing_endpoints = getEndpoints(edge); // if (!existing_endpoints.equals(new_endpoints)) { // throw new IllegalArgumentException("edge " + edge + // " already exists in this graph with endpoints " + existing_endpoints + // " and cannot be added with endpoints " + endpoints); // } else { // return null; // } // } // return new_endpoints; // } // // public Pair<N> getEndpoints(ValueDirectedEdge<N,E> edge) { // if (edges.contains(edge)) { // return new Pair(edge.getSourceNode(), edge.getDestinationNode()); // } // return null; // } // // protected Set<ValueDirectedEdge<N,E>> getIncoming_internal(N vertex) // { // return vertices.get(vertex).getFirst(); // } // // protected Collection<ValueDirectedEdge<N,E>> getOutgoing_internal(N vertex) // { // return vertices.get(vertex).getSecond(); // } // // public Set<N> getNodes() { // return Collections.unmodifiableSet(this.vertices.keySet()); // } // // @Override // public Set<ValueDirectedEdge<N,E>> getEdges() { // return Collections.unmodifiableSet(this.edges); // } // // public Set<ValueDirectedEdge<N,E>> getAdjacentEdges(N node) { // //return Collections.unmodifiableSet(this.neighborEdges.get(node)); // if (!containsVertex(node)) // return null; // // Set<ValueDirectedEdge<N,E>> incident = new HashSet(); // incident.addAll(getIncoming_internal(node)); // incident.addAll(getOutgoing_internal(node)); // return Collections.unmodifiableSet(incident); // } // // public Set<ValueDirectedEdge<N,E>> getTraversableEdges(N node) { // final Set<ValueDirectedEdge<N,E>> traversableEdges = new HashSet(); // for (ValueDirectedEdge<N,E> edge : edges) { // if (edge.getSourceNode() == node) { // traversableEdges.add(edge); // } // } // return Collections.unmodifiableSet(traversableEdges); // } // // public Set<ValueDirectedEdge<N,E>> getOutEdges(N node) { // return this.getTraversableEdges(node); // } // // public Set<ValueDirectedEdge<N,E>> getInEdges(N node) { // return getIncoming_internal(node); // } // // public int getIndegree(N node) { // return this.getInEdges(node).size(); // } // // public int getOutdegree(N node) { // return this.getOutEdges(node).size(); // } // // public List<N> getAdjacentNodes(N vertex) { // if (!containsVertex(vertex)) // return null; // // List<N> neighbors = new LinkedList<N>(); // for (ValueDirectedEdge<N,E> edge : getIncoming_internal(vertex)) // neighbors.add(this.getSource(edge)); // for (ValueDirectedEdge<N,E> edge : getOutgoing_internal(vertex)) // neighbors.add(this.getDest(edge)); // return Collections.unmodifiableList(neighbors); // } // // public List<N> getTraversableNodes(N node) { // Set<ValueDirectedEdge<N,E>> traversableEdges = this.getTraversableEdges(node); // List<N> traversableNeighbors = new ArrayList<N>(); // for (ValueDirectedEdge<N,E> traversableEdge : traversableEdges) { // traversableNeighbors.add(traversableEdge.getDestinationNode()); // } // return Collections.unmodifiableList(traversableNeighbors); // } // // public N getSource(ValueDirectedEdge<N,E> edge) { // if (!containsEdge(edge)) // return null; // return this.getEndpoints(edge).getFirst(); // } // // public N getDest(ValueDirectedEdge<N,E> edge) { // if (!containsEdge(edge)) // return null; // return this.getEndpoints(edge).getSecond(); // } // // }