2012-10-04 18 views
9

私は隣接リストでグラフを作成しようとしています。つまり、すべてのノードのリストが必要です。また、すべてのノードクラス内に、すべての隣接ノードを保持するデータ構造も必要です。これを行うための最良の構造(ターゲットノードクラスの高速検索)が何であるか不思議です。アレイは動作するでしょうか?隣接リストとグラフ

+2

Ruby言語ではなく特殊なデータ構造のほとんどの場合のためのハッシュと配列の重使用のために知られています。 Rubyはプログラマーの生産性を優先するので、ハッシュや配列には豊富な機能があるため、開発者は常にそれらを使用できます。あなたの場合、私は配列がうまくいくと思います。 – Valentin

+1

RubyなどのOOP言語では、グラフ内の各ノードを同じタイプの他のオブジェクトへの参照としてそのエッジを維持するオブジェクトとして表現することを検討してください。 –

答えて

23

Rubyで有向グラフを作成する方法の1つで、各ノードは後継ノードへの参照を保持しますが、ノードは名前で参照できます。まず、ノードのクラスが必要です。

class Node 

    attr_reader :name 

    def initialize(name) 
    @name = name 
    @successors = [] 
    end 

    def add_edge(successor) 
    @successors << successor 
    end 

    def to_s 
    "#{@name} -> [#{@successors.map(&:name).join(' ')}]" 
    end 

end 

各ノードは、後継ノードへの参照を保持しています。どのような操作が必要なのかわからないので、実際にグラフを横断するものは定義していませんが、後続ノードへの参照を持つ各ノードはグラフを横断することを簡単にします。

今、私たちは、グラフ全体を表すクラスを作成します:

class Graph 

    def initialize 
    @nodes = {} 
    end 

    def add_node(node) 
    @nodes[node.name] = node 
    end 

    def add_edge(predecessor_name, successor_name) 
    @nodes[predecessor_name].add_edge(@nodes[successor_name]) 
    end 

    def [](name) 
    @nodes[name] 
    end 

end 

このクラスは、名前をキーと、そのノードのハッシュを保持します。これにより、特定のノードの検索が容易になります。ここ

サイクルを含むグラフの一例は次のとおり

graph = Graph.new 
graph.add_node(Node.new(:a)) 
graph.add_node(Node.new(:b)) 
graph.add_node(Node.new(:c)) 
graph.add_edge(:a, :b) 
graph.add_edge(:b, :c) 
graph.add_edge(:c, :a) 
puts graph[:a] #=> a -> [b] 
puts graph[:b] #=> b -> [c] 
puts graph[:c] #=> c -> [a] 
関連する問題