sdgaw erzswer
sdgaw erzswer

Reputation: 2382

C++ iterating over vector copy

I am trying to implement the Bron-Kerbosch's algorithm, which is a recursive algorithm for clique finding. I managed to get to a point, where it returns the correct number of cliques, yet when I print them, they are not correct - additional nodes are added. Am I missing something obvious here?

I am using adjacency list structure:

vector< list<int> > adjacency_list;

where I add edges the following way:

void graph::addEdge(int i1,int i2){

  //as this is an undirected graph  
  adjacency_list[i1].push_back(i2);
  adjacency_list[i2].push_back(i1);

}

Main algorithm is the following:

void graph::BronKerbosch(vector<int> R, vector<int> P, vector<int> X){

  if (P.empty() && X.empty()){
    result_cliques.insert(R);
  }

  //  vector <int> tmpVerts = P;
  for(std::vector<int>::iterator it = P.begin(); it != P.end();) {

    vector<int> intersection = {}, intersectionX = {};
    int node = *it;

    //N(P)
    for (int nodeP : adjacency_list[node]){
      for (int node2 : P){
        if (nodeP == node2){
          intersection.push_back(nodeP);
        }   
      }

      //N(X)
      for (int node3 : X){
        if (nodeP == node3){
          intersectionX.push_back(nodeP);
        }
      }
    }

    R.push_back(node);
    BronKerbosch(R,intersection,intersectionX);

    //P.erase(remove(P.begin(),P.end(),node),P.end());
    P.erase(it); 
    X.push_back(node);

  }
}

And I run it within:

void graph::run_BronKerbosch(){

  vector<int> R,P,X;

  for (int i=1; i < adjacency_list.size(); i++) {
    P.push_back(i);
  }

  BronKerbosch(R,P,X);

  cout << "................\nClassic: " << result_cliques.size() << endl;
  for (auto clique : result_cliques){
    cout << "(";
    for (int node : clique){
      cout << node <<" ";
    }    
    cout << ")\n";    
  } 

}

The output problem for the following graph input:

1 2
1 3
2 3

is, that this code returns:

(1 2 3 )
(1 2 3 4 )
(1 2 3 4 5 )

whereas it should return (used python for this):

(1 2 3 )
(2 4 )
(2 5 )

Thank you very much for any help.

Upvotes: 2

Views: 112

Answers (1)

danbanica
danbanica

Reputation: 3038

In the wikipedia page, the recursive call looks like this:

for each vertex v in P:
    BronKerbosch1(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
    ...

In the code from the question, you do a R.push_back(node) before the recursive call, but that node will be included in R in all subsequent iterations of the loop, which is not correct.

That is, the following instructions:

R.push_back(node);
BronKerbosch(R,intersection,intersectionX);

should probably be followed by a R.pop_back(node) immediately after the recursive call.

Upvotes: 1

Related Questions