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 }