lib/rgl/adjacency.rb in rgl-0.5.9 vs lib/rgl/adjacency.rb in rgl-0.5.10

- old
+ new

@@ -1,46 +1,43 @@ # adjacency.rb # -# $Id$ -# -# The DirectedAdjacencyGraph class implements a generalized adjacency list -# graph structure. An AdjacencyGraph is basically a two-dimensional structure -# (ie, a list of lists). Each element of the first dimension represents a -# vertex. Each of the vertices contains a one-dimensional structure that is -# the list of all adjacent vertices. -# -# The class for representing the adjacency list of a vertex is, by default, a -# Set. This can be configured by the client, however, when an AdjacencyGraph -# is created. - require 'rgl/mutable' require 'set' module RGL + # The +DirectedAdjacencyGraph+ class implements a generalized adjacency list + # graph structure. An AdjacencyGraph is basically a two-dimensional structure + # (ie, a list of lists). Each element of the first dimension represents a + # vertex. Each of the vertices contains a one-dimensional structure that is + # the list of all adjacent vertices. + # + # The class for representing the adjacency list of a vertex is, by default, a + # +Set+. This can be configured by the client, however, when an AdjacencyGraph + # is created. class DirectedAdjacencyGraph include MutableGraph - # Shortcut for creating a DirectedAdjacencyGraph: + # Shortcut for creating a DirectedAdjacencyGraph + # @example + # RGL::DirectedAdjacencyGraph[1,2, 2,3, 2,4, 4,5].edges.to_a.to_s => + # "(1-2)(2-3)(2-4)(4-5)" # - # RGL::DirectedAdjacencyGraph[1,2, 2,3, 2,4, 4,5].edges.to_a.to_s => - # "(1-2)(2-3)(2-4)(4-5)" - # def self.[](*a) result = new 0.step(a.size - 1, 2) { |i| result.add_edge(a[i], a[i + 1]) } result end - # Returns a new empty DirectedAdjacencyGraph which has as its edgelist - # class the given class. The default edgelist class is Set, to ensure - # set semantics for edges and vertices. + # The new empty graph has as its edgelist class the given class. The default + # edgelist class is Set, to ensure set semantics for edges and vertices. # # If other graphs are passed as parameters their vertices and edges are # added to the new graph. - # + # @param [Class] edgelist_class + # @param [Array[Graph]] other_graphs def initialize(edgelist_class = Set, *other_graphs) @edgelist_class = edgelist_class @vertices_dict = Hash.new other_graphs.each do |g| g.each_vertex { |v| add_vertex v } @@ -56,79 +53,73 @@ @vertices_dict[v] = @vertices_dict[v].dup end end # Iterator for the keys of the vertices list hash. - # + # @see Graph#each_vertex def each_vertex(&b) @vertices_dict.each_key(&b) end - def each_adjacent(v, &b) # :nodoc: + # @see Graph#each_adjacent + def each_adjacent(v, &b) adjacency_list = (@vertices_dict[v] or raise NoVertexError, "No vertex #{v}.") adjacency_list.each(&b) end - # Returns true. + # @return true. # def directed? true end - # Complexity is O(1), because the vertices are kept in a Hash containing + # Complexity is O(1), because the vertices are kept in a +Hash+ containing # as values the lists of adjacent vertices of _v_. # + # @see Graph#has_vertex def has_vertex?(v) @vertices_dict.has_key?(v) end # Complexity is O(1), if a Set is used as adjacency list. Otherwise, # complexity is O(out_degree(v)). - # - # --- - # MutableGraph interface. - # + # @see Graph#has_edge? def has_edge?(u, v) has_vertex?(u) && @vertices_dict[u].include?(v) end - # See MutableGraph#add_vertex. - # - # If the vertex is already in the graph (using eql?), the method does + # If the vertex is already in the graph (using +eql?+), the method does # nothing. - # + # @see MutableGraph#add_vertex def add_vertex(v) @vertices_dict[v] ||= @edgelist_class.new end - # See MutableGraph#add_edge. - # + # @see MutableGraph#add_edge. def add_edge(u, v) add_vertex(u) # ensure key add_vertex(v) # ensure key basic_add_edge(u, v) end - # See MutableGraph#remove_vertex. - # + # @see MutableGraph#remove_vertex. def remove_vertex(v) @vertices_dict.delete(v) # remove v from all adjacency lists @vertices_dict.each_value { |adjList| adjList.delete(v) } end - # See MutableGraph::remove_edge. - # + # @see MutableGraph::remove_edge. def remove_edge(u, v) @vertices_dict[u].delete(v) unless @vertices_dict[u].nil? end - # Converts the adjacency list of each vertex to be of type _klass_. The + # Converts the adjacency list of each vertex to be of type +klass+. The # class is expected to have a new constructor which accepts an enumerable as # parameter. - # + # @param [Class] klass def edgelist_class=(klass) @vertices_dict.keys.each do |v| @vertices_dict[v] = klass.new @vertices_dict[v].to_a end end @@ -139,24 +130,25 @@ @vertices_dict[u].add(v) end end # class DirectedAdjacencyGraph - # AdjacencyGraph is an undirected Graph. The methods add_edge and - # remove_edge are reimplemented: if an edge (u,v) is added or removed, - # then the reverse edge (v,u) is also added or removed. + # AdjacencyGraph is an undirected Graph. The methods + # {DirectedAdjacencyGraph#add_edge} and {DirectedAdjacencyGraph#remove_edge} + # are reimplemented: if an edge (u,v) is added or removed, then the reverse + # edge (v,u) is also added or removed. # class AdjacencyGraph < DirectedAdjacencyGraph - # Always returns false. + # @return false. # def directed? false end # Also removes (v,u) - # + # @see DirectedAdjacencyGraph#remove_edge def remove_edge(u, v) super @vertices_dict[v].delete(u) unless @vertices_dict[v].nil? end @@ -170,12 +162,12 @@ end # class AdjacencyGraph module Graph # Convert a general graph to an AdjacencyGraph. If the graph is directed, - # returns a DirectedAdjacencyGraph; otherwise, returns an AdjacencyGraph. - # + # returns a {DirectedAdjacencyGraph}; otherwise, returns an {AdjacencyGraph}. + # @return {DirectedAdjacencyGraph} or {AdjacencyGraph} def to_adjacency result = (directed? ? DirectedAdjacencyGraph : AdjacencyGraph).new each_vertex { |v| result.add_vertex(v) } each_edge { |u, v| result.add_edge(u, v) } result @@ -183,24 +175,24 @@ # Return a new DirectedAdjacencyGraph which has the same set of vertices. # If (u,v) is an edge of the graph, then (v,u) is an edge of the result. # # If the graph is undirected, the result is self. - # + # @return [DirectedAdjacencyGraph] def reverse return self unless directed? result = DirectedAdjacencyGraph.new each_vertex { |v| result.add_vertex v } each_edge { |u, v| result.add_edge(v, u) } result end - # Return a new AdjacencyGraph which has the same set of vertices. If (u,v) + # Return a new {AdjacencyGraph} which has the same set of vertices. If (u,v) # is an edge of the graph, then (u,v) and (v,u) (which are the same edges) # are edges of the result. # - # If the graph is undirected, the result is self. - # + # If the graph is undirected, the result is +self+. + # @return [AdjacencyGraph] def to_undirected return self unless directed? AdjacencyGraph.new(Set, self) end