# mutable.rb require 'rgl/base' module RGL # A MutableGraph can be changed via the addition or removal of edges and # vertices. # module MutableGraph include Graph # Add a new vertex _v_ to the graph. If the vertex is already in the # graph (tested via eql?), the method does nothing. # def add_vertex(v) raise NotImplementedError end # Inserts the edge (u,v) into the graph. # # Note that for undirected graphs, (u,v) is the same edge as (v,u), so # after a call to the function #add_edge, this implies that edge (u,v) # will appear in the out-edges of u and (u,v) (or equivalently (v,u)) # will appear in the out-edges of v. Put another way, v will be adjacent # to u and u will be adjacent to v. # def add_edge(u, v) raise NotImplementedError end # Add all objects in _a_ to the vertex set. # def add_vertices(*a) a.each { |v| add_vertex v } end # Add all edges in the _edges_ array to the edge set. Elements of the # array can be both two-element arrays or instances of {Edge::DirectedEdge} or # {Edge::UnDirectedEdge}. # def add_edges(*edges) edges.each { |edge| add_edge(edge[0], edge[1]) } end # Remove u from the vertex set of the graph. All edges whose target is # _v_ are also removed from the edge set of the graph. # # Postcondition: num_vertices is one less, _v_ no longer appears in the # vertex set of the graph, and there no edge with source or target _v_. # def remove_vertex(v) raise NotImplementedError end # Remove the edge (u,v) from the graph. If the graph allows parallel # edges, this removes all occurrences of (u,v). # # Precondition: u and v are vertices in the graph. # Postcondition: (u,v) is no longer in the edge set for g. # def remove_edge(u, v) raise NotImplementedError end # Remove all vertices specified by the array a from the graph by calling # {#remove_vertex}. # def remove_vertices(*a) a.each { |v| remove_vertex v } end # Returns all minimum cycles that pass through a give vertex. # The format is an Array of cycles, with each cycle being an Array # of vertices in the cycle. # @return [Array[Array]] def cycles_with_vertex(vertex) cycles_with_vertex_helper(vertex, vertex, []) end protected def cycles_with_vertex_helper(vertex, start, visited) adjacent_vertices(start).reject { |x| visited.include?(x) }.inject([]) do |acc, adj| local_visited = Array.new(visited) << adj acc << local_visited if (adj==vertex) acc = acc + cycles_with_vertex_helper(vertex, adj, local_visited) end end public # @return [Array] of all minimum cycles in a graph # # This is not an efficient implementation O(n^4) and could # be done using Minimum Spanning Trees. Hint. Hint. # def cycles g = self.clone self.inject([]) do |acc, v| acc = acc.concat(g.cycles_with_vertex(v)) g.remove_vertex(v); acc end end end # module MutableGraph end # module RGL