/* tabu3.c tabu search program for clique finding by Patric Ostergard, 15.05.2014 */ /* make -f makefile3 */ #include #include #include #include "cliquer.h" char infilename[128], outfilename[128]; #define MAXN 7000 /* order of graph */ int debug_level = 0; extern long int lrand48(); int gr[MAXN][MAXN]; /* distance matrix */ int wt[MAXN]; /* orbit size */ int a60=0; int d(int a,int b) { int c,e,i; c = a^b; e = 0; for(i=0;i<16;i++) if(((c>>i)&1)==1) e++; return e; } int err_message(int i) { printf("Usage: tabu d1 d2 threshold sim rounds seed (error %d)\n",i); exit(1); } int main(argc,argv) int argc; char *argv[]; /* arguments: d1 d2 lambda sim rd tabu seed */ { int n,k,m,total; int ii[MAXN],jj[MAXN],nr,posit,sim,rd,rct=0; int tabu[MAXN],pp,npos; int absval,count,count2,p,size,temp,temp2; int timeout; int i,j,k2,tabo,seed; int weight,weight2,ok,ant,ant2,mx,gsize; int gtab[MAXN],htab[MAXN],value[MAXN],v2[MAXN]; int d1,d2,d3; int high,threshold; int max=0; graph_t *g; set_t st; /* no timer */ clique_default_options->time_function = NULL; if(argc<8) err_message(10); if((d1 = atoi(argv[1]))==0) err_message(1); if((d2 = atoi(argv[2]))==0) err_message(2); if((threshold = atoi(argv[3]))==0) err_message(3); if((sim = atoi(argv[4]))==0) err_message(4); if((rd = atoi(argv[5]))==0) err_message(5); seed = atoi(argv[6]); strncpy(infilename, argv[7], sizeof(infilename)); if(argc>8) debug_level = atoi(argv[8]); /* INIT graph (now: testing)*/ int pidx; for(pidx = 0; pidx<8; pidx++) { printf("%s ", argv[pidx]); } printf("\n"); #if 0 n = 2048; for(i=0;in) break; value[i] = lrand48()%n; for(j=0;j 0) { printf("Initial weight/size: %d/%d\n",weight,ant); } int ct = 0; timeout = 1; for(;;) { /* if(timeout%5==0) printf("T: %d\n",timeout); */ if(timeout>1000) { /* now we are stuck, RESTART */ count2 = 0; if(weight>max) max = weight; goto again; } high = -1; nr = 0; if(ct<100) { /* different nbrhood in the beginning, ct rounds */ d3 = d1; ct++; } else d3 = d2; for(;;) { i = (lrand48()%ant); /* remove vertex */ /* if(tabu[i]) continue; */ /* find vertices (indices) that are close to the removed one */ for(j=0;jd3) continue; /* order matters! */ htab[j] = -1; ant2++; weight2 += wt[value[j]]; } /* printf("%d %d\n",ant2,weight2); for testing */ /* run clique search */ gsize = 0; for(j=0;jweights[j] = wt[gtab[j]]; for(k=j+1;k=d1) GRAPH_ADD_EDGE(g,j,k); } mx = clique_max_weight(g,clique_default_options); graph_free(g); total = mx-weight2; if(total > high) { nr = 1; ii[0] = i; jj[0] = mx; high = total; } else if(total==high) { ii[nr] = i; jj[nr++] = mx; } break; } posit = (lrand48()%nr); /* MAKE CHANGE */ for(j=0;jd3) { /* order matters */ v2[temp++] = value[j]; /* save */ continue; } htab[j] = -1; ant2++; weight2 += wt[value[j]]; } /* run clique search */ gsize = 0; for(j=0;jweights[j] = wt[gtab[j]]; for(k=j+1;k=d1) GRAPH_ADD_EDGE(g,j,k); } st = clique_find_single(g,jj[posit],jj[posit],FALSE,clique_default_options); graph_free(g); if(st==NULL) { timeout++; continue; } i = -1; while ((i=set_return_next(st,i)) >= 0) { v2[temp++] = gtab[i]; } ant = temp; weight += high; for(i=0;i=threshold) { /* YES! */ printf("Yess!!! %d %d\n",ant,weight); for(i=0;i0) { printf("%d/%d %d %d (max %d) %d/%d\n",count2,sim,ant,weight,max,a60,rct); } if(count2++==sim) { count2 = 0; if(weight>max) max = weight; if(weight>=threshold-1) a60++; if(++rct < rd) goto again; exit(0); } } } }