/* ** maxc.c */ /* ** April 22, 1998 ** this program implements Algorithm 4.19 ** for solving Problem 4.5 Maximum Clique */ /* ** Compile with: ** gcc -O -c maxc.c ** gcc -O -c setlib0.c ** gcc -O maxc.o setlib0.o -omaxc ** ** or use the makefile with "make maxc" ** ** Run with: ** maxc {NZSG} fname ** ** maxc help ---- for instructions ** ** maxc labels ---- for labels ** ** ** fname is the name of a file that contains a ** list of m edges of the n-element ** vertex set {0,1,2,...,n-1}. ** ** For example here is how the file should look ** like for m=3 edges from the n=6 vertex set ** {0,1,2,3,4,5} ** ** 3 6 ** 1 5 ** 2 3 ** 5 4 ** */ #include #include #include "defs.h" #include "setlib0.h" #define false 0 #define true 1 #define BOUNDSIZE (boundtype?OptSize:OptWeight) #define WHICHBOUND(L,start) (boundtype?BOUND(L,start):WTBOUND(L,start)) typedef set * graph; int NODES; int n; graph A; setlist D,C,B,N; int * X; FILE *f; int * OptClique; int * Color; set Uncolored; set used; setlist ColorClass; int NumColors; int OptSize; int (*BOUND)(); float (*WTBOUND)(); set R,T; char WBOUND[30]; /***** RICHARD STUFF *****/ float* weights; float cliqueWeight; float OptWeight; int boundtype; /***** END RICHARD *****/ void help() { printf("maxc bound sort fname\n"); printf("\n"); printf("fname is the name of a file that\n"); printf("contains a list of m edges of the\n"); printf("n-element vertex set {0,1,2,...,n-1}.\n"); printf("For example here is how the file should\n"); printf("look like for m=3 edges from the n=6\n"); printf("vertex set {0,1,2,3,4,5}\n"); printf("\n"); printf(" 3 6\n"); printf(" 1 5 \n"); printf(" 2 3 \n"); printf(" 5 4 \n"); printf("\n"); printf("Bound is the type of bounding method to use:\n"); printf("\n"); printf("Suppose that there are ell vertices\n"); printf(" x_0,x_1,x_2, ... , x_{ell-1}\n"); printf("chosen in the clique so far,\n"); printf("then the set of next poss. vertices is\n"); printf("C[ell]={u in C[ell-1]:{u,x_ell} is an edge }\n"); printf("\n"); printf(" (N)one - no bounding function used.\n"); printf("\n"); printf(" Si(z)eBound - if |C[v]|+ell < OptSize, then prune.\n"); printf("\n"); printf(" (S)amplingBound - greedily color one time the vertices of the\n"); printf(" that graph at the beginning of execution.\n"); printf(" let k be the number of distinct colors \n"); printf(" among the vertices of C[ell].\n"); printf(" If k+ell < OptSize, then prune.\n"); printf("\n"); printf("\n"); printf(" (G)reedyBound - greedily color the vertices of C[ell] with \n"); printf(" say k colors. If k+ell < OptSize, then prune.\n"); printf("\n"); printf("\n"); printf(" (W)eighted - prepend the bound name with a W or w to use the\n"); printf(" version for weighted vertices.\n"); } /****************************************************/ int NoBound( ) { return(n); } // This should never actually be used float WNoBound( ) { return(0); } int SizeBound( int L ) /* ** Algorithm 4.15 */ { int k; k=SetOrder(C[L]); return(k+L); } float WSizeBound( int L ) /* * Algorithm 4.15 with weights */ { int i; int max = FindLargestElement(C[L]); float w = 0; for (i = 0; i <= max; i++) if (MemberOfSet(i,C[L])) w += weights[i]; w += cliqueWeight; return w; } int GreedyColor( set U, int a ) /* ** Algorithm 4.16 */ { int h,i,k; k=0; for(i=a;i maxWeights[Color[u]]) maxWeights[Color[u]] = weights[u]; } } k=0; for (i=0; i < NumColors; i++) k += maxWeights[i]; return(k+cliqueWeight); } int GreedyBound( int L , int a) /* ** Algorithm 4.18 */ { return(GreedyColor(C[L],a)+L); } float WGreedyBound( int L, int a ) /* * Algorithm 4.18 with weights */ { int k = GreedyColor(C[L],a); float* maxWeights = (float*)calloc(k,sizeof(float)); float maxWeight = 0; int i; for (i = a; i < n; i++) { fprintf(stderr,"before %d %d\n",L,a); fprintf(stderr,"weights[%d]==%f\n",i,weights[i]); if (weights[i] > maxWeights[Color[i]]) { fprintf(stderr,"inside %d %d\n",L,a); maxWeights[Color[i]] = weights[i]; } fprintf(stderr,"after %d %d\n",L,a); } for (i = 0; i < k; i++) maxWeight += maxWeights[i]; return(maxWeight+cliqueWeight); } /****************************************************/ void WMaxClique2( int L ) /* ** Algorithm 4.19 with weighted vertices */ { int start,i,x; NODES++; if (L==0) { GetSet(C[L],V); start=0; } else { for(i=0;i OptSize || (L+1 == OptSize && cliqueWeight > OptWeight)) { OptSize=L+1; OptWeight=cliqueWeight; for(i=0;i<=L;i++) OptClique[i]=X[i]; } WMaxClique2(L+1); cliqueWeight-=weights[x]; } } } } /****************************************************/ graph NewGraph(int n) /* ** Allocate storage for a graph on order n */ { int i; graph A; A = (graph)calloc(n, sizeof(set)); for(i=0;i