Beispiel #1
0
int main(){
    int i,j,k,start,end,count,root,des;
    int Vnum;
    unsigned long max=MAX_LENGTH;
    char *str;
    str = (char *)malloc(max*sizeof(char));
    char p[100];
    char tmp[100];
    Node *array=NULL;
    Node *tra=NULL;
loop: while(getline(&str,&max,stdin)!=EOF)
    {
        if(str[0]=='V')
        {
            array=cleargraph(array);
            memset(tmp,'\0',sizeof(tmp));
            i=2;
            count = 0;
            while((*(str+i)>=48&&*(str+i)<=57)||*(str+i)=='-')
            {
                tmp[count]= *(str+i);
                i++;
                count++;
            }
            Vnum = getint(tmp);
            if(Vnum<0)
            {
                printf("Error: invalid input about the number of V.\n");
                continue;
            }
            array = (Node *)malloc(Vnum*sizeof(Node));
            if(array==NULL)
            {
                printf("Error: there is not enough room for storing the graph.\n");
                return false;
            }
            //printf("Vnum=%d\n",Vnum);
            for(i=0;i<Vnum;i++)       //initialize
            {
                array[i].ID=i;
                array[i].next=NULL;
                //printf("%d\n",array[i].ID);
            }
            
            
        }
        else if(str[0]=='E')
        {
            if(array==NULL)
            {
                printf("Error: the graph does not exist.\n");
                array=cleargraph(array);
                continue;
            }
            edgenum=0;
            for(i=0;*(str+i)!='\0';i++)
            {
                if(*(str+i)=='<')
                {
                    memset(tmp,'\0',sizeof(tmp));
                    i++;
                    count = 0;
                    while((*(str+i)>=48&&*(str+i)<=57)||*(str+i)=='-')
                    {
                        tmp[count]= *(str+i);
                        i++;
                        count++;
                    }
                    start = atoi(tmp);
                    if(start>Vnum-1||start<0)
                    {
                        printf("Error: a vertex specified does not exist.\n");
                        array=cleargraph(array);
                        goto loop;
                    }
                    i++;    //omit ','
                    count = 0;
                    memset(tmp,'\0',sizeof(tmp)); //initialize tmp array
                    while((*(str+i)>=48&&*(str+i)<=57)||*(str+i)=='-')
                    {
                        tmp[count]= *(str+i);
                        i++;
                        count++;
                    }
                    end = atoi(tmp);
                    if(end>Vnum-1||end<0)
                    {
                        printf("Error: a vertex specified does not exist.\n");
                        array=cleargraph(array);
                        goto loop;
                    }
                    if(start != end)
                    {
                        //store a edge
                        if(insertedge(array,start,end)==false)
                        {
                            array=cleargraph(array);
                            goto loop;
                        }
                        edgenum++;
                    }
                    
                    long long vv = (long)Vnum * (long)Vnum;
                    if(edgenum>vv)
                    {
                        printf("Error: the number of edges is beyond the limit\n");
                        array=cleargraph(array);
                        goto loop;
                    }
                }
            }
            if(edgenum==0)
            {
                goto loop;
            }
            int n = Vnum;
            int **arr;
            SAT_Manager mgr; 
            int *clause1, *clause2, *clause3, *clause4;
            for(k=1;k<=Vnum;k++)        //vertex cover of size k
            {  
                int multiply = n*k;     //Vnum*k atoms
                mgr = SAT_InitManager();
                SAT_SetNumVariables(mgr, multiply);
                //dynamic assign two-dimention array
                arr = (int **)malloc(sizeof(int *)*n);
                if(!arr)
                {
                    printf("Error: there is not enough room.\n");
                    SAT_ReleaseManager(mgr);
                    return false;
                }
                memset(arr, 0, sizeof(int *)*n);
                while(n--)
                {
                    arr[n] = (int *)malloc(sizeof(int)*k);
                }
                n = Vnum;
                int index = 1;
                //initialize the VarIndex
                for(i=0;i<n;i++)
                {
                    for(j=0;j<k;j++)
                        arr[i][j]= index++;
                }
                //create clause
                
                //test
                // for(i=0;i<n;i++)
                // {
                //     for(j=0;j<k;j++)
                //         printf("arr[%d][%d]=%d\n",i,j,arr[i][j]);
                // }

                clause1 = (int *)malloc(sizeof(int)*n);
                for(i=0;i<k;i++)
                {
                    for(j=0;j<n;j++)
                    {
                        clause1[j]= arr[j][i]<<1;
                    }
                    SAT_AddClause(mgr, clause1, n);
                    
                }
                
                //free(clause);
                clause2 = (int *)malloc(sizeof(int)*2);
                int r;
                for(i=0;i<n;i++)
                {
                    for(j=0;j<k;j++)
                    {
                        for(r=j+1;r<k;r++)
                        {

                            clause2[0] = (arr[i][j]<<1)+1;
                            clause2[1] = (arr[i][r]<<1)+1;
                            SAT_AddClause(mgr, clause2, 2);
                        }                     
                    }
                }
                //free(clause);
                clause3 = (int *)malloc(sizeof(int)*2);
                for(i=0;i<k;i++)
                {
                    for(j=0;j<n;j++)
                    {
                        for(r=j+1;r<n;r++)
                        {
                            clause3[0] = (arr[j][i]<<1)+1;
                            //printf("%d ",clause3[0]);
                            clause3[1] = (arr[r][i]<<1)+1;
                            //printf("%d\n",clause3[1]);
                            SAT_AddClause(mgr,clause3,2);
                        }
                        
                    }
                }

                //free(clause);
                clause4 = (int *)malloc(sizeof(int)*2*k);
                Node * point;
                int m;
                for(i=0;i<n;i++)
                {
                    point = array+i;
                    while(point->next)
                    {
                        point = point->next;
                        j = point->ID;
                        m=0;
                        //printf("j=%d\n",j);
                        for(r=0;r<k;r++)
                        {
                            clause4[m++] = arr[i][r]<<1;
                            //printf("arr[%d][%d]=%d\n",i,r,arr[i][r]<<1);
                            clause4[m++] = arr[j][r]<<1;
                            //printf("arr[%d][%d]=%d\n",j,r,arr[j][r]<<1);
                        }
                        SAT_AddClause(mgr, clause4, 2*k);
                        // printf("i=%d k=%d\n",i,k);
                         // printf("clause4\n");
                         // for(int bbb=0;bbb<2*k;bbb++)printf("%d ",clause4[bbb]);
                         // printf("\n");
                    }
                }

                //free(clause);
                //finish adding clause
                int pp[2], bak, idx[n];
                pipe(pp);
                bak = dup(STDOUT_FILENO);
                dup2(pp[1],STDOUT_FILENO);
                int result = SAT_Solve(mgr);
                dup2(bak, STDOUT_FILENO);
                int pre = -1;
                
                if(result == SATISFIABLE)
                {

                    int idx_num = SAT_NumVariables(mgr);
                    //printf("idx_num=%d\n",idx_num);
                    for(i=1;i<=idx_num;i++)
                    {
                        //printf("i=%d\n",i);
                        int a = SAT_GetVarAsgnment(mgr, i);
                        //printf("%d\n",a);
                        if(a==1)
                        {
                            if(pre!= -1)
                            {
                                printf("%d ",pre);
                                fflush(stdout);
                            }
                            pre = (i-1)/k;
                            //printf("i=%d,pre=%d\n",i,pre);
                        }
                        else if(a == -1){
                            printf("Error: not get the right result\n");
                            fflush(stdout);
                            goto loop;
                        }
                    }
                    printf("%d\n",pre);
                    fflush(stdout);
                    for(i=0;i<n;i++)
                        free(arr[i]);
                    free(arr);
                    free(clause1);
                    free(clause2);
                    free(clause3);
                    free(clause4);
                    SAT_ReleaseManager(mgr);
                    goto loop;
                }
            }
            for(i=0;i<n;i++)
                free(arr[i]);
            free(arr);
            SAT_ReleaseManager(mgr);
            printf("unsat\n");
            fflush(stdout);
            goto loop;
        }     
        else if(str[0]=='s')
        {

            i=0;
            if(array==NULL)
            {
                printf("Error: there is no graph existing, please input a new graph firstly\n");
                goto loop;
            }
            //for(i=0;*(str+i)!='\0';i++)printf("i=%d %c\n",i,*(str+i));
            i+=2;
            if(*(str+i)!='\0')
            {
                //while(*(str+i)<48||*(str+i)>57)i++;
                memset(tmp,'\0',sizeof(tmp));
                count = 0;
                while((*(str+i)>=48&&*(str+i)<=57)||*(str+i)=='-')
                {
                    tmp[count]= *(str+i);
                    i++;
                    count++;
                }
                //printf("%s\n",tmp);
                root = atoi(tmp);
                //printf("root=%d\n",root);
                if(root<0 || root> Vnum-1)
                {
                    printf("Error: a vertex specified does not exist.\n");
                    goto loop;
                }
                //while(*(str+i)<48||*(str+i)>57)i++;
                i++;
                memset(tmp,'\0',sizeof(tmp));
                count = 0;
                while((*(str+i)>=48&&*(str+i)<=57)||*(str+i)=='-')
                {
                    tmp[count]= *(str+i);
                    i++;
                    count++;
                }
                
                des = atoi(tmp);
                //printf("des=%d\n",des);
                if(des<0 || des> Vnum-1)
                {
                    printf("Error: a vertex specified does not exist.\n");
                    goto loop;
                }    
            }
            shortestpath(array,Vnum,root,des);
            printf("\n");
        }
        
    }
    free(array);
    return true;
}
Beispiel #2
0
/*return the solve vertex set
*return NULL if unsolvable or any error occurs
*/
int solveVertexCover_SAT(Graph* graph, int* &solveSet)
{
	if(graph == NULL || graph->V == 0)
	{
		return 0;
	}
	SAT_Manager mgr;
	mgr = SAT_InitManager();

	int bakP[2], bak;

    pipe(bakP);
    bak = dup(STDOUT_FILENO);
    dup2(bakP[1], STDOUT_FILENO);
   
   	int k, i, j, m, p, q, cIter, solveResult = UNSATISFIABLE;
   	
   	for(k = 1; k <= graph->V; k++)
   	{
   		int groupId = SAT_AllocClauseGroupID(mgr);
   		if(k == 1)
   			SAT_SetNumVariables(mgr, 1*graph->V);
   		else{//add V Variable each loop since k is increment by 1 each time 
   			int temp = 0;
   			while(temp < graph->V){
   				SAT_AddVariable(mgr);
   				temp++;
   			}
   		}
   		int* c = NULL;
   		/* pre alloc c as maximum cluase size */
   		if(2*k > graph->V)
   			c = (int*) malloc(sizeof(int) * (2*k));
   		else
   			c = (int*) malloc(sizeof(int) * graph->V);
   		/* for k*V atoms matrix: Xrc => k*(r-1)+c (var index in SAT) */

   		/* for i:[1,k] add clause: X1i v X2i v .. v XVi (r:[1,V] c:i)*/
   		for(i = 1; i <= k; i++)
   		{
   			for(cIter = 0; cIter < graph->V; cIter++)
   				c[cIter] = ((k*cIter + i) << 1);
   			 SAT_AddClause(mgr, c, graph->V, groupId);
   		}

   		/* for m:[1,n] p,q:[1,k] p<q add clause: ~Xmp v ~Xmq */
   		for(m = 1; m <= graph->V; m++)
   			for(p = 1; p <= k; p++)
   				for(q = p+1; q <= k; q++)
   				{
   					c[0] = ((k*(m-1)+p) << 1) + 1;
   					c[1] = ((k*(m-1)+q) << 1) + 1;
   					SAT_AddClause(mgr, c, 2, groupId);
   				}

   		/* for m:[1,k] p,q:[1,n] p<q add clause: ~Xpm v ~Xqm */
   		for(m = 1; m <= k; m++)
   			for(p = 1; p <= graph->V; p++)
   				for(q = p+1; q <= graph->V; q++)
   				{
   					c[0] = ((k*(p-1)+m) << 1) + 1;
   					c[1] = ((k*(q-1)+m) << 1) + 1;
   					SAT_AddClause(mgr, c, 2, groupId);
   				}
   		/* for each edge <i,j> in graph add clause: 
   			Xi1 v Xi2 v ... v Xik v Xj1 v Xj2 v ... v Xjk */
   		int num_cluase = SAT_NumClauses(mgr);
   		for(i = 0; i < graph->V; i++)
   		{
   			Node* nCrawl = graph->array[i].head;
   			while(nCrawl != NULL)
   			{
   				int dest = nCrawl->d;
   				/*only add clause for edge<i,dest> which dest > i
   				 for add each edge only once in an undirect graph*/
   				if(dest > i){
   					for(cIter = 0; cIter < k; cIter++)
   						c[cIter] = ((k*i+cIter+1) << 1);
   					for(cIter = k; cIter < 2*k; cIter++)
   						c[cIter] = ((k*dest+cIter-k+1) << 1);
   					SAT_AddClause(mgr, c, 2*k, groupId); 
   				}
   				nCrawl = nCrawl->next;
   			}
   		}
   		if(num_cluase == SAT_NumClauses(mgr)){
            break;
   		}
   		solveResult = SAT_Solve(mgr);
   		if(solveResult == SATISFIABLE)
   			break;
   		free(c);
   		SAT_DeleteClauseGroup(mgr, groupId);
   		SAT_Reset(mgr);
   	}

   	dup2(bak, STDOUT_FILENO);
   	if(solveResult == UNSATISFIABLE){
   		SAT_ReleaseManager(mgr);
   		return 0;
   	}
	int n = SAT_NumVariables(mgr);

	solveSet = (int*) malloc(sizeof(int) * k);

	for(i = 0, j = 1; j <= n && i < k; j++) {
	   	int a = SAT_GetVarAsgnment(mgr, j);
	   	if(a == 1) {
	   		solveSet[i] = (int) ceil(((double)j/(double)k)) - 1;
			i++;
	    }
	   	else if(a == 0) {}
	   	else 
	   	{
	   		fprintf(stderr, "Error: SAT error.\n");
	   		SAT_ReleaseManager(mgr); 
			return 0; 
	   	}
	}
	SAT_ReleaseManager(mgr);
	return k;
}
Beispiel #3
0
void* sat_cnf(void *parameters) {
	int  k = 1;// minimum vertex cover
	listNode* cur;
	thread_function_args *param = (thread_function_args *)parameters;
	int numNodes = param->numNodes;
	list *edgeList = param->edgeList;
	struct timespec start, end;

	if(param->vc == NULL) {
		param->vc = (int *)malloc(numNodes*sizeof(int));
	}
	
	int p[2], bak;
	if(pipe(p) < 0){
		fprintf(stderr, "Error: pipe failed\n");
		exit(-1);
	}
	bak = dup(1);
    dup2(p[1], 1);

	clockid_t cid;
	pthread_getcpuclockid(pthread_self(), &cid);
	clock_gettime(cid, &start);

	while(k <= numNodes){	
		int i,j,p,q;
       	int val = 1; /* value of variable, starts from 1*/
		int x[numNodes][k]; 
		// memset(vc, 0, numNodes*sizeof(int));

       /* initialize the value of every literal*/
		for(j = 0; j < k; j++){
			for(i = 0; i < numNodes; i++){
				x[i][j] = val++;
			}
		}

		SAT_Manager mgr = SAT_InitManager();
		SAT_SetNumVariables(mgr, numNodes*k);

       	int c[numNodes*k]; /*at most n*k literals in one clause*/

       	/*for each column, at least one of the n vertices is in VC i*/
		for(j = 0; j < k; j++){
			for(i = 0; i < numNodes; i++){
				c[i] = (x[i][j] << 1);
			}
			SAT_AddClause(mgr, c, numNodes);
		}

       	/*for each row (k>1), one vertex can't be both p^{th} and q^{th} vertex in the VC*/
		if(k > 1){
			for(i = 0; i < numNodes; i++){
				for(q = 0; q < k ; q++){
					for(p = 0; p < q; p++){
						c[0] = (x[i][p] << 1) + 1;
						c[1] = (x[i][q] << 1) + 1;
						SAT_AddClause(mgr, c, 2);
					}
				}
			}
		}

       	/*for each column, one vertex in VC can't be both p^{th} and q^{th} vertex*/
		for(j = 0; j < k; j++){
			for(q = 0; q < numNodes; q++){
				for(p = 0; p < q; p++){
					c[0] = (x[p][j] << 1) + 1;
					c[1] = (x[q][j] << 1) + 1;
					SAT_AddClause(mgr, c, 2);
				}
			}
		}

       	/*for each edge, at least one endpoint is in VC*/
		cur = edgeList->head;

		while(cur != NULL) {
			edge *e = (edge *) cur->data;

          	for(j = 0; j < k; j++) {   /*first endpoint*/
				c[j] = (x[e->p1][j] << 1);
			}

			int tmp = k;

        	for(j = 0; j < k; j++) {   /*second endpoint*/
				c[tmp] = (x[e->p2][j] << 1);
				tmp++;
			}

			SAT_AddClause(mgr, c, 2*k);
			cur = cur->next;
		}

		int result = SAT_Solve(mgr);

		if(result == SATISFIABLE) {
			int index = 0;
			int n = SAT_NumVariables(mgr);

			for(j = 1; j <= n; j++) {
				int a = SAT_GetVarAsgnment(mgr, j);

				if(a == 1) {
					if(j <= numNodes) {
						param->vc[index] = j - 1;
					}
					else {
						if(j % numNodes == 0) {
							param->vc[index] = numNodes - 1;
						}
						else {
							param->vc[index] = j % numNodes - 1;
						}
					}

					index++;
				}
			}

			qsort(param->vc, index, sizeof(int), compare);
			param->vcSize = index;
			SAT_ReleaseManager(mgr); 
			dup2(bak, 1);                 
			break;
		}   

		k++;
		SAT_ReleaseManager(mgr);
	}

	pthread_getcpuclockid(pthread_self(), &cid);
	clock_gettime(cid, &end);
	param->cputime = timediff(&start,&end);
	return NULL;
}
Beispiel #4
0
int vc(int v)
{ 
   int i,j,r,l,a,key,var,loop1,ind;
   int row,col,nop; 
   //int *node;
    for(i=1;i<=v;i++)
	{       
		l=v*i;
		
    		int p[2], bak;

		pipe(p);
    		bak = dup(STDOUT_FILENO);
		dup2(p[1], STDOUT_FILENO);
		mgr= SAT_InitManager();
			
                SAT_SetNumVariables(mgr,l);
               
		r=cl_one(v,i);
		r=cl_two(v,i);
		r=cl_three(v,i);
		r=cl_four(v,i);
		
		key = SAT_Solve(mgr);
		
		dup2(bak, STDOUT_FILENO);
                if(key == SATISFIABLE) 
		{
			ind=0;
			var= SAT_NumVariables(mgr);
			
		        for(j = 1; j <= var; j++) 
			{
				a = SAT_GetVarAsgnment(mgr,j);
	    			if(a == 1) {
			                      
                                                for(row=1;row<=v;row++)
						{
							for(col=1;col<=v;col++)
							{
								if(grk[row][col]==j)
								{
									node[ind]=row-1;
									ind++;
								}
							}
						}							
						
	    				   }
	    			else if(a == 0) {
						  nop=1;
				      	        }
	                        else {
		                      fprintf(stderr,"Error: Sat solver generet invalid state"); fflush(stderr);
	                            }
			}
			SAT_ReleaseManager(mgr);    
		
		       
			break;
    		}
    		else
		 {
			nop=1;
			SAT_ReleaseManager(mgr);
    		  }
		  
                 
	}
	
    return i;
}