001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU Lesser General Public License (LGPL): http://www.gnu.org/licenses/
004    
005    /*
006     * BaseGraph.java
007     *
008     * Created on November 13, 2004, 8:20 PM
009     */
010    
011    package graphlab.library;
012    
013    import Jama.Matrix;
014    import graphlab.library.exceptions.InvalidEdgeException;
015    import graphlab.library.exceptions.InvalidGraphException;
016    import graphlab.library.exceptions.InvalidVertexException;
017    import graphlab.library.genericcloners.EdgeVertexCopier;
018    
019    import java.util.AbstractList;
020    import java.util.Iterator;
021    
022    /**
023     * Generic base class for representation of all types of graphs.
024     *
025     * @author Omid Aladini
026     */
027    abstract public class BaseGraph<VertexType extends BaseVertex, EdgeType extends BaseEdge<VertexType>>
028            implements Iterable<VertexType> {
029        /**
030         * Returns the number of vertices.
031         *
032         * @return Number of vertices in the graph.
033         */
034        public abstract int getVerticesCount();
035    
036        /**
037         * Creates a clone of the current graph using the GraphConverter object which is responsible
038         * for duplication of the graph elements (edges and vertices).
039         *
040         * @param gc Reference to EdgeVertexCopier object.
041         * @return Clone of the current graph which is independent of it's source graph.
042         * @throws InvalidGraphException If the graph is not a valid graph object.
043         */
044        public abstract BaseGraph<VertexType, EdgeType>
045        copy(EdgeVertexCopier<VertexType, EdgeType> gc)
046                throws InvalidGraphException;
047    
048        /**
049         * Inserts an edge in the graph.
050         *
051         * @param newEdge Reference to the new edge object.
052         * @throws graphlab.library.exceptions.InvalidVertexException
053         *          Thrown when the edge object tries
054         *          to connect two vertices whom their indexes are invalid.
055         */
056        public abstract void insertEdge(EdgeType newEdge)
057                throws InvalidVertexException;
058    
059        /**
060         * Removes all edges between two vertices.
061         *
062         * @param source Index of the edges' start point.
063         * @param target Index of the edges' end point.
064         * @throws graphlab.library.exceptions.InvalidVertexException
065         *          Thrown when two supplied indexes of vertices are invalid.
066         */
067        public abstract void removeAllEdges(VertexType source, VertexType target)
068                throws InvalidVertexException;
069    
070        /**
071         * Removes an edge from the graph.
072         *
073         * @param edge Edge to be removed.
074         * @throws InvalidEdgeException If <code>edge</code> is an invalid edge object.
075         */
076        public abstract void removeEdge(EdgeType edge)
077                throws InvalidEdgeException;
078    
079        /**
080         * Returns a collection of all edges which connects two vertices supplied as first and second arguments of
081         * this method.
082         *
083         * @param Source of the desired edges.
084         * @param Target of the desired edges.
085         * @return Returns a collection of all edges which connects two vertices supplied as first and second arguments of
086         *         this method.
087         * @throws InvalidVertexException if supplied source or target are invalid.
088         */
089        public abstract AbstractList<EdgeType> getEdges(VertexType source, VertexType target)
090                throws InvalidVertexException;
091    
092        /**
093         * Returns true if there is an edge between specified vertices (direction considered for directed graphs).
094         *
095         * @param Source of the edge for existance check.
096         * @param Target of the edge for existance check.
097         * @return true if there is an edge between specified vertices (direction considered for directed graphs).
098         * @throws InvalidVertexException if supplied source or target are invalid.
099         */
100        public abstract boolean isEdge(VertexType source, VertexType target)
101                throws InvalidVertexException;
102    
103        /**
104         * Inserts a new vertex to the graph.
105         *
106         * @param newVertex The new vertex to be inserted.
107         */
108        public abstract void insertVertex(VertexType newVertex);
109    
110        /**
111         * Removes a vertex and all it's connected edges.
112         *
113         * @param Vertex to be removed.
114         */
115        public abstract void removeVertex(VertexType v)
116                throws InvalidVertexException;
117    
118        /**
119         * Returns iterator object for the vertices.
120         *
121         * @return iterator object for the vertices.
122         */
123        public abstract Iterator<VertexType> iterator();
124    
125        /**
126         * Returns in-degree of vertex <I>vertexId</I>, the number of edges which
127         * their target goes to the specified vertex.
128         *
129         * @return in-degree of vertex <I>vertexId</I>.
130         * @throws InvalidVertexException
131         * @see graphlab.library.BaseGraph#getDegree(BaseVertex)
132         */
133        public abstract int getInDegree(VertexType v)
134                throws InvalidVertexException;
135    
136        /**
137         * Returns out-degree of the supplied vertex, the number of edges which
138         * their source is attached to the specified vertex.
139         *
140         * @return out-degree of vertex <I>vertexId</I>.
141         * @throws InvalidVertexException
142         * @see graphlab.library.BaseGraph#getDegree(BaseVertex)
143         */
144        public abstract int getOutDegree(VertexType v)
145                throws InvalidVertexException;
146    
147        /**
148         * Returns a Jama Matrix object that represents adjacency matrix of
149         * the graph. the Matrix object have the ability apply simple linear
150         * algebra operations on the adjacency matrix.
151         *
152         * @return Adjacency Matrix of the graph as a Jama Matrix object.
153         */
154        public abstract Matrix getAdjacencyMatrix();
155    
156        /**
157         * Returns whether the graph is directed.
158         *
159         * @return True is graph is constructed as a directed graph and false otherwise.
160         */
161        public abstract boolean isDirected();
162    
163        /**
164         * Prints the Adjacency Matrix to the standard output.
165         */
166        public abstract void dump();
167    
168        /**
169         * Constructs and returns an Edge Iterator object which iterates through all the edges in the graph.
170         * Note that if the graph object is changed during iteration, the iteration may not
171         * actually represent current state of the graph. For example, if you deleted an edge
172         * after construction of this object, the edge would be included in the iteration.
173         *
174         * @return Iterator object on edges.
175         * @see BaseGraph#lightEdgeIterator()
176         */
177        public abstract Iterator<EdgeType> edgeIterator();
178    
179        /**
180         * Constructs an Edge Iterator object which iterates through all the edges going to
181         * or coming from the specified vertex <code>v</code>.
182         * Note that if the graph object is changed during iteration, the iteration may not
183         * actually represent current state of the graph. For example, if you deleted an edge
184         * after construction of this object, the edge would be included in the iteration.
185         *
186         * @param v Source or target of desired edges.
187         * @return Iterator object on edges which their sources or targets are the supplied vertex.
188         * @see graphlab.library.BaseGraph#lightEdgeIterator(BaseVertex)
189         * @see graphlab.library.BaseGraph#getNeighbors(BaseVertex)
190         */
191        public abstract Iterator<EdgeType> edgeIterator(VertexType v)
192                throws InvalidVertexException;
193    
194        /**
195         * This method returns true if the graph contains the specified vertex, false otherwise.
196         *
197         * @param v Vertex to check existance.
198         * @return True if the graph contains the specified vertex, false otherwise.
199         */
200        public abstract boolean containsVertex(VertexType v);
201    
202        /**
203         * If the supplied vertex is invalid (Not one of graph's vertices), throws InvalidVertexException. This
204         * method should be called before any operation by algorithms where some vertices
205         * are supplied as their arguments.
206         *
207         * @param v The vertex to be checked.
208         * @throws InvalidVertexException If the supplied vertex is invalid.
209         */
210        public abstract void checkVertex(VertexType v)
211                throws InvalidVertexException;
212    
213        /**
214         * Returns a new instance of an empty graph of the current graph type.
215         *
216         * @return A new instance of an empty graph of the current graph type.
217         */
218        public abstract <GraphType extends BaseGraph<VertexType, EdgeType>>
219        GraphType createEmptyGraph();
220    
221        /**
222         * Returns array of vertices upcasted to BaseVertex.
223         *
224         * @return Array of vertices upcasted to BaseVertex.
225         */
226        public abstract BaseVertex[] getVertexArray();
227    
228        /**
229         * Returns array of array of 'int's where represents a simple adjacency list.
230         *
231         * @return Array of array of 'int's where represents a simple adjacency list.
232         */
233        public abstract int[][] getEdgeArray();
234    
235        /**
236         * Returns a light(weight) Edge Iterator object which iterates through all the edges in the graph.
237         * The light(weight) edge iterator presents an iterator with O(1) constructor. Note that you should
238         * not change the content of the graph during your iteration. You can still change properties of
239         * each edge or vertex.
240         *
241         * @return Returns a light(weight) Edge Iterator object.
242         */
243        public abstract Iterator<EdgeType> lightEdgeIterator();
244    
245        /**
246         * Constructs a light(weight) Edge Iterator object which iterates through all the edges going to
247         * or coming from the specified vertex <code>v</code>.
248         * The light(weight) edge iterator presents an iterator with O(1) constructor. Note that you should
249         * not change the content of the graph during your iteration. You can still change properties of
250         * each edge or vertex.
251         *
252         * @param v Source or target of desired edges.
253         * @return A light(weight) Edge Iterator object which iterates through all the edges going to
254         *         or coming from the specified vertex.
255         */
256        public abstract Iterator<EdgeType> lightEdgeIterator(VertexType v)
257                throws InvalidVertexException;
258    
259        /**
260         * Clears the graph.
261         */
262        public abstract void clear();
263    
264        public abstract void setDirected(boolean isDirected);
265    
266        /**
267         * If zero, indicates that the graph is not a subgraph. If greater than zero,
268         * it indicates that it's a subgraph with Id <code>subgraphId</code>.
269         */
270        protected int subgraphIndex = 0;
271    
272        /**
273         * Whether the graph is a subgraph. Then it shares it's contents.
274         */
275        protected boolean isSubgraph = false;
276        protected int lastSubgraphIndex = 0;
277        protected BaseGraph<VertexType, EdgeType> superGraph = null;
278    
279        /**
280         * Sets the graph as a subgraph.
281         *
282         * @param b
283         */
284        public void registerSubgraph(BaseGraph<VertexType, EdgeType> superGraph) {
285            isSubgraph = true;
286            this.superGraph = superGraph;
287            superGraph.informVertices();
288        }
289    
290        private void informVertices() {
291            if (isSubgraph)
292                superGraph.informVertices();
293    
294            for (VertexType v : this) {
295                v.informNewSubgraph();
296            }
297    
298        }
299    
300        /**
301         * Get new id for a new subgraph;
302         *
303         * @param b
304         */
305        public int getNewSubgraphIndex() {
306            if (isSubgraph)
307                return superGraph.getNewSubgraphIndex();
308            return lastSubgraphIndex + 1;
309        }
310    
311        /**
312         * Set's the subgraph index.
313         *
314         * @param i the subgraph index.
315         * @return
316         */
317        public void setSubGraphIndex(int i) {
318            subgraphIndex = i;
319        }
320    
321    
322        /**
323         * A wrapper for getting vertex Id's which supports multiple vertex owners.
324         *
325         * @param v Vertex which the caller intends to get its Id.
326         * @return The Id.
327         */
328        protected int getId(VertexType v) {
329            if (subgraphIndex != 0) {
330                return v.getSubgraphId(subgraphIndex);
331            }
332    
333            return v.getId();
334        }
335    
336        public abstract int getEdgesCount();
337    
338        // -------------------         Some Helper Methods          ----------------------
339        /**
340         * @see BaseGraph#lightEdgeIterator()
341         */
342        public Iterable<EdgeType> edges() {
343            return new Iterable<EdgeType>() {
344                public Iterator<EdgeType> iterator() {
345                    return lightEdgeIterator();
346                }
347            };
348        }
349    
350        /**
351         * Returns degree of vertex, the number of edges which their target or source is the specified vertex.
352         *
353         * @param vertex
354         */
355        public int getDegree(VertexType vertex) {
356            return isDirected() ? getInDegree(vertex) + getOutDegree(vertex) : getInDegree(vertex);
357        }
358    
359        /**
360         * @param vertex
361         * @return an Iterable object which can be iterated trough all neighbours of the given vertex using lightEdgeIterator(vertex)
362         * @see graphlab.library.BaseGraph#lightEdgeIterator(BaseVertex)
363         */
364        public Iterable<VertexType> getNeighbors(final VertexType vertex) {
365            return new Iterable<VertexType>() {
366    
367                public Iterator<VertexType> iterator() {
368                    final Iterator<EdgeType> ei = lightEdgeIterator(vertex);
369                    return new Iterator<VertexType>() {
370                        public boolean hasNext() {
371                            return ei.hasNext();
372                        }
373    
374                        public VertexType next() {
375                            EdgeType edg = ei.next();
376                            if (edg.source == vertex)
377                                return edg.target;
378                            else
379                                return edg.source;
380                        }
381    
382                        public void remove() {
383                            ei.remove();
384                        }
385                    };
386                }
387            };
388        }
389    
390    
391        /**
392         * Its the same as edges
393         */
394        public Iterable<EdgeType> getEdges() {
395            return edges();
396        }
397    
398        /**
399         * @return an Iterable which can iterated on all vertices of graph
400         */
401        public Iterable<VertexType> vertices() {
402            return this;
403        }
404    }