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; }
/*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; }
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; }
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; }