Проблема здесь в том, что вы используете рекурсию, и она становится глубокой для сложных графов.Для каждой рекурсии стек должен быть увеличен для хранения значения результата.Чтобы решить эту проблему, вы можете сделать две вещи: перейти на цикл или переписать рекурсию, оптимизированную с помощью хвостового вызова, и включить оптимизацию хвостового вызова для ruby (для некоторых объяснений посмотрите здесь: http://nithinbekal.com/posts/ruby-tco/).
IЯ сделал небольшую версию, которая использует цикл while. Надеюсь, это поможет ...
class Edge
attr_reader :left, :right
def initialize(left, right)
@left, @right = left, right
end
def vertexes
[left, right]
end
end
class Graph
attr_reader :vertexes, :edges
def initialize(vertexes, edges)
@vertexes, @edges = vertexes, edges
end
def add_edges(new_edges)
new_edges.each { |edge| add_edge(edge) }
end
def add_edge(edge)
add_vertex(edge.left)
add_vertex(edge.right)
@edges << edge
@edges.uniq!
edge
end
def add_vertex(vertex)
@vertexes << vertex
@vertexes.uniq!
vertex
end
def edges_for(vertex)
edges.select { |edge| edge.left == vertex || edge.right == vertex }
end
end
module DFS
def self.components(graph)
vertexes = graph.vertexes.clone
graph.vertexes.map do |vertex|
next unless vertexes.delete(vertex)
component = Graph.new([vertex], [])
edges = graph.edges_for(vertex)
while (new_vertexes = edges.map(&:vertexes).flatten & vertexes).any? do
component.add_edges(edges)
edges = new_vertexes.map { |new_vertex| graph.edges_for(new_vertex) }.flatten
vertexes -= new_vertexes
end
component.add_edges(edges)
component
end.compact
end
end