Reputation: 2382
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
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