Как создать полный график в ruby

#ruby-on-rails #ruby #graph

#ruby-on-rails #ruby #График

Вопрос:

Я только начал с Ruby и создал график, используя два класса, один из которых является классом node, а другой — классом graph, и теперь я хочу написать функцию genCompleteGraph(n), которая принимает положительное целое число n и возвращает полный график на n узлах, но я застрял в нем ине нашел много ресурсов для этого, может ли кто-нибудь помочь мне в этом, вот мой код:

 class Node
  extend Forwardable
  include Enumerable
  attr_reader :label, :adj, :id
  def_delegators :@adj, :<<, :size, :each, :[]
  def_delegators :@label, :to_s
  def initialize(label)
    @label = label.to_sym
    @adj = []
    @id = self.class.count
  end
  def add_edge(n)
    adj << n
  end
  def remove_edge(n)
    adj.delete(n)
  end
  def degree
    adj.size
  end
  def inspect
    to_s
  end
  @count = 0
  class << self
    def count
      @count  = 1
      @count
    end
  end
end
class Graph
  attr_reader :nodes, :edges
  def initialize
    @nodes = {}
    @edges = {}
  end
  def get_nodes
    nodes.keys
  end
  def get_edges
    edges.keys
  end
  def node(s)
    s = s.to_sym
    nodes.fetch(s, false)
  end
  def edge(s1, s2)
    n1 = node(s1)
    n2 = node(s2)
    if n1 and n2 then
      edge_from_nodes(n1, n2)
    else
      false
    end
  end
  def add_node(s)
    s = s.to_sym
    if nodes.has_key?(s) then return end
    n = Node.new(s)
    nodes[s] = n
  end
  def add_nodes(ss)
    ss.each {|s| add_node(s)}
  end

  def add_edge(s1, s2)
    n1 = node(s1)
    n2 = node(s2)
    if n1 and n2 then
      e = edge_from_nodes(n1, n2)
      if not edges.has_key?(e) then
        n1.add_edge(n2)
        n2.add_edge(n1)
        edges[e] = {}
        return e
      end
    end
  end
  def remove_edge(s1, s2)
    n1 = node(s1)
    n2 = node(s2)
    if n1 and n2 then
      n1.remove_edge(n2)
      n2.remove_edge(n1)
      edges.delete(edge(n1, n2))
    end
  end
  def nbr_nodes
    nodes.size
  end
  def nbr_edges
    edges.size
  end
  def to_s
    res = ''
    nodes.values.each do |node|
      adjs = node.map(amp;:to_s).join(',')
      if adjs.size > 0 then
        res  = "#{node} -> #{adjs}n"
      else
        res  = "#{node}n"
      end
    end
    res
  end
  def inspect
    "<Graph: #{nbr_nodes}, #{nbr_edges}>"
  end
  private
  def edge_from_nodes(n1, n2)
    [n1, n2].sort {|a,b| a.id <=> b.id}
  end
end
  

И результат, который я пытаюсь получить, выглядит так:

 >> c3 = genCompleteGraph(3)
=> <Graph: 3, 3>
>> c3.get_nodes
=> [:v0, :v1, :v2]
>> c3.get_edges
=> [[v0, v1], [v0, v2], [v1, v2]]
>> c5 = genCompleteGraph(5)
=> <Graph: 5, 10>
>> c5.get_nodes
=> [:v0, :v1, :v2, :v3, :v4]
>> c5.get_edges
=> [[v0, v1], [v0, v2], [v0, v3], [v0, v4], [v1, v2], [v1, v3], [v1, v4],
 [v2, v3], [v2, v4], [v3, v4]]
  

Ответ №1:

 
def genCompleteGraph(n)
  g = Graph.new
  n.times do |i|
    idx = :"v#{i}"
    Node.new(idx)
    g.add_node(idx)
    i.times do |j|
      g.add_edge(:"v#{j}", idx)
    end
  end
  g
end
  
 [30] pry(main)> g = genCompleteGraph(3)
=> <Graph: 3, 3>
[31] pry(main)> g.nodes
=> {:v0=>v0, :v1=>v1, :v2=>v2}
[32] pry(main)> g.get_nodes
=> [:v0, :v1, :v2]
[33] pry(main)> g.get_edges
=> [[v0, v1], [v0, v2], [v1, v2]]
[34] pry(main)> g = genCompleteGraph(5)
=> <Graph: 5, 10>
[35] pry(main)> g.get_nodes
=> [:v0, :v1, :v2, :v3, :v4]
[36] pry(main)> g.get_edges
=> [[v0, v1], [v0, v2], [v1, v2], [v0, v3], [v1, v3], [v2, v3], [v0, v4], [v1, v4], [v2, v4], [v3, v4]]