sat.c
上传用户:hhyinxing
上传日期:2013-09-10
资源大小:833k
文件大小:19k
源码类别:

并行计算

开发平台:

Unix_Linux

  1. /* FILE : sat.c*/
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. /*包含有关时间的函数*/
  5. #include <time.h>  
  6. /*mpi库函数*/
  7. #include "mpi.h"  
  8. #include <math.h>
  9. /*变量数目*/
  10. #define NVARS  100
  11. /*子句数目*/
  12. #define NCLAUSES  3
  13. /*每条子句的长度*/
  14. #define LENGTH_CLAUSE  3
  15. /*fgets一行最多读入的字符数*/
  16. #define MAXLINE 60
  17. #define TRUE 1
  18. #define FALSE 0
  19. /*既不是可满足的也不是不可满足的*/
  20. #define UNCERTAIN -1
  21. /*变量值为空*/
  22. #define NOVALUE -1
  23. #define DEPTH 5
  24. /*计算pow(x,y)*/
  25. int Pow(int x, int y);
  26. #define COUNT Pow(2,DEPTH)
  27. #define TASKTAG 11 
  28. /**************/ 
  29. /*主要数据结构*/
  30. /**************/
  31. /*变量*/
  32. struct VARIABLE{
  33. /*变量真值为1,假值为0,无值为-1*/
  34. int value;
  35. };
  36. /*文字*/
  37. struct LITERAL{
  38. /*取值为VAR,-VAR和NOVALUE */
  39. /* VAR取值从1到NVARS*/
  40. int value;
  41. };
  42. /*子句*/
  43. struct CLAUSE{
  44. struct LITERAL lit[LENGTH_CLAUSE];
  45. int num_unassigned;
  46. /*被满足状态取值TRUE,FALSE或UNCERTAIN */
  47. int state_of_satisfied;
  48. };
  49. /*合取范式*/
  50. struct CNF{
  51. struct VARIABLE var[NVARS];
  52. struct CLAUSE clause[NCLAUSES];
  53. int num_uncertain;
  54. /*结果取值为TRUE,FALSE或UNCERTAIN*/
  55. int result;
  56. };
  57. /************/
  58. /*进一步定义*/
  59. /************/
  60. /*测试一个子句是否可满足*/
  61. int DavisPutnam();
  62. /*当赋予一个新值时更新结构CNF*/
  63. void UpdateCNF();
  64. /*检查该CNF是否只有单一字句*/
  65. int HasUnitClause();
  66. /*检查该CNF是否有纯文字*/
  67. int HasPureLiteral();
  68. /*从输入文件读数据初始化CNF*/
  69. void InitCNF();
  70. /*从失败记号恢复CNF*/
  71. void Reverse();
  72. /*返回一个整数的绝对值*/
  73. int Abs();
  74. /*将CNF打包到一个整数缓冲*/
  75. void PackCNF();
  76. /*将一个整数缓冲释放到一个CNF*/
  77. void UnpackCNF();
  78. /*根据任务更新该CNF*/
  79. void SetValue(); /*从X中取得n位*/
  80. unsigned GetBits(); /*从根接收任务然后计算并会送结果*/
  81. void SlaveWork();
  82. /*从CNF中选变量*/
  83. void PickVars();
  84. /*检查变量是否在缓冲中*/
  85. int NotInBuf(); 
  86. /*主函数*/
  87. int main(int argc,char ** argv)  
  88. {   
  89. struct CNF  Cnf;  /*合取范式CNF*/
  90. int length=2+NVARS+NCLAUSES*(2+LENGTH_CLAUSE)+1;   /*缓冲区长度*/
  91. int buf[length];  /*LENGHT_CLAUSE*NCLAUSE缓冲区*/
  92. MPI_Status status;  /*MPI--状态*/
  93. int i,j,myrank,size,BufResult;
  94. char* CnfFile;  /*输入CNF文件名*/
  95. FILE * in;  /*处理文件*/
  96. MPI_Init(&argc,&argv);  /*MPI--初始化*/
  97. MPI_Comm_rank(MPI_COMM_WORLD,&myrank);  /*MPI--次第号*/
  98. MPI_Comm_size(MPI_COMM_WORLD,&size);  /*MPI--数目*/
  99. /*root processor read data and initiate Cnf,then pack it to buff*/
  100. if(myrank==0)  /*进程0(主进程)*/
  101. {
  102. if (argc<2)  /*保证有两个参数*/
  103. {
  104. printf("You forgot to enter a parametes!n");  /*参数数目不对*/
  105. MPI_Abort(MPI_COMM_WORLD,99);  /*MPI--退出*/
  106. }
  107. CnfFile=argv[1];  /*读取CNF文件名*/
  108. if ((in=fopen(CnfFile,"rt"))==NULL) /*read file*/
  109. {
  110. printf("cannot open the result filen");  /*文件不存在或没有相应的属性*/
  111. MPI_Abort(MPI_COMM_WORLD,99);  /*MPI--退出 */
  112. }
  113. if(myrank==0) printf("NVARS=%d NCLAUSES=%d LENGTH_CLAUSE=%dn",NVARS,NCLAUSES,LENGTH_CLAUSE);
  114. InitCNF(&Cnf,in);  /*从输入文件中读取数据并初始化CNF*/
  115. PackCNF(Cnf,buf);  /*将CNF打包到整型缓冲--便于MPI广播*/
  116. }
  117. /*broadcast buf to all the processors*/
  118. MPI_Barrier(MPI_COMM_WORLD);
  119. MPI_Bcast(buf,length,MPI_INT,0,MPI_COMM_WORLD);  /*MPI--广播CNF包*/
  120. MPI_Barrier(MPI_COMM_WORLD);
  121. /*if it is root processor,distribute the task and wait result from slaves*/
  122. if ( myrank == 0)  /*进程0(主进程)*/
  123. {
  124. double start,end;
  125. start=MPI_Wtime();  /*MPI--时间(开始时间)*/
  126. /*send the first bulk of task*/
  127. for(i=0;i<size-1;i++)  /*对每一个从进程都发送消息*/
  128. MPI_Send(&i,1,MPI_INT,i+1,TASKTAG,MPI_COMM_WORLD);  /*发送CNF信息到从进程*/
  129. while (1)  /*一直执行*/
  130. {              
  131. MPI_Recv(&BufResult,1,MPI_INT,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status);  /*从从进程接收结果*/
  132. if ( BufResult==TRUE )  /*SAT算法成功 */
  133. {
  134. end=MPI_Wtime();  /*MPI--时间(结束时间)*/
  135. i=COUNT+10;
  136. printf("nSatisfied! time%fn",end-start);  /*运行时间*/
  137. /*send i as the end signal*/
  138. for(j=0;j<size-1;j++)
  139.     MPI_Send(&i,1,MPI_INT,j+1,TASKTAG,MPI_COMM_WORLD);  /*向从进程发送终止信号*/
  140. break;  /*退出执行*/
  141. }
  142. else if(i>COUNT)  /*SAT算法超出规模*/
  143. {
  144. printf("nUnsatisfied!n");  /*SAT算法失败*/
  145. /*send i as the terminal signal*/
  146. for(j=0;j<size-1;j++)
  147. MPI_Send(&i,1,MPI_INT,j+1,TASKTAG,MPI_COMM_WORLD);  /*向从进程发送终止信号*/
  148. break;  /*退出执行*/
  149. }
  150. else
  151. {
  152. int dest=status.MPI_SOURCE;  /*确定消息发送目的地*/
  153. MPI_Send(&i,1,MPI_INT,dest,TASKTAG,MPI_COMM_WORLD);  /*向从进程发送相应CNF包*/
  154. i++;  /*下一步操作*/
  155. }
  156. }
  157. }
  158. else  /*其它进程(从进程)*/
  159. {
  160. unsigned BufTask;  /*任务数*/
  161. UnpackCNF(&Cnf,buf);  /*将缓冲中的CNF解包*/
  162. while(1)  /*一直执行*/
  163. {
  164. MPI_Recv(&BufTask,1,MPI_INT,0,TASKTAG,MPI_COMM_WORLD,&status);  /*从进程0接受CNF包信息*/
  165. if ( BufTask <= COUNT)  /*未越界*/
  166. SlaveWork(Cnf,BufTask,&BufResult);  /*从0进程接受任务,计算,将结果返回0进程*/
  167. else break;  /*其它情况*/
  168. }
  169. }
  170. MPI_Finalize();  /*MPI--结束*/
  171. return(0);
  172. }
  173. /******************************************/ 
  174. /*该函数从输入文件读入CNF数据并给Cnf赋值
  175. 输入:in一包含CNF数据的文件
  176. 输出:pCnf一个指向Cnf结构的指针*/ 
  177. /******************************************/ 
  178. void InitCNF(struct CNF * pCnf,FILE* in)  /*从输入文件中读取数据并初始化CNF(参数:CNF式指针,处理文件)*/
  179. {
  180. char prestr[MAXLINE];  /*文件缓存字符数组*/
  181. int i,j,temp;
  182. for(i=0;i<NVARS;i++)  /*在给定的变量数目范围(100)内*/
  183. pCnf->var[i].value=UNCERTAIN;  /*给CNF式变量赋初值(-1)*/
  184. for (i=0;i<NCLAUSES;i++) {  /*在给定的子句数目范围(350)内*/
  185. for (j=0;j<LENGTH_CLAUSE;j++) {  /*在给定的子句长度范围(3)内*/
  186. fscanf(in,"%d",&pCnf->clause[i].lit[j].value);  /*给CNF式文字赋初值*/
  187. /* printf("%d ",&ilauses[c].lit[l]); */
  188. }
  189. fscanf(in,"%d",&temp);  /*其它读入的值存入临时变量中*/
  190. /* printf("%d n",temp); */
  191. pCnf->clause[i].num_unassigned=LENGTH_CLAUSE;  /*子句中未赋值数取为子句长度*/
  192. pCnf->clause[i].state_of_satisfied=UNCERTAIN;  /*子句状态取为不确定(-1)*/
  193. }
  194. pCnf->num_uncertain=NVARS;  /*CNF中未赋值数取为变量最大数目(100)*/
  195. pCnf->result=UNCERTAIN;  /*CNF结果取为不确定(-1)*/
  196. fclose(in);  /*关闭处理文件*/
  197. }
  198. /******************************************/ 
  199. /*该函数计算结果是最主要的函数
  200. 输入:Cnf一个CNF结构
  201. 输出:DavisPutnam取值TRUE或FALSE*/ 
  202. /******************************************/ 
  203. int DavisPutnam(struct CNF  Cnf)  /*测试子句是否为SAT(参数:CNF式)*/
  204. {
  205. int Serial;/*number of the var to be signed*/  /*待赋值的变量数*/
  206. /*test if this Cnf has had the result*/
  207. if (Cnf.result==TRUE) return TRUE;  /*如果CNF的一部分的结果取为真,返回真*/
  208. if (Cnf.result==FALSE) return FALSE;  /*如果CNF的一部分的结果取为假,返回假*/
  209. /*test if Cnf has unit clause*/
  210. if (HasUnitClause(Cnf,&Serial)==TRUE )  /*CNF含有单子句*/
  211. {
  212. Cnf.var[Abs(Serial)].value=(Serial>0)?TRUE:FALSE;  /*CNF变量赋值(0或1)*/
  213. printf("nsingle%d",Serial);
  214. UpdateCNF(&Cnf,Abs(Serial));  /*为变量赋新值时更新CNF*/
  215. if (Cnf.result==TRUE) return TRUE;  /*如果CNF的一部分的结果取为真,返回真*/
  216. if (Cnf.result==FALSE) return FALSE;  /*如果CNF的一部分的结果取为假,返回假*/
  217. if (DavisPutnam(Cnf)==TRUE) return TRUE;  /*如果CNF的一部分测试子句后的结果取为真,返回真*/
  218. else return FALSE;  /*其它情况,返回假*/
  219. }
  220. /*test if Cnf has pure literal*/
  221. else if (HasPureLiteral(Cnf,&Serial)==TRUE )  /*CNF含有纯文字*/
  222. {
  223.         Cnf.var[Serial].value=TRUE;  /*CNF变量赋值为真(1)*/
  224. printf("nPure %d",Serial);
  225. UpdateCNF(&Cnf,Serial);  /*为变量赋新值时更新CNF*/
  226. if (Cnf.result==TRUE) return TRUE;  /*如果CNF的一部分的结果取为真,返回真*/
  227. if (Cnf.result==FALSE) return FALSE;  /*如果CNF的一部分的结果取为假,返回假*/
  228. if (DavisPutnam(Cnf)==TRUE) return TRUE;  /*如果CNF的一部分测试子句后的结果取为真,返回真*/
  229. else return FALSE;  /*其它情况,返回假*/
  230. }
  231. /*pick a var without value*/
  232.      else  /*CNF不只含有单个文字且不含有纯文字*/
  233.  {
  234. for(Serial=0;Serial<NVARS;Serial++)  /*在给定的变量数目范围(100)内*/
  235. if (Cnf.var[Serial].value==NOVALUE)  break;  /*CNF式中变量没有值,退出*/
  236. printf("ncommon%d",Serial);
  237. /*first assume this var is TRUE*/
  238. Cnf.var[Serial].value=TRUE;  /*CNF变量赋值为真(1)*/
  239. UpdateCNF(&Cnf,Serial);  /*为变量赋新值时更新CNF*/
  240. if (Cnf.result==TRUE) return TRUE;  /*CNF式中变量值为真(1),返回真(1)*/
  241. else if (Cnf.result==UNCERTAIN)  /*CNF式中变量值不确定*/
  242. if (DavisPutnam(Cnf)==TRUE) return TRUE;  /*如果CNF的一部分测试子句后的结果取为真,返回真*/
  243. /*Else try that #Serial is FALSE*/
  244. Cnf.var[Serial].value=FALSE;  /*CNF变量赋值为真(1)*/
  245. /*update Cnf when #Serial is FALSE*/
  246. Reverse(&Cnf,Serial);  /*将CNF从失败信号中恢复出来*/
  247. if (Cnf.result==TRUE) return TRUE;  /*如果CNF的一部分的结果取为真,返回真*/
  248. if (Cnf.result==FALSE)  return FALSE;  /*如果CNF的一部分的结果取为假,返回假*/
  249. if (DavisPutnam(Cnf)==TRUE) return TRUE;  /*如果CNF的一部分测试子句后的结果取为真,返回真*/
  250.   return FALSE;  /*其它情况,返回假(0)*/
  251.  }
  252. }
  253. /******************************************/ 
  254. /*该函数检查Cnf是否有单元字句
  255. 输入:Cnf一个CNF结构,Serial变量的编号
  256. 输出:HasUnitClause取值为TRUE或FALSE*/ 
  257. /******************************************/ 
  258. int HasUnitClause(struct CNF  Cnf,int *Serial)  /*测试CNF是否含有单子句(参数:CNF式,指向变量的指针)*/
  259. {
  260. int i,j,k;
  261. for (i=0;i<NCLAUSES;i++)  /*在给定的子句数目范围(350)内*/
  262. if (Cnf.clause[i].num_unassigned==1)  /*子句中未赋值数为1*/
  263. {
  264. for(j=0;j<LENGTH_CLAUSE;j++)  /*在给定的子句长度范围(3)内*/
  265. {
  266. k=Cnf.clause[i].lit[j].value;  /*k暂时存放子句中相应的文字的值*/
  267. if (Cnf.var[Abs(k)].value==NOVALUE)  /*CNF中相应变量没有值*/
  268. {
  269. *Serial=k;  /*相应变量赋值*/
  270. return TRUE;  /*返回真(1)*/
  271. }
  272. }
  273. }
  274. *Serial=0;  /*变量指针格式化*/
  275. return FALSE;  /*其它情况,返回假(0)*/
  276. }
  277. /******************************************/ 
  278. /*该函数检查Cnf是否有纯文字
  279. 输入:Cnf一个CNF结构,Serial变量的编号
  280. 输出:HasPureLiteral取值TRUE或FALSE*/ 
  281. /******************************************/ 
  282. int HasPureLiteral(struct CNF  Cnf,int* Serial)  /*测试CNF是否含有纯文字(参数:CNF式,指向变量的指针)*/
  283. {
  284. int i,j,k,in_flag=FALSE;  /*标记初始设为假*/
  285. for(i=0;i<NVARS;i++)  /*在给定的变量数目范围(100)内*/
  286. if (Cnf.var[i].value==NOVALUE)  /*CNF中相应变量没有值*/
  287. {
  288. for(j=0;j<NCLAUSES;j++)  /*在给定的子句数目范围(350)内*/
  289. {
  290. for(k=0;k<LENGTH_CLAUSE;k++)  /*在给定的子句长度范围(3)内*/
  291. if (Cnf.clause[j].lit[k].value==-i) break;  /*子句中相应的文字的值为对应的负值,退出*/
  292. else if (Cnf.clause[j].lit[k].value==i) in_flag=TRUE;  /*子句中相应的文字的值为对应的正值,标记设为真*/
  293. if( k < LENGTH_CLAUSE ) break;  /*子句长度小于其最大值(3),退出循环*/
  294. }
  295. if(in_flag && j==NCLAUSES)  /*标记为真且在给定的子句数目范围(350)内*/
  296. {
  297. *Serial=i;  /*相应变量赋值*/
  298. return TRUE;  /*返回真(1)*/
  299. }
  300. }
  301. *Serial=0;  /*变量指针格式化*/
  302. return FALSE;  /*其它情况,返回假(0)*/
  303. }
  304. /******************************************/ 
  305. /*该函数根据变量NO.Serial设置Cnf的值
  306. 输入:Cnf一个CNF结构,Serial变量编号*/ 
  307. /******************************************/ 
  308. void UpdateCNF(struct CNF  * Cnf,int Serial)  /*为变量赋新值时更新CNF(参数:CNF式,整型变量)*/
  309. {
  310. int i,j;
  311. Cnf->num_uncertain--;  /*CNF式中未赋值数减1*/
  312. for(i=0;i<NCLAUSES;i++)  /*在给定的子句数目范围(350)内*/
  313. for(j=0;j<LENGTH_CLAUSE;j++)  /*在给定的子句长度范围(3)内*/
  314. if (Cnf->clause[i].lit[j].value==Serial || Cnf->clause[i].lit[j].value==-Serial)  /*子句中相应的文字的值为对应的变量正值或负值*/
  315. {
  316. Cnf->clause[i].num_unassigned--;  /*子句中未赋值数减1*/
  317. if(Cnf->clause[i].lit[j].value==Abs(Serial)&&Cnf->var[Abs(Serial)].value==TRUE  /*子句中相应的文字的值为对应的变量正值且CNF中相应变量为真(1)*/
  318. || Cnf->clause[i].lit[j].value==-Abs(Serial) && Cnf->var[Abs(Serial)].value==FALSE)  /*子句中相应的文字的值为对应的变量负值且CNF中相应变量为假(0)*/
  319. {
  320. /*printf("this is result %dn",Cnf->result);*/
  321. Cnf->clause[i].state_of_satisfied=TRUE;  /*子句设为满足条件*/
  322. }
  323. else if (Cnf->clause[i].num_unassigned==0)  /*子句中未赋值文字为0*/
  324. if(Cnf->clause[i].state_of_satisfied==UNCERTAIN)  /*子句是否满足条件不确定*/
  325. {
  326. Cnf->clause[i].state_of_satisfied=FALSE;  /*子句设为不满足条件*/
  327. Cnf->result=FALSE;  /*CNF结果设为假(0)*/
  328. }
  329. }
  330. for(i=0;i<NCLAUSES;i++)  /*在给定的子句数目范围(350)内*/
  331. if(Cnf->clause[i].state_of_satisfied==FALSE)  /*子句不满足条件*/
  332. {
  333. Cnf->result=FALSE;  /*CNF结果设为假(0)*/
  334. return ;
  335. }
  336. else if(Cnf->clause[i].state_of_satisfied==UNCERTAIN)  /*子句是否满足条件不确定 */
  337. {
  338. Cnf->result=UNCERTAIN;  /*子句是否满足条件设为不确定*/
  339. return;
  340. }
  341. Cnf->result=TRUE;  /*CNF结果设为真(1)*/
  342. }
  343. /******************************************/ 
  344. /*当我们将一个错误的值赋于一个变量时,我们必须将Cnf转置到可能争取的状态
  345. 输入:Cnf一个指向CNF结构的指针,Serial变量的编号
  346. 输出:Cnf*/ 
  347. /******************************************/ 
  348. void Reverse(struct CNF * Cnf,int Serial)  /*将CNF从失败信号中恢复出来(参数:CNF式,整型变量)*/
  349. {
  350. int i,j,k,temp;
  351. for(i=0;i<NCLAUSES;i++)  /*在给定的子句数目范围(350)内*/
  352. for(j=0;j<LENGTH_CLAUSE;j++)  /*在给定的子句长度范围(3)内*/
  353. if (Cnf->clause[i].lit[j].value==Serial)  /*子句中相应的文字的值为对应的变量正值*/
  354. /*#Serial is in this clause and it is positive*/
  355. {
  356. /*judge if this clause can be satisfied*/
  357. for(k=0;k<LENGTH_CLAUSE;k++)  /*在给定的子句长度范围(3)内*/
  358. if((temp=Cnf->clause[i].lit[k].value)==Abs(temp) 
  359. && Cnf->var[Abs(temp)].value==TRUE  /*子句中相应的文字的值为对应的变量正值且CNF中相应变量为真(1)*/
  360. ||temp==-Abs(temp) && Cnf->var[Abs(temp)].value==FALSE)  /*子句中相应的文字的值为对应的变量负值且CNF中相应变量为假(0)*/
  361. break;
  362. if(k==LENGTH_CLAUSE)  /*到达子句末尾*/
  363. /*if k=LENGTH_CLAUSE then this clause can't be satisfied,so the CNF can't be satisfied*/
  364. {
  365. Cnf->clause[i].state_of_satisfied=FALSE;  /*子句是否满足条件设为假(0)*/
  366. Cnf->result=FALSE;  /*CNF结果设为假(0)*/
  367. }
  368. }
  369. else if (Cnf->clause[i].lit[j].value==-Serial)/*if*/  /*子句中相应的文字的值为对应的变量正值*/
  370. Cnf->clause[i].state_of_satisfied=TRUE;  /*子句是否满足条件设为真(1)*/
  371. for(i=0;i<NCLAUSES;i++)  /*在给定的子句数目范围(350)内*/
  372. if(Cnf->clause[i].state_of_satisfied==FALSE)  /*子句是否满足条件为假(0)*/
  373. {
  374. Cnf->result=FALSE;  /*CNF结果设为假(0)*/
  375. return ;
  376. }
  377. else if(Cnf->clause[i].state_of_satisfied==UNCERTAIN)  /*子句是否满足条件为不确定*/
  378. {
  379. Cnf->result=UNCERTAIN;  /*CNF结果设为不确定--以后确定*/
  380. return;
  381. }
  382. Cnf->result=TRUE;  /*CNF结果设为真(1)*/
  383. }
  384. /*****************************************/ 
  385. /*该函数返回一个整数的绝对值*/ 
  386. /*****************************************/ 
  387. int Abs(int i)  /*返回变量的绝对值(参数:整型变量)*/
  388. {
  389. if(i>0) return i;  /*正数情况*/
  390. return -i;  /*负数情况*/
  391. }
  392. /****************************/ 
  393. /*该函数返回一个整数x的y次方*/ 
  394. /****************************/ 
  395. int Pow(int x,int y)
  396. {
  397. int i,res=1;
  398. for(i=0;i<y;i++) res=res*x;
  399. return res;
  400. }
  401. /******************************************/ 
  402. /*因为CNF结构不是一个MPI类型,当我们要广播它的时候我们必须将其压成另一种形式
  403. 输入:Cnf一个CNF结构
  404. 输出:一个整数缓冲*/ 
  405. /******************************************/ 
  406. void PackCNF(struct CNF Cnf,int buf[])  /*将CNF打包到整型缓冲--便于MPI广播(参数:CNF式,整型缓存)*/
  407. {
  408. int i=0,j,k;
  409. buf[i++]=Cnf.num_uncertain;  /*整型缓冲第一个元素为CNF式不确定变量数*/
  410. buf[i++]=Cnf.result;  /*整型缓冲第二个元素为CNF式结果*/
  411. for(j=0;j<NVARS;j++)  /*在给定的变量数目范围(100)内*/
  412. buf[i++]=Cnf.var[j].value;  /*给整型缓冲其它元素赋CNF式相应变量的值*/
  413. for(j=0;j<NCLAUSES;j++)  /*在给定的子句数目范围(350)内*/
  414. {
  415. buf[i++]=Cnf.clause[j].num_unassigned;  /*整型缓冲接下来第一个元素为子句不确定文字数*/
  416. buf[i++]=Cnf.clause[j].state_of_satisfied;  /*整型缓冲接下来第二个元素为子句状态*/
  417. for(k=0;k<LENGTH_CLAUSE;k++)  /*在给定的子句长度范围(3)内*/
  418. buf[i++]=Cnf.clause[j].lit[k].value;  /*给整型缓冲其它元素赋子句相应文字的值*/
  419. }
  420. }
  421. /******************************************/ 
  422. /*该函数是PackCNF函数的反函数
  423. 输入:buf一个整数缓冲
  424. 输出:pCnf一个指向CNF结构的指针*/ 
  425. /******************************************/ 
  426. void UnpackCNF(struct CNF * pCnf,int buf[])  /*将缓冲中的CNF解包(参数:CNF式,整型缓存)*/
  427. {
  428. int i=0,j,k;
  429. pCnf->num_uncertain=buf[i++];  /*CNF式不确定变量数为整型缓冲第一个元素*/
  430. pCnf->result=buf[i++];  /*CNF式结果为整型缓冲第二个元素*/
  431. for (j=0;j<NVARS;j++)  /*在给定的变量数目范围(100)内*/
  432. pCnf->var[j].value=buf[i++];  /*给CNF式相应变量赋整型缓冲其它元素的值*/
  433. for (j=0;j<NCLAUSES;j++)  /*在给定的子句数目范围(350)内*/
  434. {
  435. pCnf->clause[j].num_unassigned=buf[i++];  /*子句不确定文字数为整型缓冲接下来第一个元素*/
  436. pCnf->clause[j].state_of_satisfied=buf[i++];  /*子句状态为整型缓冲接下来第二个元素*/
  437. for(k=0;k<LENGTH_CLAUSE;k++)  /*在给定的子句长度范围(3)内*/
  438. pCnf->clause[j].lit[k].value=buf[i++];  /*给子句相应文字赋整型缓冲其它元素的值*/
  439. }
  440. }
  441. /******************************************/ 
  442. /*该函数将任务数转换为变量的值
  443. 输入:x任务
  444. 输出:pCnf一个指向CNF结构的指针*/ 
  445. /******************************************/ 
  446. void SetValue(struct CNF * pCnf,unsigned x)  /*在任务中为变量设值并更新CNF(参数:指向CNF式的指针,无符号整型变量--任务数)*/
  447. {
  448. int i;
  449. for (i=0;i<DEPTH;i++)  /*在计算深度范围(5)内*/
  450. {
  451. pCnf->var[i].value=GetBits(x,i);  /*CNF式相应变量赋值为任务数*/
  452. UpdateCNF(pCnf,i);  /*为变量赋新值时更新CNF*/
  453. if(pCnf->result==TRUE)  /*CNF式结果为真*/
  454. return;
  455. else if (pCnf->result==FALSE)  /*CNF式结果为假*/
  456. return;
  457. }
  458. }
  459. /******************************************/ 
  460. /*从x右边取出NO.n位
  461. 输入:x取出位的源
  462. 输出:GetBits取值为0或1*/ 
  463. /******************************************/ 
  464. unsigned GetBits(unsigned x,int n)  /*从变量相应位上取值(参数:无符号整型变量,整型变量--取值位置)*/
  465. {
  466. return (x>>n) & ~(~0 << 1);  /*从变量相应位上取值*/
  467. }
  468. /******************************************/ 
  469. /*该函数由从进程执行执行,计算该任务的结果并将其送回根进程
  470. 输入:Cnf一个CNF结构,i任务*/
  471. /******************************************/ 
  472. void SlaveWork(struct CNF Cnf,unsigned i,int BufVar[])  /*从进程的工作--从0进程接受任务,计算,将结果返回0进程*/
  473. {
  474. int BufResult;
  475. SetValue(&Cnf,i); /*,BufVar);*/  /*在任务中为变量设值并更新CNF*/
  476. if( DavisPutnam(Cnf)==TRUE )  /*子句为SAT*/
  477. {
  478. BufResult=TRUE;  /*缓存结果为真(1)*/
  479. MPI_Send(&BufResult,1,MPI_INT,0,0,MPI_COMM_WORLD);  /*MPI--发送缓存结果到0进程*/
  480. }
  481. else  /*子句不为SAT*/
  482. {
  483. BufResult=FALSE;  /*缓存结果为假(0)*/
  484. MPI_Send(&BufResult,1,MPI_INT,0,0,MPI_COMM_WORLD);  /*MPI--发送缓存结果到0进程*/
  485. }
  486. }
  487. /******************************************/
  488. /*该函数从cnf中选取需要的变量
  489. 输入:Cnf一个CNF结构
  490. 输出:BufVar变量缓冲*/
  491. /******************************************/
  492. void PickVars(struct CNF Cnf,int BufVar[])  /*从CNF中选取相应变量(参数:CNF式,整型缓存)*/
  493. {
  494. int i,j,k=0,l=0,m;
  495. for(i=0;i<DEPTH;i++)  /*在计算深度范围(5)内*/
  496. if(HasUnitClause(Cnf,&j)==TRUE && NotInBuf(BufVar,Abs(j))) /*CNF含有单子句且没有变量在缓冲中*/
  497. {
  498. /*printf("nsingle!");*/
  499. BufVar[i]=Abs(j);  /*整型缓存中相应的值为单个子句的值*/
  500. }
  501. else if (HasPureLiteral(Cnf,&j)==TRUE && NotInBuf(BufVar,Abs(j)))  /*CNF含有纯文字且没有变量在缓冲中*/
  502. {
  503. /*printf("npure!");*/
  504. BufVar[i]=Abs(j);  /*整型缓存中相应的值为单个子句的值*/
  505. }
  506. else 
  507. {
  508. m=Abs(Cnf.clause[k].lit[l].value);  /*临时变量赋值为子句中相应文字的值*/
  509. while(!NotInBuf(BufVar,m))  /*当临时变量不在整型缓存中时循环*/
  510. {
  511. if (l>LENGTH_CLAUSE)  /*超出子句长度范围(3)*/
  512. {
  513. l=0;
  514. k++;
  515. }
  516. else l++;  /*子句中文字序号增加1*/
  517. m=Abs(Cnf.clause[k].lit[l].value);  /*临时变量赋值为子句中相应文字的值*/
  518. /*printf("nm=%d",m);*/
  519. }
  520. BufVar[i]=m;  /*整型缓存中相应元素的值设为临时变量的值*/
  521. }
  522. }
  523. /******************************************/
  524. /*该函数检查变量I是否在这个缓冲中
  525. 输入:Buf包含变量的缓冲,i整数
  526. 输出:NotInBuf取值0或1*/
  527. /******************************************/
  528. int NotInBuf(int Buf[],int i)  /*测试变量是否在缓冲中(参数:整型缓存,整型变量)*/
  529. {
  530. int j;
  531. for(j=0;j<DEPTH;j++)  /*在计算深度范围(5)内*/
  532. if (i==Buf[j]) return 0;  /*变量在缓冲中,返回0--判断时为假*/
  533. return 1;  /*变量不在缓冲中,返回1--判断时为真*/