implemented cliques in a graph
This commit is contained in:
parent
6fad3847cf
commit
9d51ef6fbd
1
.gitignore
vendored
1
.gitignore
vendored
@ -52,6 +52,7 @@ libla.la
|
||||
version.cc
|
||||
t
|
||||
test
|
||||
fi
|
||||
tX
|
||||
*.tar.bz2
|
||||
.*.swp
|
||||
|
128
graph.cc
128
graph.cc
@ -24,7 +24,133 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
|
||||
namespace LA {
|
||||
|
||||
template<typename G>
|
||||
NRVec<int> neighbors(const G &adjacency, const int v)
|
||||
{
|
||||
if(v<0||v>=adjacency.nrows()) laerror("invalid vertex number in neighbors");
|
||||
int n=0;
|
||||
for(int i=0; i<adjacency.nrows(); ++i) if(adjacency(v,i) && v!=i) ++n;
|
||||
int ii=0;
|
||||
NRVec<int> r(n);
|
||||
for(int i=0; i<adjacency.nrows(); ++i) if(adjacency(v,i) && v!=i) r[ii++]=i;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename G>
|
||||
NRVec<int> nonneighbors(const G &adjacency, const int v)
|
||||
{
|
||||
if(v<0||v>=adjacency.nrows()) laerror("invalid vertex number in nonneighbors");
|
||||
int n=0;
|
||||
for(int i=0; i<adjacency.nrows(); ++i) if(!adjacency(v,i) && v!=i) ++n;
|
||||
int ii=0;
|
||||
NRVec<int> r(n);
|
||||
for(int i=0; i<adjacency.nrows(); ++i) if(!adjacency(v,i) && v!=i) r[ii++]=i;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//heuristic algorithm by Boppana and Halldorsson, BIT 32, 180, (1992)
|
||||
template<typename G>
|
||||
NRVec<int> findclique(const G &adjacency, const int v)
|
||||
{
|
||||
NRVec<int> r(0);
|
||||
if(adjacency.nrows())
|
||||
{
|
||||
if(v<0||v>=adjacency.nrows()) laerror("invalid vertex number in findclique");
|
||||
NRVec<int> neighb = neighbors(adjacency,v);
|
||||
NRVec<int> nonneighb = nonneighbors(adjacency,v);
|
||||
NRVec<int> c1(0),c2(0);
|
||||
if(neighb.size())
|
||||
{
|
||||
G subg1 = adjacency.submatrix(neighb);
|
||||
c1 = findclique(subg1);
|
||||
//reindex to original graph
|
||||
for(int i=0; i<c1.size(); ++i) c1[i] = neighb[c1[i]];
|
||||
}
|
||||
if(nonneighb.size())
|
||||
{
|
||||
G subg2 = adjacency.submatrix(nonneighb);
|
||||
c2 = findclique(subg2);
|
||||
//reindex to original graph
|
||||
for(int i=0; i<c2.size(); ++i) c2[i] = nonneighb[c2[i]];
|
||||
}
|
||||
c1.append(v);
|
||||
c1.sort();
|
||||
c2.sort();
|
||||
if(c1.size()>=c2.size()) r=c1; else r=c2;
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
|
||||
|
||||
template<typename G>
|
||||
NRVec<int> complement(const G &adjacency, const NRVec<int> & vertexlist)
|
||||
{
|
||||
int n=adjacency.nrows();
|
||||
NRVec<char> occ(n);
|
||||
occ.clear();
|
||||
for(int i=0; i<vertexlist.size(); ++i)
|
||||
{
|
||||
if(vertexlist[i]<0||vertexlist[i]>=n) laerror("illegal vertex in complement");
|
||||
occ[vertexlist[i]]=1;
|
||||
}
|
||||
int m=0;
|
||||
for(int i=0; i<n; ++i) if(!occ[i]) ++m;
|
||||
NRVec<int> r(m);
|
||||
m=0;
|
||||
for(int i=0; i<n; ++i) if(!occ[i]) r[m++]=i;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//found cliques releatedly until the whole graph is covered
|
||||
//could be recursive but we made it iterative
|
||||
template<typename G>
|
||||
NRVec<int> cliquecover(const G &adjacency)
|
||||
{
|
||||
int n=adjacency.nrows();
|
||||
NRVec<int> r(n); r.clear();
|
||||
G graph = adjacency;
|
||||
int cliquenumber=1;
|
||||
int remaining=n;
|
||||
NRVec<int> cliques(0);
|
||||
NRVec<int> notincliques(n);
|
||||
for(int i=0; i<n; ++i) notincliques[i]=i;
|
||||
while(remaining)
|
||||
{
|
||||
NRVec<int> clique = findclique(graph);
|
||||
NRVec<int> cliqueorignum(clique.size());
|
||||
for(int i=0; i<clique.size(); ++i) cliqueorignum[i] = notincliques[clique[i]];
|
||||
cliques.concatme(cliqueorignum);
|
||||
for(int i=0; i<clique.size(); ++i) r[cliqueorignum[i]] = cliquenumber;
|
||||
++cliquenumber;
|
||||
notincliques = complement(adjacency,cliques);
|
||||
remaining=notincliques.size();
|
||||
if(remaining)
|
||||
{
|
||||
graph= adjacency.submatrix(notincliques);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
//force instantization
|
||||
#define INSTANTIZE(T) \
|
||||
template NRVec<int> neighbors(const NRSMat<T> &adjacency, const int v); \
|
||||
template NRVec<int> nonneighbors(const NRSMat<T> &adjacency, const int v); \
|
||||
template NRVec<int> findclique(const NRSMat<T> &adjacency, const int v); \
|
||||
template NRVec<int> complement(const NRSMat<T> &adjacency, const NRVec<int> & vertexlist); \
|
||||
template NRVec<int> cliquecover(const NRSMat<T> &adjacency); \
|
||||
|
||||
|
||||
|
||||
INSTANTIZE(char)
|
||||
|
||||
}//namespace
|
||||
|
17
graph.h
17
graph.h
@ -30,6 +30,23 @@
|
||||
|
||||
namespace LA {
|
||||
|
||||
//presently I am not sure what the best general class for a graph would be, so leave it purely templated algorithms
|
||||
//where the class G is adjacency supporting operator() and submatrix() operations
|
||||
|
||||
template<typename G>
|
||||
NRVec<int> neighbors(const G &adjacency, const int v);
|
||||
|
||||
template<typename G>
|
||||
NRVec<int> nonneighbors(const G &adjacency, const int v);
|
||||
|
||||
template<typename G>
|
||||
NRVec<int> findclique(const G &adjacency, const int v=0);
|
||||
|
||||
template<typename G>
|
||||
NRVec<int> complement(const G &adjacency, const NRVec<int> & vertexlist);
|
||||
|
||||
template<typename G>
|
||||
NRVec<int> cliquecover(const G &adjacency);
|
||||
|
||||
|
||||
|
||||
|
22
t.cc
22
t.cc
@ -26,6 +26,8 @@
|
||||
#include "polynomial.h"
|
||||
#include "contfrac.h"
|
||||
#include "simple.h"
|
||||
#include "graph.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace LA_Vecmat3;
|
||||
@ -1954,7 +1956,7 @@ cin >>v;
|
||||
cout <<v;
|
||||
}
|
||||
|
||||
if(1)
|
||||
if(0)
|
||||
{
|
||||
Quaternion<double> v,r,tmp,q,q1;
|
||||
cin >>q;
|
||||
@ -2746,5 +2748,23 @@ if(0)
|
||||
laerror("test exception");
|
||||
}
|
||||
|
||||
if(1)
|
||||
{
|
||||
NRSMat<char> adj;
|
||||
cin >>adj;
|
||||
NRVec<int> clique = findclique(adj);
|
||||
cout <<"First clique is "<<clique<<endl;
|
||||
cout <<"Check adjacency of the clique: "<<adj.submatrix(clique)<<endl;
|
||||
NRVec<int> cover = cliquecover(adj);
|
||||
cout <<"Clique cover is "<<cover<<endl;
|
||||
NRPerm<int> p(cover.size());
|
||||
cover.sort(0,p);
|
||||
cout<<"permutation to disentabgle the cliques = "<<p<<endl;
|
||||
NRVec<int> perm1(p.size());
|
||||
for(int i=0; i<p.size(); ++i) perm1[i] = p[i+1]-1;
|
||||
NRSMat<char> adjperm = adj.submatrix(perm1);
|
||||
cout <<"resorted graph = "<<adjperm<<endl;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user