/*
bool isperfect(unsigned __int64 Ne[], int N=-1, ...)
Function isperfect returns boolean value 'true' if input graph is a perfect graph and 'false' otherwise.
The input graph with N<=64 nodes, expressed as a bitwise neighbor node lists. Each set bit in Ne[n] indicates
that the corresponding graph node is a neighbor. For example, if the ith bit of Ne[n] is set, graph node i is
a neighbor of graph node n. The nth bit of Ne[n] cannot be set, i.e. Ne[0]&0x0001 = 0 and Ne[1]&0x0002 = 0.
Ne must be 64-bit unsigned integers. The length of Ne, N, can be surmised by checking for zero termination
(if input parameter N=0) or for connected graphs, by looking at the maximal neighbor index (if the input
parameter N=-1 or N is blank).
Copyright 2010 by Delbert Dueck <deldueck@gmail.com>, Columbia University Department of Computer Science
*/
bool isperfect(unsigned __int64
*Ne, int N=-1
/* parameters for internal use only */, int va=-1,
unsigned __int64 v_=0, int
vy=-1, int vz=-1, int vn=0) {
unsigned __int64 ne, vs, vt;
int n, v;
if (N<=0) { /*
first [outside] call of function; determine graph length, N */
if (N==-1) {N=5;
for (n=0,ne=0; n
if (N==0) ffor (N=0; N<64 && Ne[N]; N++);
/* zero-terminated array; useful for disconnected graphs */
for (n=0; n<N; n++) Ne[n] &= (~((span class="keywordstyle">unsigned __int64)1<<n));
/* remove any self-links (invalid format) */
if (!(isperfect(Ne,N,-1,0,-1,-1,0)))
return (false);
/* test graph */
for (n=0; n<N; n++) Ne[n] ^= (0xffffffffffffffff>>(64-N));
/* complement graph (invalid format) */
for (n=0; n<N; n++) Ne[n] &= (~((unsigned __int64)1<<n));
/* remove any self-links */
if (!(isperfect(Ne,N,-1,0,-1,-1,0))) return (false); else
return (true);
/* test graph complement */
}
if (vn==1 && va==-1 && vy==-1 && vz!=-1) va=vz;
/* quick fix for array indexing/labelling problem */
if (vn==0) vs=(0xffffffffffffffff>>(64-N));
else vs=Ne[vz];
for (v=0; v<N; v++) {
if (!(((unsigned __int64)1<<v)&vs))
continue; /* enforce for v=vs loop */
if (vn>=2) {if (v==vy)
continue;} /* don't backtrack for path */
if (vn>=3) {vt = (v_-((unsigned __int64)1<<va)-((unsigned __int64)1<<vz)); if (Ne[v] & vt)
continue;}
/* chord encountered */
if (vn>=2) {
/* chordless path at least three long encountered */
if
(Ne[v] & ((unsigned __int64)1<<va)) {
/* hole or 3-clique encountered */
if
(vn+1>=5 && ((vn+1)&1)) return (false);
/* odd hole encountered */
continue;
}
}
if (vn<=((N-1)|1))
if (!isperfect(Ne,N,va,(v_|((unsigned __int64)1<<v)),vz,v,vn+1))
return (false);
/* recursion call */
}
return (true);
/* no odd holes encountered */
}