web-dev-qa-db-ja.com

オブジェクトグラフ表現と隣接リストおよびマトリックス表現の比較

現在、技術プログラミングインタビューの準備に関するSteve Yeggeのアドバイスに従っています。 http://steve-yegge.blogspot.com/2008/03/get-that-job-at-google.html

グラフに関するセクションで、彼は次のように述べています。

メモリ内のグラフを表す3つの基本的な方法(オブジェクトとポインター、マトリックス、隣接リスト)があり、各表現とその長所と短所をよく理解する必要があります。

マトリックスと隣接リストの表現の長所と短所はCLRSで説明されていますが、これらをオブジェクト表現と比較するリソースを見つけることができませんでした。

それについて考えるだけで、このことのいくつかを自分で推測することができますが、何か重要なことを見逃していないことを確認したいと思います。誰かがこれを包括的に説明したり、そうするリソースを教えてくれたりしたら、とても感謝しています。

78
jbeard4

オブジェクトとポインター

これらは、他の回答で述べたhammarのような基本的なデータ構造にすぎません。Javaでは、これをエッジや頂点などのクラスで表します。たとえば、エッジは2つの頂点を接続し、有向または無向のいずれかで、ウェイトを含めることができます。頂点はID、名前などを持つことができます。ほとんどの場合、両方に追加のプロパティがあります。したがって、次のようにグラフを作成できます

Vertex a = new Vertex(1);
Vertex b = new Vertex(2);
Edge edge = new Edge(a,b, 30); // init an Edge between ab and be with weight 30  

このアプローチは、オブジェクト指向のユーザーにとって読みやすく便利なため、オブジェクト指向の実装によく使用されます;)。

マトリックス

マトリックスは、単純な2次元配列です。次のようなint配列として表現できる頂点IDがあると仮定します。

int[][] adjacencyMatrix = new int[SIZE][SIZE]; // SIZE is the number of vertices in our graph
adjacencyMatrix[0][1] = 30; // sets the weight of a vertex 0 that is adjacent to vertex 1

これは通常、インデックスアクセスが必要な密なグラフに使用されます。これにより、非/有向および重み付けされた構造を表すことができます。

隣接リスト

これは単純なデータ構造のミックスであり、通常はHashMap<Vertex, List<Vertex>>。同様に、グアバのHashMultimapを使用できます。

O(1)(償却済み)頂点ルックアップがあり、私が要求したこの特定の頂点に隣接するすべての頂点のリストを返します。

ArrayList<Vertex> list = new ArrayList<>();
list.add(new Vertex(2));
list.add(new Vertex(3));
map.put(new Vertex(1), list); // vertex 1 is adjacent to 2 and 3

これは、スパースグラフの表現に使用されます。Googleで申請している場合、ウェブグラフがスパースであることを知っておく必要があります。 BigTable を使用すると、よりスケーラブルな方法でそれらに対処できます。

ああ、ところで、 ここ は、この投稿の素晴らしい写真の要約です;)

89
Thomas Jungblut

少なくともこれらの表現を使用するアルゴリズムを比較する目的では、オブジェクトとポインターはほとんど隣接リストと同じです。

比較する

struct Node {
    Node *neighbours[];
};

struct Node {
    Node *left;
    Node *right;
};

後者の場合、名前付きポインターよりも作業が簡単な場合は、その場で隣人のリストを簡単に作成できます。

7
hammar

オブジェクト表現( incidence list )の利点は、2つの隣接する頂点が同じEdgeインスタンスを共有することです。これにより、無向のエッジデータ(長さ、コスト、フロー、さらには方向)を簡単に操作できます。ただし、ポインターに余分なメモリを使用します。

4

別の優れたリソース: Khan Academy-"Representing Graphs"

隣接リストと隣接マトリックスに加えて、3番目のタイプのグラフ表現として「エッジリスト」をリストします。エッジリストは、トーマスの「オブジェクトとポインター」の回答にあるような「エッジオブジェクト」のリストとして解釈できます。

利点:Edgeに関する詳細情報を保存できます(Michalが言及)

短所:使用するには非常に遅いデータ構造です。

  • エッジのルックアップ:O(log e)
  • エッジを削除する:O(e)
  • 特定のノードに隣接するすべてのノードを検索します:O(e)
  • 2つのノード間にパスがあるかどうかを判別します:O(e ^ 2)

e =エッジの数

1
Chris Leung