2016-04-27 10 views
1

私は、ノードの数を返す無向グラフの隣接行列にBFSを実装しようとしています。私はこれまでこれまで考え出してきましたが、トップ/訪問先のノードをプリントアウトしたときと同じではないと思います。ソートされていないだけでなく、いくつかのノードが複数回出現しています。私はどこかでBFSがトポロジカルな並べ替えであり、私が得た順序はソートされていないと読んだ。隣接行列のBFS

int BFS(std::vector<std::vector<int> > &matrix, int start) 
{ 
    std::vector<bool> visited(matrix.size(), false); 
    std::queue<int> Q; 
    Q.push(start); 
    int count = 0; 

    while(! Q.empty()) 
    { 
     int top = Q.front(); Q.pop(); 
     visited[top] = true; count++; 
     for (int i = 0; i < matrix.size(); ++i) 
     { 
      if(matrix[top][i] != 0 && (! visited[i])) 
      { 
       Q.push(i); 
      } 
     } 
    } 
    return count; 
} 
+0

あなたはそれが正しいと思いませんか? – erip

+0

私はちょうどそれを追加する質問を編集していた、あなたはdownvoted。 – TJain

+0

私はdownvoteしませんでした。 :) – erip

答えて

0

答えを磨くのに役立ついくつかの質問があります。しかし、あなたが戻った数について詳しく説明してください。ここでは見ているものがあります:

  • なぜforループ内のカウントをインクリメントしますか?ノードを複数回カウントしている可能性があります。
  • のサイズはすべてのノードを保持するのに十分ではありません。 std::vector<bool> visited(matrix.size(), false);では、matrix.size()は外側のベクトルのサイズのみを返します。つまり、最大で1行分のデータがにあります。にアクセスできます。
  • に使用されるデータ構造には問題があります。ベクトル>またはn * n個の要素を1つのシーケンスに持つ線形化されたベクトルを使用します。単純なベクトルを使用する場合は、にアクセスしてインデックスを検索するときに[i] [j]インデックスを位置にマップする必要があります。。これは大きな問題であり、ノードを正しく追跡することはできません。
  • ソート順はBFSから保証されません。あなた自身を説得するための簡単な反例を作ってください。トポロジカルソートは、BFS(またはDFS)を使用して実行できます。
+0

私は別のバリエーションを試した後にそれを削除するのを忘れてしまったので、その数は誤って残されました。私は今編集して削除しました。 グラフにn個のノードがある場合、隣接行列はn * nになるため、訪問先配列はすべてのノードを保持できます。したがって、訪問されたノードはすべてのノードを処理することができます。 いいえ、常にソートを実行することはできませんが、同じノードを複数回訪問することは想定されていません。私はvisited [top] = trueの後にtopのprint文を追加し、BFSにはないと思うノードの繰り返しを見つけました。 – TJain

+0

重要なポイントが1つありません:visitedの宣言では、サイズをmatrix.size()として指定します。しかし、行列はベクトルのベクトルです。 matrix、size()と言うと、外側ベクトルのサイズが得られます。しかし、訪れた人は潜在的にすべての要素を持つ必要があるかもしれません。 – KalyanS

+0

しかし要素の数=隣接行列であるので外側の行列のサイズ。 – TJain

1

キューをポップした後にvisitedノードをtrueに設定する代わりに、ノードをキューに挿入するときにノードを設定し、いくつかのノードの重複カウントを防ぐためにカウントを追加する必要があります。以下を参照してください:

//..previous lines 

Q.push(start); 
visited[start] = true; 
int count = 1; 

while(!Q.empty()){ 
    int top = Q.front(); Q.pop(); 

    for (int i = 0; i < matrix.size(); ++i){ 
     if(matrix[top][i] != 0 && (! visited[i])){ 
      Q.push(i); 
      visited[i] = true; 
      count++; 
     } 
    } 
} 
+0

私はヒットとトライアルでも答えに達しましたが、基本的にforループは訪問先ノードのすべての近隣ノードを追加するためのものです。 キューから削除しているときにアクセスした場合、またはifを実行するときにキューに追加しないでください。 – TJain

+0

いいえ、それは同じではありません。例:あなたは(1) - >(2)、(3)、(2) - >(3)を持っています。キューをポップするときに++を数えると、(3)ノードは2回カウントされます。 –

関連する問題