web-dev-qa-db-ja.com

隣接行列の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;
}
8
TJain

キューをポップした後に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++;
        }
    }
}
4
Jonathan Darryl

答えを磨くのに役立ついくつかの質問があります。しかし、あなたが取り戻すカウントの詳細を共有してください。注目すべき点は次のとおりです。

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