int
main(int argc,char *argv[])
{
	int *g;
	int *new_g;
	int gsize;
	int count;
	int i;
	int j;
	int best_count;
	int best_i;
	int best_j;
	int best_k;
	void *taboo_list;
	int val,iter,jter;
	char fname[255];
	FILE *fp;
    char bc[255];
    int fd;
	/*
	 * start with graph of size 8
	 */

	if (argc < 2) {
		gsize = 8;
		g = (int *)malloc(gsize*gsize*sizeof(int));
		if(g == NULL) {
			exit(1);
		}

	/*
	 * start out with all zeros
	 */
		memset(g,0,gsize*gsize*sizeof(int));
		val = 0, iter = 0, jter=0;
		for( iter=0; iter<gsize; iter++){
			for( jter = 0; jter< gsize; jter++){
				g[iter*gsize + jter]  = val;
				val = 1 - val; 
			}
		}
	//	PrintGraph(g, gsize);

	} else if (argc == 2) {

		gsize = atoi(argv[1]);
		g = (int *)malloc(gsize*gsize*sizeof(int));
		if(g == NULL) {
			exit(1);
        	}
		g = PaleyGraph(gsize);
	}
    else {
        char graphfile[256];
        strcpy(graphfile, argv[2]);
        gsize = atoi(argv[1]);
        //printf("gsize=%d", gsize);
        g = (int *)malloc(gsize*gsize*sizeof(int));
        ReadGraph(graphfile, &g, &gsize);
        printf("\nStarting from given graph of size %d\n.", gsize);
        fflush(stdout);
    }
	/*
	 *make a fifo to use as the taboo list
	 */
        taboo_list = FIFOInitEdge(TABOOSIZE);
        if(taboo_list == NULL) {
                exit(1);
        }


	/*
	 * while we do not have a publishable result
	 */
    
	while(gsize < 206)
	{
		/*
		 * find out how we are doing
		 */
		count = CliqueCount(g,gsize);

		/*
		 * if we have a counter example
		 */
		if(count == 0)
		{
		//	printf("Eureka! i Counter-example found!\n");
			sprintf(fname,"solutions/CE-%d.txt",gsize);
			fp = fopen(fname,"w");
			char *key;
			(void)MakeGraphKey(g,gsize,&key);
            PrintGraph(g,gsize,fp, key);    
            fclose(fp);
            /*
			if(gsize == 31)
			{
				FILE *fp;
				char buf[100];
				bzero(buf, 100);
				sprintf(buf, "graph_%d.state", gsize);
				printf("Filename: %s", buf); 
				fp = fopen(buf, "w+");
				PrintGraphToFile(g, gsize, fp);
				fclose(fp);
			}
            */
			free(key);
			/*
			 * make a new graph one size bigger
			 */
			new_g = (int *)malloc((gsize+1)*(gsize+1)*sizeof(int));
			if(new_g == NULL)
				exit(1);
			/*
			 * copy the old graph into the new graph leaving the
			 * last row and last column alone
			 */
			CopyGraph(g,gsize,new_g,gsize+1);

			/*
			 * zero out the last column and last row
			 */
			for(i=0; i < (gsize+1); i++)
			{
				if(drand48() > 0.5) {
					new_g[i*(gsize+1) + gsize] = 0; // last column
					new_g[gsize*(gsize+1) + i] = 0; // last row
				}
				else
				{
					new_g[i*(gsize+1) + gsize] = 1; // last column
					new_g[gsize*(gsize+1) + i] = 1; // last row
				}
			}

			/*
			 * throw away the old graph and make new one the
			 * graph
			 */
			free(g);
			g = new_g;
			gsize = gsize+1;

			/*
			 * reset the taboo list for the new graph
			 */
			taboo_list = FIFOResetEdge(taboo_list);

			/*
			 * keep going
			 */
			continue;
		}

		/*
		 * otherwise, we need to consider flipping an edge
		 *
		 * let's speculative flip each edge, record the new count,
		 * and unflip the edge.  We'll then remember the best flip and
		 * keep it next time around
		 *
		 * only need to work with upper triangle of matrix =>
		 * notice the indices
		 */
		best_count = BIGCOUNT;
		for(i=0; i < gsize; i++)
		{
			for(j=i+1; j < gsize; j++)
			{
				/*
				 * flip two edges (i,j), (i,random(j) + 1) 
				 */
				int k = getRandomJ(gsize);
				g[i*gsize+j] = 1 - g[i*gsize+j];
				if (k == j)
					k = j + 1;
				g[i*gsize + k] = 1 - g[i*gsize + k];
				count = CliqueCount(g,gsize);

				/*
				 * is it better and the i,j,count not taboo?
				 */
				if((count < best_count) && 
//					!FIFOFindEdge(taboo_list,i,j))
					!FIFOFindEdgeCount(taboo_list,i,j,count) &&
					!FIFOFindEdgeCount(taboo_list,i,k, count))
				{
					/* no need to store j + 1 */
					best_count = count;
					best_i = i;
					best_j = j;
					best_k = k;
				}

				/*
				 * flip it back
				 */
				g[i*gsize+j] = 1 - g[i*gsize+j];
				g[i*gsize+k] = 1 - g[i*gsize+k];
			}
		}

		if(best_count == BIGCOUNT) {
			printf("no best edge found, terminating\n");
			exit(1);
		}
		
		/*
		 * keep the best flip we saw
		 */
		g[best_i*gsize+best_j] = 1 - g[best_i*gsize+best_j];
		g[best_i*gsize + best_k] = 1 - g[best_i*gsize + best_k];

		/*
		 * taboo this graph configuration so that we don't visit
		 * it again
		 */
		count = CliqueCount(g,gsize);
//		FIFOInsertEdge(taboo_list,best_i,best_j);
		FIFOInsertEdgeCount(taboo_list,best_i,best_j,count);
		FIFOInsertEdgeCount(taboo_list,best_i,best_k,count);
/*
		printf("ce size: %d, best_count: %d, best edges: (%d,%d) (%d,%d), new colors: %d %d\n",
			gsize,
			best_count,
			best_i,
			best_j,
			best_i,
			best_k,
			g[best_i*gsize+best_j],
			g[best_i*gsize+best_k]);
*/	
        /* write update to file */	
	    sprintf(fname,"solutions/CE-%d-upd.txt",gsize);
        sprintf(bc,"%d",best_count);
        fp = fopen(fname, "w+");
        if (fp == NULL) {
            printf("\n Ah file error ? \n");
            exit(0);
    
        }
        fd = fileno(fp);
        ftruncate(fd, 0);
        PrintGraph(g,gsize,fp, bc);
	    fclose(fp);	
		/*
		 * rinse and repeat
		 */
	}

	FIFODeleteGraph(taboo_list);


	return(0);

}
int
main(int argc,char *argv[])
{
	int *g;
	int *new_g;
	int gsize;
	int count;
	int i;
	int j;
	int best_count;
	int best_i;
	int best_j;
	void *taboo_list;

	/*
	 * start with graph of size 8
	 */
	gsize = 15;
	g = (int *)malloc(gsize*gsize*sizeof(int));
	if(g == NULL) {
		exit(1);
	}

	/*
	 * make a fifo to use as the taboo list
	 */
	taboo_list = FIFOInitEdge(TABOOSIZE);
	if(taboo_list == NULL) {
		exit(1);
	}

	/*
	 * start out with all zeros
	 */
	memset(g,0,gsize*gsize*sizeof(int));

	/*
	 * while we do not have a publishable result
	 */
	while(gsize < 102)
	{
		/*
		 * find out how we are doing
		 */
		count = CliqueCount(g,gsize);

		/*
		 * if we have a counter example
		 */
		if(count == 0)
		{
			printf("Eureka!  Counter-example found!\n");
			PrintGraph(g,gsize);
			/*
			 * make a new graph one size bigger
			 */
			new_g = (int *)malloc((gsize+1)*(gsize+1)*sizeof(int));
			if(new_g == NULL)
				exit(1);
			/*
			 * copy the old graph into the new graph leaving the
			 * last row and last column alone
			 */
			CopyGraph(g,gsize,new_g,gsize+1);

			/*
			 * zero out the last column and last row
			 */
			for(i=0; i < (gsize+1); i++)
			{
				new_g[i*(gsize+1) + gsize] = 0; // last column
				new_g[gsize*(gsize+1) + i] = 0; // last row
			}

			/*
			 * throw away the old graph and make new one the
			 * graph
			 */
			free(g);
			g = new_g;
			gsize = gsize+1;

			/*
			 * reset the taboo list for the new graph
			 */
			taboo_list = FIFOResetEdge(taboo_list);

			/*
			 * keep going
			 */
			continue;
		}

		/*
		 * otherwise, we need to consider flipping an edge
		 *
		 * let's speculative flip each edge, record the new count,
		 * and unflip the edge.  We'll then remember the best flip and
		 * keep it next time around
		 *
		 * only need to work with upper triangle of matrix =>
		 * notice the indices
		 */
		best_count = BIGCOUNT;
		for(i=0; i < gsize; i++)
		{
			for(j=i+1; j < gsize; j++)
			{
				/*
				 * flip it
				 */
				g[i*gsize+j] = 1 - g[i*gsize+j];
				count = CliqueCount(g,gsize);

				/*
				 * is it better and the i,j,count not taboo?
				 */
				if((count < best_count) && 
//					!FIFOFindEdge(taboo_list,i,j))
				!FIFOFindEdgeCount(taboo_list,i,j,count))
				{
					best_count = count;
					best_i = i;
					best_j = j;
				}

				/*
				 * flip it back
				 */
				g[i*gsize+j] = 1 - g[i*gsize+j];
			}
		}

		if(best_count == BIGCOUNT) {
			printf("no best edge found, terminating\n");
			exit(1);
		}
		
		/*
		 * keep the best flip we saw
		 */
		g[best_i*gsize+best_j] = 1 - g[best_i*gsize+best_j];

		/*
		 * taboo this graph configuration so that we don't visit
		 * it again
		 */
		count = CliqueCount(g,gsize);
//		FIFOInsertEdge(taboo_list,best_i,best_j);
		FIFOInsertEdgeCount(taboo_list,best_i,best_j,count);

		printf("ce size: %d, best_count: %d, best edge: (%d,%d), new color: %d\n",
			gsize,
			best_count,
			best_i,
			best_j,
			g[best_i*gsize+best_j]);

		/*
		 * rinse and repeat
		 */
	}

	FIFODeleteGraph(taboo_list);


	return(0);

}
int
main(int argc,char *argv[])
{
	signal(SIGINT, sig_handler);
	signal(SIGTERM, sig_handler);
	
	int *g;
	int *new_g;
	int gsize;
	long count;
	long count_1;
	long count_2;
	long count_3;
	int i;
	int j;
	int k;
	long best_count;
	long prev_best_count;
	int best_i;
	int best_j;
	int best_k;
	int best_l;
	void *taboo_list;
	int* taboo_array;
	int val,iter,jter;
	int multi = 0;
	/*
	 * start with graph of size 8
	 */

	if (argc < 2) {
		gsize = 8;
		g = (int *)malloc(gsize*gsize*sizeof(int));
		if(g == NULL) {
			exit(1);
		}

	/*
	 * start out with all zeros
	 */
		memset(g,0,gsize*gsize*sizeof(int));
		val = 0, iter = 0, jter=0;
		for( iter=0; iter<gsize; iter++){
			for( jter = 0; jter< gsize; jter++){
				g[iter*gsize + jter]  = val;
				val = 1 - val; 
			}
		}
		PrintGraph(g, gsize);

	} else if (argc == 2) {

		gsize = atoi(argv[1]);
		g = (int *)malloc(gsize*gsize*sizeof(int));
		if(g == NULL) {
			exit(1);
        	}
		g = PaleyGraph(gsize);
		int* row = (int *)malloc(gsize*sizeof(int));
		memcpy(row, g, gsize*sizeof(int));
		create_sgraph(&g, gsize, row);
		taboo_array = (int*)malloc(sizeof(int)*gsize);
		memset(taboo_array, 0, gsize*sizeof(int));
		printf("Starting from Paley graph of size %d\n.", gsize);
		fflush(stdout);
		free(row);
	}
	else {
		gsize = atoi(argv[1]);
		g = (int *)malloc(gsize*gsize*sizeof(int));
		ReadGraph(argv[2], &g, &gsize);
		count = CliqueCount(g,gsize);
		if (count == 0)
		{
			printf("Eureka!  Sym Counter-example found!\n");
			PrintGraph(g,gsize);
			fflush(stdout);
			
			new_g = (int *)malloc((gsize+1)*(gsize+1)*sizeof(int));
			if(new_g == NULL)
				exit(1);
			
			int* row = (int *)malloc((gsize+1)*sizeof(int));
			memcpy(row, g, gsize*sizeof(int));
			free(g);
			gsize = gsize+1;
			create_sgraph(&new_g, gsize, row);
			free(row);
			//CopyGraph(g,gsize,new_g,gsize+1);
			set_sedge(&new_g, gsize, gsize-1, 0);
			long count0  = CliqueCount(new_g, gsize);
			set_sedge(&new_g, gsize, gsize-1, 1);
			long count1  = CliqueCount(new_g, gsize);
			if(count0 < count1)
				set_sedge(&new_g, gsize, gsize-1, 0);
			taboo_array = (int*) malloc(sizeof(int)*gsize);
			memset(taboo_array, 0, sizeof(int)*gsize);
			g = new_g;
			
		}
		else
		{
			int* row = (int *)malloc(gsize*sizeof(int));
			memcpy(row, g, gsize*sizeof(int));
			create_sgraph(&g, gsize, row);
			taboo_array = (int*)malloc(sizeof(int)*gsize);
			memset(taboo_array, 0, gsize*sizeof(int));
			printf("Starting from given graph of size %d\n.", gsize);
			fflush(stdout);
			free(row);
		}
	}

	/*
	 *make a fifo to use as the taboo list
	 */
        taboo_list = FIFOInitEdge(TABOOSIZE);
        if(taboo_list == NULL) {
                exit(1);
        }


	/*
	 * while we do not have a publishable result
	 */
  while(gsize<206)
  {

	best_count = BIGCOUNT;
	while(gsize < 206)
	{
		best_j = -1;
		count = CliqueCount(g,gsize);
		if(count == 0)
		{
			printf("Eureka!  Sym Counter-example found!\n");
			PrintGraph(g,gsize);
			fflush(stdout);
			/*
			 * make a new graph one size bigger
			 */
			new_g = (int *)malloc((gsize+1)*(gsize+1)*sizeof(int));
			if(new_g == NULL)
				exit(1);
			
			int* row = (int *)malloc((gsize+1)*sizeof(int));
			memcpy(row, g, gsize*sizeof(int));
			free(g);
			gsize = gsize+1;
			create_sgraph(&new_g, gsize, row);
			free(row);
			//CopyGraph(g,gsize,new_g,gsize+1);
			set_sedge(&new_g, gsize, gsize-1, 0);
			long count0  = CliqueCount(new_g, gsize);
			set_sedge(&new_g, gsize, gsize-1, 1);
			long count1  = CliqueCount(new_g, gsize);
			if(count0 < count1)
				set_sedge(&new_g, gsize, gsize-1, 0);
			taboo_array = (int*) malloc(sizeof(int)*gsize);
			memset(taboo_array, 0, sizeof(int)*gsize);
			g = new_g;

			best_count = BIGCOUNT;
			/*
			 * reset the taboo list for the new graph
			 */
			//taboo_list = FIFOResetEdge(taboo_list);
			free(taboo_array);
			taboo_array = (int*) malloc(sizeof(int)*gsize);
			memset(taboo_array, 0, sizeof(int)*gsize);

			continue;
		}
		

		//best_count = BIGCOUNT;
		prev_best_count = best_count;
		if(multi<5){
				for(i=0; i < gsize; i++)
				{
					
					flip_sedge(&g, gsize, i);
					count = CliqueCount(g,gsize);
					if(count<best_count && !taboo_array[i]){
					//if(count<best_count ){
						best_count = count;
						best_i = i;
					}
					flip_sedge(&g, gsize, i);
				}
		}
		else{
			for(i=0; i<gsize; i++){
				for(j=i+1; j<gsize; j++){
					flip_sedge(&g, gsize, i);
					flip_sedge(&g, gsize, j);
					count = CliqueCount(g,gsize);
					if(count<best_count){
						best_count = count;
						best_i = i;
						best_j = j;
					}
					flip_sedge(&g, gsize, i);
					flip_sedge(&g, gsize, j);
				}
			}
		}

		if(best_count == BIGCOUNT || best_count==prev_best_count) {
			if(multi>=5)
			{
				printf("no best edge found, continuing with taboo\n");
				fflush(stdout);
				break;
			}
			else
			{
				printf("single flip exhausted. starting singleflip again.", multi);
				fflush(stdout);
				memset(taboo_array, 0, sizeof(int)*gsize);
				multi ++;
				continue;
			}
			//flip_sedge(g, gsize, i);
		}
		flip_sedge(&g, gsize, best_i);
		count = best_count;
		if(multi)
			flip_sedge(&g, gsize, best_j);
		taboo_array[best_i] = 1;
		printf("sym ce size: %d, best_count: %ld, best edge(s): (%d), (%d)\n", gsize, best_count, best_i, best_j);
		g_latest = g;
		g_size_latest = gsize;
		g_count_latest = count;
		fflush(stdout);
	}

	while(gsize < 206)
	{
		/*
		 * if we have a counter example
		 */
		if(count == 0)
		{
			printf("Eureka!  Counter-example found!\n");
			PrintGraph(g,gsize);
			fflush(stdout);
			/*
			 * make a new graph one size bigger
			 */
			new_g = (int *)malloc((gsize+1)*(gsize+1)*sizeof(int));
			if(new_g == NULL)
				exit(1);
			/*
			 * copy the old graph into the new graph leaving the
			 * last row and last column alone
			 */
			CopyGraph(g,gsize,new_g,gsize+1);

			/*
			 * zero out the last column and last row
			 */
			for(i=0; i < (gsize+1); i++)
			{
				if(drand48() > 0.5) {
					new_g[i*(gsize+1) + gsize] = 0; // last column
					new_g[gsize*(gsize+1) + i] = 0; // last row
				}
				else
				{
					new_g[i*(gsize+1) + gsize] = 1; // last column
					new_g[gsize*(gsize+1) + i] = 1; // last row
				}
			}

			/*
			 * throw away the old graph and make new one the
			 * graph
			 */
			free(g);
			g = new_g;
			gsize = gsize+1;

			/*
			 * reset the taboo list for the new graph
			 */
			taboo_list = FIFOResetEdge(taboo_list);

			/*
			 * keep going
			 */
			//continue;
			break; //Go to first while loop
		}

		/*
		 * otherwise, we need to consider flipping an edge
		 *
		 * let's speculative flip each edge, record the new count,
		 * and unflip the edge.  We'll then remember the best flip and
		 * keep it next time around
		 *
		 * only need to work with upper triangle of matrix =>
		 * notice the indices
		 */
		best_count = BIGCOUNT;
		for(i=0; i < gsize; i++)
		{
			for(j=i+1; j < gsize; j++)
			{
				/*
				 * flip two edges (i,j), (i,random(j) + 1) 
				 */
				int k = getRandomJ(gsize);
				int l = getRandomJ(gsize);

				g[i*gsize+j] = 1 - g[i*gsize+j];
				count_1 = CliqueCount(g,gsize);

				if (k == j)
					k = j + 1;
				g[i*gsize + k] = 1 - g[i*gsize + k];
				count_2 = CliqueCount(g,gsize);

				if (l == j)
					l = j + 1;
				if (l == k)
					l = (k + 1) % gsize;

				g[i*gsize + l] = 1 - g[i*gsize + l];
				count_3 = CliqueCount(g,gsize);

                                count = (count_1 < count_2) ? count_1 : count_2 ;
				count = (count_3 < count) ? count_3 : count ;

				/*
				 * is it better and the i,j,count not taboo?
				 */
				if(count < best_count){
					if(count == count_1
//#ifdef USE_TABOO
						&& !FIFOFindEdgeCount(taboo_list,i,j,count)
//#endif
						)
					{
						best_count = count;
						best_i = i;
						best_j = j;
						best_k = best_l = -1;
					}
					else if(count == count_2
//#ifdef USE_TABOO
						&& (!FIFOFindEdgeCount(taboo_list,i,j,count)
						|| !FIFOFindEdgeCount(taboo_list,i,k, count))
//#endif
						)
					{
						best_count = count;
						best_i = i;
						best_j = j;
						best_k = k;
						best_l = -1;
					}
					else if(count == count_3
//#ifdef USE_TABOO
						&& (!FIFOFindEdgeCount(taboo_list,i,j,count)
						|| !FIFOFindEdgeCount(taboo_list,i,k, count)
						|| !FIFOFindEdgeCount(taboo_list,i,l, count))
//#endif
						)
					{
						best_count = count;
						best_i = i;
						best_j = j;
						best_k = k;
						best_l = l;
					}
				} 

				/*
				 * flip it back
				 */
				g[i*gsize+j] = 1 - g[i*gsize+j];
				g[i*gsize+k] = 1 - g[i*gsize+k];
				g[i*gsize+l] = 1 - g[i*gsize+l];
			}
		}

		if(best_count == BIGCOUNT) {
			printf("no best edge found, terminating\n");
			exit(1);
		}
		
		/*
		 * keep the best flip we saw
		 */
		g[best_i*gsize + best_j] = 1 - g[best_i*gsize + best_j];
		if (best_k != -1)
			g[best_i*gsize + best_k] = 1 - g[best_i*gsize + best_k];
		if (best_l != -1)
			g[best_i*gsize + best_l] = 1 - g[best_i*gsize + best_l];

		/*
		 * taboo this graph configuration so that we don't visit
		 * it again
		 */
		//count = CliqueCount(g,gsize);
		count = best_count;
//#ifdef USE_TABOO
//		FIFOInsertEdge(taboo_list,best_i,best_j);
		FIFOInsertEdgeCount(taboo_list,best_i,best_j,count);
		if (best_k != -1)
			FIFOInsertEdgeCount(taboo_list,best_i,best_k,count);
		if (best_l != -1)
			FIFOInsertEdgeCount(taboo_list,best_i,best_l,count);
//#endif
		printf("ce size: %d, best_count: %ld, best edges: (%d,%d) (%d,%d) (%d,%d), new colors: %d %d\n",
			gsize,
			best_count,
			best_i,
			best_j,
			best_i,
			best_k,
			best_i,
			best_l,
			g[best_i*gsize+best_j],
			g[best_i*gsize+best_k]);

		fflush(stdout);
		g_latest = g;
		g_size_latest = gsize;
		g_count_latest = count;
		/*
		 * rinse and repeat
		 */
	}
  }

	FIFODeleteGraph(taboo_list);


	return(0);

}