// GraphTea Project: http://github.com/graphtheorysoftware/GraphTea // Copyright (C) 2012 Graph Theory Software Foundation: http://GraphTheorySoftware.com // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology // Distributed under the terms of the GNU Lesser General Public License (LGPL): http://www.gnu.org/licenses/ /* * MatrixGraph.java * * Created on November 13, 2004, 8:32 PM * Last Modify on November 15, 2004, 05:03 AM */ package graphtea.library; import Jama.Matrix; import graphtea.library.event.handlers.PreWorkHandler; import graphtea.library.event.handlers.PreWorkPostWorkHandler; import graphtea.library.exceptions.InvalidEdgeException; import graphtea.library.exceptions.InvalidGraphException; import graphtea.library.exceptions.InvalidVertexException; import graphtea.library.genericcloners.EdgeVertexCopier; import graphtea.library.genericcloners.GraphConverter; import java.util.AbstractList; import java.util.ArrayList; import java.util.Iterator; /** * Adjacency Matrix Graph. * For information about Adjacency Matrix refer to http://en.wikipedia.org/wiki/Adjacency_matrix * * @author Hooman Mohajeri Moghaddam, added weighted version of weightOfEdge method * @author Omid Aladini * @param <VertexType> Type of the vertices the graph can work with. * @param <EdgeType> Type of the edges the graph can work with. */ public class MatrixGraph<VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>> extends BaseGraph<VertexType, EdgeType> { /** * The data structure to store graph data, it looks like a three dimensional matrix with EdgeType elements. * The third dimension is designed to store multiple edges between two vertices. * ArrayLists can work with generic type's parameters and they are as fast as arrays for indexing, but * they are not thread safe. So MatrixGraph operations are not thread-safe and should be synchronized * externally. */ private ArrayList<ArrayList<ArrayList<EdgeType>>> adjacencyMatrix; //list of vertices private ArrayList<VertexType> vertices; //In-degree of vertices by order stored in <code>vertices</code> object. //More clearly, the number of edges which their sources are connected to the vertex. private ArrayList<Integer> inDegree; //Out-degree of vertices by order stored in <code>vertices</code> object. //More clearly, the number of edges which their targets are connected to the vertex. private ArrayList<Integer> outDegree; //Specified whether the graph is directed. private boolean directed; private int edgeCount = 0; /** * Constructs a graph object that stores graph data using adjacency matrix data structure. * * @param directed Indicated whether the graph is directed. * @param expectedNumberOfVertices Approximate number of vertices that will be * added to the graph. This paramether is optional and is available for performance * reasons. */ public MatrixGraph(boolean directed, int expectedNumberOfVertices) { this.directed = directed; adjacencyMatrix = new ArrayList<>(expectedNumberOfVertices); for (int rowCount = 0; rowCount < expectedNumberOfVertices; rowCount++) { ArrayList<ArrayList<EdgeType>> columns = new ArrayList<>(expectedNumberOfVertices); adjacencyMatrix.add(columns); } vertices = new ArrayList<>(expectedNumberOfVertices); inDegree = new ArrayList<>(expectedNumberOfVertices); if (!directed) outDegree = inDegree; else outDegree = new ArrayList<>(expectedNumberOfVertices); } /** * Constructs a MatrixGraph object * * @param directed Whether the graph is directed or undirected. */ public MatrixGraph(boolean directed) { this(directed, 5); } /** * Constructs an undirected graph object that stores graph data using * adjacency list data structure. */ public MatrixGraph() { this(false, 5); } /** * Constructs a graph object that stores graph data using adjacency matrix data structure by importing * graph data from a pre-existing graph. A GraphConvertor object is passed as a parameter which is * reponsible for duplication/type-convertion of graph elements. * * @param <ImportVertexType> The type of vertex object which the input graph contain. * @param <ImportEdgeType> The type of edge object which the input graph contain. * @param graph The given graph * @param gc A GraphConverter object which is responsible for duplicating/converting graph * elements. * @throws InvalidGraphException Throws when the input graph is an invalid graph object. */ public <ImportVertexType extends BaseVertex, ImportEdgeType extends BaseEdge<ImportVertexType>, ImportGraphType extends BaseGraph<ImportVertexType, ImportEdgeType> > MatrixGraph(BaseGraph<ImportVertexType, ImportEdgeType> graph, GraphConverter<ImportVertexType, VertexType, ImportEdgeType, EdgeType, ImportGraphType, MatrixGraph<VertexType, EdgeType>> gc) throws InvalidGraphException { ArrayList<VertexType> tempAL = new ArrayList<>(getVerticesCount()); for (ImportVertexType v : graph) { insertVertex(gc.convert(v)); tempAL.add(gc.convert(v)); } Iterator<ImportEdgeType> iet = graph.edgeIterator(); ImportEdgeType edge; try { while (iet.hasNext()) { edge = iet.next(); insertEdge(gc.convert(edge, tempAL.get(edge.source.getId()), tempAL.get(edge.target.getId()))); } } catch (InvalidVertexException e) { throw new InvalidGraphException(); } } /* (non-Javadoc) * @see graphtea.library.BaseGraph#getVerticesCount() */ @Override public int getVerticesCount() { return vertices.size(); } /** * Checks if a vertex with internal id <i>id</i> exist. * * @param id Id of the vertex. * @return true of exist false if not. */ private boolean vertexIdOutOfRange(int id) { return id < 0 || id >= vertices.size(); } /** * Returns the vertex with internal id <I>id</I> * * @param id Internal index of the vertex. * @return Reference of the vertex object. */ private VertexType getVertex(int id) throws InvalidVertexException { if (vertexIdOutOfRange(id)) throw new InvalidVertexException(); return vertices.get(id); } /** * Lables the vertices using their internal Id property by the index they live inside the graph. */ private void setVertexIds() { try { for (int i = 0; i < getVerticesCount(); i++) getVertex(i).setId(i); } catch (InvalidVertexException e) { System.out.println("NEVER-HAPPENS EXCEPTION"); e.printStackTrace(); } } /* (non-Javadoc) * @see graphtea.library.BaseGraph#insertEdge(null) */ @Override public void insertEdge(EdgeType newEdge) throws InvalidVertexException { VertexType sourceObj, targetObj; int source, target; sourceObj = newEdge.source; targetObj = newEdge.target; source = newEdge.source.getId(); target = newEdge.target.getId(); checkVertex(sourceObj); checkVertex(targetObj); ArrayList<EdgeType> edges; if (adjacencyMatrix.get(source).get(target) == null) { edges = new ArrayList<>(5); adjacencyMatrix.get(source).set(target, edges); } else { edges = adjacencyMatrix.get(source).get(target); } edges.add(newEdge); if (!directed) adjacencyMatrix.get(target).set(source, edges); outDegree.set(source, inDegree.get(source) + 1); inDegree.set(target, inDegree.get(target) + 1); if (!directed) { inDegree.set(source, inDegree.get(source) + 1); outDegree.set(target, inDegree.get(target) + 1); } ++edgeCount; } /** * Returns all edges between two vertices. * * @param source Index of the edges' start point. * @param target Index of the edges' end point. * @return An ArrayList of <I>EdgeType</I> containing all edges between <I>from</I> and <I>to</I>. * @throws graphtea.library.exceptions.InvalidVertexException * Thrown when two supplied indexes of vertices are invalid. */ private ArrayList<EdgeType> getEdges(int source, int target) throws InvalidVertexException { if (vertexIdOutOfRange(source) || vertexIdOutOfRange(target)) throw new InvalidVertexException(); return adjacencyMatrix.get(source).get(target); } /** * Returns all edges between two vertices. * * @param source Index of the edges' start point. * @param target Index of the edges' end point. * @return An ArrayList of <I>EdgeType</I> containing all edges between <I>from</I> and <I>to</I>. * @throws graphtea.library.exceptions.InvalidVertexException * Thrown when two supplied indexes of vertices are invalid. */ @Override public ArrayList<EdgeType> getEdges(VertexType source, VertexType target) throws InvalidVertexException { int sourceId = source.getId(); int targetId = target.getId(); checkVertex(target); checkVertex(source); return adjacencyMatrix.get(sourceId).get(targetId); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#insertVertex(null) */ @Override public void insertVertex(VertexType newVertex) { vertices.add(newVertex); int size = getVerticesCount(); newVertex.setId(size); if (adjacencyMatrix.size() < size) { adjacencyMatrix.ensureCapacity(size * 2); adjacencyMatrix.add(new ArrayList<>()); } int newSize = adjacencyMatrix.size(); for (int row = 0; row < newSize; row++) { if (row == newSize - 1) { for (int newSizeIndex = 0; newSizeIndex < newSize; newSizeIndex++) { adjacencyMatrix.get(row).add(null); } } else { adjacencyMatrix.get(row).add(null); } } inDegree.add(0); outDegree.add(0); } /** * Runs Depth First Search (DFS) algorithm on the graph starting from vertex <I>vertexId</I>. * A reference to a PreWorkPostWorkHandler is supplied that contains implementation * of pre-work and post-work operations that depends on the application of DFS. * * @param vertex Starting vertex of the traversal. * @param handler A reference to a PreWorkPostWorkHandler that contains implementation * of pre-work and post-work operations that depends on the application of DFS. * @return Whether the traversal has stopped at the middle by the handler. * @throws InvalidVertexException the vertex is invalid */ public boolean depthFirstSearch(VertexType vertex, PreWorkPostWorkHandler<VertexType> handler) throws InvalidVertexException { return new graphtea.library.algorithms.traversal.DepthFirstSearch<>(this) .doSearch(vertex, handler); } /** * Runs Breadth First Search (BFS) algorithm on the graph starting from vertex <I>vertexId</I>. * A reference to a PreWorkHandler is supplied that contains implementation * of pre-work operation that depends on the application of BFS. * * @param vertex Starting vertex of the traversal. * @param handler A reference to a PreWorkHandler that contains implementation * of pre-work operation that depends on the application of DFS. * @return Whether the traversal has stopped at the middle by the handler. * @throws InvalidVertexException the vertex is invalid */ public boolean breadthFirstSearch(VertexType vertex, PreWorkHandler<VertexType> handler) throws InvalidVertexException { return new graphtea.library.algorithms.traversal.BreadthFirstSearch<>(this) .doSearch(vertex, handler); } /** * Checks whether the current graph is a connected graph. * * @return True if graph is connected and false otherwise. */ public boolean isGraphConnected() { try { return graphtea.library.algorithms.util.ConnectivityChecker.isGraphConnected(this); } catch (InvalidGraphException e) { //Generally should not happen. So I don't bother the user by //adding throws declaration. e.printStackTrace(); return false; } } /** * Checks whether the current graph is acyclic. * * @return True if graph is acyclic and false otherwise. */ public boolean isGraphAcyclic() { try { //Soooo easy to use! return graphtea.library.algorithms.util.AcyclicChecker.isGraphAcyclic(this); } catch (InvalidGraphException e) { //Generally should not happen. So I don't bother the user by //adding throws declaration. e.printStackTrace(); return false; } } /* (non-Javadoc) * @see java.lang.Iterable#iterator() */ @Override public Iterator<VertexType> iterator() { return vertices.iterator(); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#isDirected() */ @Override public boolean isDirected() { return directed; } /** * Returns in-degree of vertex <I>vertexId</I>, the number of edges which * their target goes to the specified vertex. * * @return in-degree of vertex <I>vertexId</I>. * @throws InvalidVertexException Invalid vertex exception */ private int getInDegree(int vertexId) throws InvalidVertexException { if (vertexIdOutOfRange(vertexId)) throw new InvalidVertexException(); return inDegree.get(vertexId); } /** * Returns out-degree of vertex <I>vertexId</I>, the number of edges which * their tale is attached to the specified vertex. * * @return out-degree of vertex <I>vertexId</I>. * @throws InvalidVertexException The vertex is invalid */ private int getOutDegree(int vertexId) throws InvalidVertexException { if (vertexIdOutOfRange(vertexId)) throw new InvalidVertexException(); return outDegree.get(vertexId); } /** * This class iterates all, edges coming from or going to a specified vertex. * The order of edges the iterator iterate is undefined because of future code changes. * * @author Omid Aladini */ private class EdgeIterator implements Iterator<EdgeType> { private Iterator<EdgeType> edgesIterator; private EdgeType lastEdge = null; /** * Constructs an Edge Iterator object which iterates through all the edges in the graph. * Note that if the graph object is changed during iteration, the iteration may not * actually represent current state of the graph. For example, if you deleted an edge * after construction of this object, the edge would be included in the iteration. */ public EdgeIterator() { ArrayList<EdgeType> edges = new ArrayList<>(); if (directed) { for (ArrayList<ArrayList<EdgeType>> aae : adjacencyMatrix) for (ArrayList<EdgeType> ae : aae) for (EdgeType e : ae) edges.add(e); } else { int iCount = 0; int jCount; for (ArrayList<ArrayList<EdgeType>> aae : adjacencyMatrix) { Iterator<ArrayList<EdgeType>> it = aae.iterator(); jCount = 0; while (iCount >= jCount) { ++jCount; ArrayList<EdgeType> ae = it.next(); if (ae == null) continue; for (EdgeType e : ae) edges.add(e); } ++iCount; } } edgesIterator = edges.iterator(); } /** * Number of times edge Iteration is called. This will set as a temporary flag into * edges in order to reduce running time of edge iteration back to O(n^2). */ int edgeIterationIndex = 0; /** * Constructs an Edge Iterator object which iterates through all the edges going to * or coming from the specified vertex <code>v</code>. * Note that if the graph object is changed during iteration, the iteration may not * actually represent current state of the graph. For example, if you deleted an edge * after construction of this object, the edge would be included in the iteration. * * @param v Source or target of desired edges. */ private EdgeIterator(VertexType v) throws InvalidVertexException { checkVertex(v); if (!directed) ++edgeIterationIndex; ArrayList<EdgeType> edges = new ArrayList<>(); ArrayList<ArrayList<EdgeType>> row = adjacencyMatrix.get(v.getId()); for (ArrayList<EdgeType> ae : row) for (EdgeType e : ae) { edges.add(e); if (!directed) e.edgeIterationIndex = edgeIterationIndex; } for (ArrayList<ArrayList<EdgeType>> aae : adjacencyMatrix) { if (row == aae) continue; for (ArrayList<EdgeType> ae : aae) for (EdgeType e : ae) { if (e.target == v) { if (directed) { edges.add(e); } else if (e.edgeIterationIndex != edgeIterationIndex) { e.edgeIterationIndex = edgeIterationIndex; edges.add(e); } } } } edgesIterator = edges.iterator(); } /** * Constructs an Edge Iterator object which iterates through all the edges going to * or coming from (depending on the second parameter) the specified vertex <code>v</code>. * If the second parameter it true, then the first parameter is considered to be source of * all desired edges, and if it's false the first parameter is considered to be target of desired edges. * Note that if the graph object is changed during iteration, the iteration may not * actually represent current state of the graph. For example, if you deleted an edge * after construction of this object, the edge would be included in the iteration. * * @param v If the second parameter is true indicated the vertex which is source of desired edges, otherwise * it is considered to be target of desired edges. * @param source True means the first parameter should be considered source of desired edges. */ public EdgeIterator(VertexType v, boolean source) throws InvalidVertexException { checkVertex(v); if (!directed) ++edgeIterationIndex; ArrayList<EdgeType> edges = new ArrayList<>(); ArrayList<ArrayList<EdgeType>> row = adjacencyMatrix.get(v.getId()); if (source) { for (ArrayList<EdgeType> ae : row) for (EdgeType e : ae) { edges.add(e); if (!directed) e.edgeIterationIndex = edgeIterationIndex; } } else { for (ArrayList<ArrayList<EdgeType>> aae : adjacencyMatrix) { if (row == aae) continue; for (ArrayList<EdgeType> ae : aae) for (EdgeType e : ae) { if (e.target == v) { if (directed) { edges.add(e); } else if (e.edgeIterationIndex != edgeIterationIndex) { e.edgeIterationIndex = edgeIterationIndex; edges.add(e); } } } } } edgesIterator = edges.iterator(); } public boolean hasNext() { return edgesIterator.hasNext(); } public EdgeType next() { lastEdge = edgesIterator.next(); return lastEdge; } public void remove() { try { removeEdge(lastEdge); } catch (InvalidEdgeException e) { System.out.println("Invalid remove operation."); e.printStackTrace(); } } } /** * Returns iterator object for the edges. * * @return iterator object for the edges. */ public Iterator<EdgeType> edgeIterator() { return new EdgeIterator(); } public Iterable<EdgeType> edges() { return new Iterable<EdgeType>() { public Iterator<EdgeType> iterator() { return edgeIterator(); } }; } /* (non-Javadoc) * @see graphtea.library.BaseGraph#edgeIterator(null) */ @Override public Iterator<EdgeType> edgeIterator(VertexType v) throws InvalidVertexException { return new EdgeIterator(v); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#edgeIterator(null, boolean) */ @Override public Iterator<EdgeType> edgeIterator(VertexType v, boolean source) throws InvalidVertexException { return new EdgeIterator(v, source); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#getAdjacencyMatrix() */ @Override public Matrix getAdjacencyMatrix() { Matrix matrix = new Matrix(getVerticesCount(), getVerticesCount()); try { if (directed) { for (int i = 0; i < getVerticesCount(); i++) for (int j = 0; j < getVerticesCount(); j++) if (getEdges(i, j) != null) matrix.set(i, j, getEdges(i, j).size()); } else { for (int i = 0; i < getVerticesCount(); i++) for (int j = 0; j <= i; j++) if (getEdges(i, j) != null) { matrix.set(i, j, getEdges(i, j).size()); if (i != j) matrix.set(j, i, getEdges(i, j).size()); } } } catch (Exception e) { //never happens System.out.println("NEVER-HAPPENS-BUG:getAdjMatrix:"); e.printStackTrace(); } return matrix; } public Matrix getWeightedAdjacencyMatrix() { Matrix matrix = new Matrix(getVerticesCount(), getVerticesCount()); try { if (directed) { for (int i = 0; i < getVerticesCount(); i++) for (int j = 0; j < getVerticesCount(); j++) if (getEdges(i, j) != null) matrix.set(i, j, getEdges(i, j).get(0).getWeight()); } else { for (int i = 0; i < getVerticesCount(); i++) for (int j = 0; j <= i; j++) if (getEdges(i, j) != null) { matrix.set(i, j, getEdges(i, j).get(0).getWeight()); if (i != j) matrix.set(j, i, getEdges(i, j).get(0).getWeight()); } } } catch (Exception e) { //never happens System.out.println("NEVER-HAPPENS-BUG:getAdjMatrix:"); e.printStackTrace(); } return matrix; } /* (non-Javadoc) * @see graphtea.library.BaseGraph#dump() */ @Override public void dump() { System.out.print('\n'); for (int i = 0; i < getVerticesCount(); i++) { for (int j = 0; j < getVerticesCount(); j++) { System.out.print(" "); System.out.print(adjacencyMatrix.get(i).get(j) == null ? 0 : 1); } System.out.println(""); } } /* (non-Javadoc) * @see graphtea.library.BaseGraph#removeAllEdges(null, null) */ @Override public void removeAllEdges(VertexType source, VertexType target) throws InvalidVertexException { if (vertexIdOutOfRange(source.getId()) || vertexIdOutOfRange(target.getId()) || source != vertices.get(source.getId()) || target != vertices.get(target.getId())) throw new InvalidVertexException(); adjacencyMatrix.get(source.getId()).get(target.getId()).clear(); if (!directed) removeAllEdges(target, source); } /** * Removes a vertex and all it's connected edges. * * @param vertexId index of the vertex to be removed */ private void removeVertex(int vertexId) throws InvalidVertexException { for (ArrayList<ArrayList<EdgeType>> c : adjacencyMatrix) { c.remove(vertexId); } adjacencyMatrix.remove(vertexId); vertices.remove(vertexId); inDegree.remove(vertexId); outDegree.remove(vertexId); setVertexIds(); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#removeVertex(null) */ @Override public void removeVertex(VertexType v) throws InvalidVertexException { checkVertex(v); removeVertex(v.getId()); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#getInDegree(null) */ @Override public int getInDegree(VertexType v) throws InvalidVertexException { checkVertex(v); return getInDegree(v.getId()); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#getOutDegree(null) */ @Override public int getOutDegree(VertexType v) throws InvalidVertexException { checkVertex(v); return getOutDegree(v.getId()); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#removeEdge(null) */ @Override public void removeEdge(EdgeType edge) throws InvalidEdgeException { int source = edge.source.getId(); int target = edge.target.getId(); try { checkVertex(edge.target); checkVertex(edge.source); } catch (InvalidVertexException e) { throw new InvalidEdgeException(); } adjacencyMatrix.get(target).get(source).remove(edge); if (!directed) adjacencyMatrix.get(source).get(target).remove(edge); --edgeCount; } public VertexType getAVertex() { Iterator<VertexType> it = iterator(); if (it.hasNext()) return it.next(); else return null; } /* (non-Javadoc) * @see graphtea.library.BaseGraph#copy(graphtea.library.GraphConverter) */ @Override public BaseGraph<VertexType, EdgeType> copy(EdgeVertexCopier<VertexType, EdgeType> gc) throws InvalidGraphException { MatrixGraph<VertexType, EdgeType> oGraph = new MatrixGraph<>(directed, getVerticesCount()); ArrayList<VertexType> tempAL = new ArrayList<>(getVerticesCount()); VertexType tempVertex; for (VertexType v : this) { tempVertex = gc.convert(v); oGraph.insertVertex(tempVertex); tempAL.add(tempVertex); } Iterator<EdgeType> iet = edgeIterator(); EdgeType edge; try { while (iet.hasNext()) { edge = iet.next(); oGraph.insertEdge(gc.convert(edge, tempAL.get(edge.source.getId()), tempAL.get(edge.target.getId()))); } } catch (InvalidVertexException e) { throw new InvalidGraphException(); } return oGraph; } /* (non-Javadoc) * @see graphtea.library.BaseGraph#containsVertex(null) */ @Override public boolean containsVertex(VertexType v) { return vertices.contains(v); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#checkVertex(null) */ @Override public void checkVertex(VertexType v) throws InvalidVertexException { if (vertexIdOutOfRange(v.getId()) || v != vertices.get(v.getId())) throw new InvalidVertexException(); } public <GraphType extends BaseGraph<VertexType, EdgeType>> GraphType createEmptyGraph() { return null; } @Override public boolean isEdge(VertexType source, VertexType target) throws InvalidVertexException { return (getEdges(source, target) != null) && (getEdges(source, target).size() != 0); } // @Override public MatrixGraph<VertexType, EdgeType> dcreateEmptyGraph() { return new MatrixGraph<>(directed, 0); } @Override public void setDirected(boolean isDirected) { //TODO: Stub throw new RuntimeException("Not yet implemented."); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#getVertexArray() */ @Override public BaseVertex[] getVertexArray() { BaseVertex[] arr = new BaseVertex[getVerticesCount()]; for (VertexType v : this) arr[v.getId()] = v; return arr; } /* (non-Javadoc) * @see graphtea.library.BaseGraph#getEdgeArray() */ @Override public int[][] getEdgeArray() { int[][] arr = new int[getVerticesCount()][]; int i = 0; int j; int k; for (ArrayList<ArrayList<EdgeType>> ll : adjacencyMatrix) { j = 0; ArrayList<Integer> temp = new ArrayList<>(); for (ArrayList<EdgeType> alet : ll) { if (alet != null && alet.size() != 0) temp.add(j++); } arr[i] = new int[temp.size()]; k = 0; for (Integer vertexId : temp) arr[i][k++] = vertexId; ++i; } return arr; } /* (non-Javadoc) * @see graphtea.library.BaseGraph#lightEdgeIterator() */ @Override public Iterator<EdgeType> lightEdgeIterator() { //TODO: Stub, not yet light. return edgeIterator(); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#lightEdgeIterator(null) */ @Override public Iterator<EdgeType> lightEdgeIterator(VertexType v) throws InvalidVertexException { //TODO: Stub, not yet light. return edgeIterator(v); } public Iterator<EdgeType> lightBackEdgeIterator(VertexType v) throws InvalidVertexException { //TODO: Stub throw new RuntimeException("Not yet implemented."); } /* (non-Javadoc) * @see graphtea.library.BaseGraph#clear() */ @Override public void clear() { int expectedNumberOfVertices = 0; adjacencyMatrix = new ArrayList<>(expectedNumberOfVertices); for (int rowCount = 0; rowCount < expectedNumberOfVertices; rowCount++) { ArrayList<ArrayList<EdgeType>> columns = new ArrayList<>(expectedNumberOfVertices); adjacencyMatrix.add(columns); } vertices = new ArrayList<>(expectedNumberOfVertices); inDegree = new ArrayList<>(expectedNumberOfVertices); if (!directed) outDegree = inDegree; else outDegree = new ArrayList<>(expectedNumberOfVertices); edgeCount = 0; } @Override public int getEdgesCount() { return edgeCount; } /* (non-Javadoc) * @see graphtea.library.BaseGraph#weightOfEdge(null, null) */ @Override public int[] weightOfEdge(VertexType source, VertexType target) throws InvalidVertexException { int[] res=null; if(isEdge(source, target)) { AbstractList<EdgeType> edges = getEdges(source, target); int i=0; for(EdgeType et : edges ) { res[i] = et.getWeight(); i++; } } return res; } }