我们将含有N个逻辑连接词的最小完全集称作N-最小完全集
大体思路
- 用原先判断完全集的方法求256个三元连接词(用0-255表示真值表最后一列的十进制编码值)里有56个1-最小完全集。(给定连接词的集合,通过嵌套连接词生成公式的方式能找到十六个互不等价的逻辑公式,该连结词的集合为完全集)
- 如果一个含n个三元连接词的集合为完全集(n>=2),这意味着这个集合可以通过互相嵌套真值表表出其他任何三元连接词的真值表,那么它也一定可以通过嵌套方式表出56个1-最小完全集或者前边已经得到的完全集:
n=2时,判断三元连接词f(p,q,r)和g(p,q,r)是否组成完全集,采用前者真值表做某些变换后,所得真值表最后一列替换后者真值表前三列,进而计算得到新的三元连接词真值的方式,例如g(f(p,p,p),q,r)h(p,p,r),设置一个深度,用递归方式反复尝试不同嵌套(共有八种),直至得到56个1-完全集之一的真值表,则证明{f,g}是一个2-完全集(不知道是否也可以用产生16个不同真值表的方式判断完全),记录递归过程中嵌套表出的新真值表,如果连续的两个深度,没有新的真值表产生,那么这个连结词的集合一定不完全,如果达到了设置的递归深度未找到56个1-完全集之一,那么我们也暂时认为这个集合不完全,然后f和g调换顺序按递归方式再检测一遍。(其实思路和原来判断完全集的方式类似)。这样的方式我们可以把所有两个连接词的集合都检查一遍,划分为2-完全和2-不完全两类,当然这里的完全集就是2-最小完全集。但是我们的算法毕竟是自己设置的递归深度,不能说明2-不完全的这些集合没有是完全集的,但是好在200个连接词取两个的不同组合一共只有19900种,我们在时间可接受的情况下调整递归深度,连续几个深度时如果求出的2-最小完全集数不再变化,就假设已经完全求出。把剩下的2-不完全集用原方法逐一检测(我们原先判断完全的算法已经改写成批处理算法),确定没有完全集,那么就可以断定求出了所有的2-最小完全集。另外,我们还记录了所有2-不完全集能够表出的真值表(15000*256可存储),这些真值表也一定是完整的。
接下来,我们通过固定一个合适的递归深度,去掉多余的递归条件(有一些递归条件肯定会产生大量重复真值表),同时这也大大优化了程序的效率。最后成功的在保证结果不受影响的前提下去除了六个递归条件,固定递归深度为5,求解时间因而降到了9秒左右。
n=3时,判断三元连接词f(p,q,r),g(p,q,r)和h(p,q,r)是否组成完全集,由于我们已经有了所有的2-最小完全集和2-不完全集以及表出的真值表,我们仅需在2-不完全集中添加一个不是1-完全的连接词,排除其中含有2-完全集的情况,进而判断这个三个连接词集合是否完全即可。到这里,我们不再用递归方式暴力搜索,因为14000多个2-不完全集组合200个1-不完全集的情况太多了。我们已经求出了所有2-不完全集能够表出的真值表(连接词),一个三连接词如果集合完全,它的任意2-不完全子集表出的连接词一定有一个和本集合剩下的那个连接词组成2-最小完全集。这样我们可以很快的求出所有的3-最小完全集和3-不完全集.
n=4时同理n=3,在3-不完全集上添加1-不完全集,排除有2-最小完全子集和3-最小完全子集后,检查任意3-不完全集表出的连接词是否有和剩下的一个连接词组成2-完全集,若有,则集合时4-最小完全,否则是4-不完全集。
求判断2-最小完全的伪代码:
Procedure complete(fuction from,function to, level)
Begin
1 if level = Maxlevel then return false
2 for j=1 to 3 do
3 to[:,j]from[:,4]
4 new_functioncompute_new_truth_table(to)
5 if new_function then return true
6 else 记录from,to这对连接词新表出的new_function
7 if complete(new_function , to , level+1) then return true
8 if complete(new_function , from , level+1) then return true
9 if complete(from , new_function , level+1) then return true
10 if complete(to , new_function , level+1) then return true
11 end for
12 for j=1 to 3 do
13 for k=1 to 3 do
14 tmptab[:,k]to[:,k]
15 end for
16 if j=3 then to[:,j]tmptab[:,1]
17 else to[:,j]tmptab[:,j+1]
18 new_functioncompute_new_truth_table(to)
19 if new_function then return true
20 else 记录from,to这对连接词新表出的new_function
21 if complete(new_function , to , level+1) then return true
22 if complete(new_function , from , level+1) then return true
23 if complete(from , new_function , level+1) then return true
24 if complete(to , new_function , level+1) then return true
25 end for
26 return false
End
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
struct node
{
int arr[8];
int fei;
int lfei;
int rfei;
int ffei;
int xu;
} fyy[300],xll[300];
struct wqj
{
int arr[4][8];
int maxj;
int x,y,z;
} la[5][12000],fla[5][700000];
int zzb[6][4][4];
int zzb8[8][4];
int tmptab[8][4];
int hsh[256],has[256];
int create(int n,int m)
{
int i,sum,tol=0;
for(int i=0; i<4; i++)
{
sum=zzb[m][i][0]*4+zzb[m][i][1]*2+zzb[m][i][2]*1;
zzb[m][i][3]=fyy[n].arr[sum];
if(zzb[m][i][3]==1)tol++;
}
return tol;
}
int vis2[256][256];
int vis3[256][256][256];
void cshzzb()
{
int i,t,k;
memset(zzb8,0,sizeof(zzb8));
for(i=0; i<8; i++)
{
t=i;
k=2;
while(t)
{
zzb8[i][k]=t%2;
k--;
t/=2;
}
}
/*for(i=0;i<8;i++){
for(k=0;k<4;k++){
printf("%d ",zzb8[i][k]);
}
printf("\n");
}*/
}
int op[8],op1[8],op2[8];
int Maxlevel;
int vissum[256];
struct cxf
{
int op[256];
int cnt;
} val[201][201];
int cnum,qi,qj;
int finall(int f,int to,int level)
{
int i,j,k,sum,a,s;
//if(vis2[f][to])return 1;
if(level==Maxlevel)return 0;
for(j=0; j<3; j++)
{
sum=0;
for(i=0; i<8; i++)
{
op[i]=zzb8[i][j];
zzb8[i][j]=xll[f].arr[i];
s=zzb8[i][0]*4+zzb8[i][1]*2+zzb8[i][2];
sum+=xll[to].arr[s]*(int)pow(2.0,7-i);
zzb8[i][j]=op[i];
}
if(hsh[sum]==1)return 1;
else
{
a=has[sum];
if(vissum[sum]==0)
{
val[qi][qj].op[cnum++]=a;
val[qi][qj].cnt=cnum;
vissum[sum]=1;
}
//if(vis2[to][a])return 1;
}
//if(finall(a,to,level+1))return 1;
//if(finall(a,f,level+1))return 1;
//if(finall(f,a,level+1))return 1;
if(finall(to,a,level+1))return 1;
}
for(j=0; j<3; j++)
{
sum=0;
for(i=0; i<8; i++)
{
for(k=0; k<3; k++)
{
tmptab[i][k]=zzb8[i][k];
}
}
if(j==2)
{
for(i=0; i<8; i++)
{
tmptab[i][j]=zzb8[i][0];
}
}
else
{
for(i=0; i<8; i++)
{
tmptab[i][j]=zzb8[i][j+1];
}
}
for(i=0; i<8; i++)
{
s=tmptab[i][0]*4+tmptab[i][1]*2+tmptab[i][2];
sum+=xll[to].arr[s]*(int)pow(2.0,7-i);
}
if(hsh[sum]==1)return 1;
else
{
a=has[sum];
if(vissum[sum]==0)
{
val[qi][qj].op[cnum++]=a;
val[qi][qj].cnt=cnum;
vissum[sum]=1;
}
//if(vis2[to][a])return 1;
}
//if(finall(a,to,level+1))return 1;
//if(finall(a,f,level+1))return 1;
if(finall(f,a,level+1))return 1;
//if(finall(to,a,level+1))return 1;
}
return 0;
}
int s1[256],s2[256],s3[256],s4[256];
int main()
{
int t,i,j,k,tmp,sum;
for(i=0; i<4; i++)
{
zzb[i][0][0]=zzb[i][1][0]=zzb[i][0][2]=zzb[i][2][2]=0;
zzb[i][1][2]=zzb[i][2][0]=zzb[i][3][0]=zzb[i][3][2]=1;
if(i==0)
{
for(j=0; j<4; j++)zzb[i][j][1]=zzb[i][j][0];
}
else if(i==1)
{
for(j=0; j<4; j++)zzb[i][j][1]=!zzb[i][j][0];
}
else if(i==2)
{
for(j=0; j<4; j++)zzb[i][j][1]=zzb[i][j][2];
}
else if(i==3)
{
for(j=0; j<4; j++)zzb[i][j][1]=!zzb[i][j][2];
/*for(j=0;j<4;j++){
for(k=0;k<4;k++)
printf("%d ",zzb[i][j][k]);
printf("\n");
}
printf("\n");*/
}
}
FILE *fp=fopen("test.txt","r");
FILE *fo=fopen("out.txt","w");
FILE *fo3=fopen("out3.txt","w");
FILE *fo4=fopen("out4.txt","w");
int cas=0;
for(i=0; i<256; i++)
{
for(j=0; j<8; j++)
fscanf(fp,"%d",&fyy[i].arr[j]);
/*for(j=0; j<8; j++)
printf("%d",fyy[i].arr[j]);
printf("\n");*/
fyy[i].fei=0;
fyy[i].lfei=0;
fyy[i].rfei=0;
fyy[i].ffei=0;
}
int tol=0;
for(i=0; i<256; i++)
{
if(fyy[i].arr[0]==1&&fyy[i].arr[7]==0)
{
fyy[i].fei=1;
}
else if(fyy[i].arr[0]==1)fyy[i].lfei=1;
else if(fyy[i].arr[7]==0)fyy[i].rfei=1;
for(j=0; j<4; j++)
{
int p=create(i,j);
if(p%2)
{
fyy[i].ffei=1;
break;
}
}
if(fyy[i].fei==1&&fyy[i].ffei==1)
{
sum=0;
for(j=0; j<8; j++)
{
//fprintf(fo,"%d",fyy[i].arr[j]);
sum+=fyy[i].arr[j]*(int)pow(2.0,7- j);
}
//fprintf(fo,"\n");
//fprintf(fo,"D%d\n",sum);
hsh[sum]=1;
}
if(!(fyy[i].fei==1&&fyy[i].ffei==1))
{
sum=0;
for(j=0; j<8; j++)
{
xll[cas].arr[j]=fyy[i].arr[j];
sum+=fyy[i].arr[j]*(int)pow(2.0,7- j);
}
xll[cas].xu=i;
has[sum]=cas;
cas++;
//fprintf(fo,"%d",fyy[i].arr[j]);
//fprintf(fo,"\n");
//fprintf(fo," %d %d %d %d\n",fyy[i].lfei,fyy[i].rfei,fyy[i].fei,fyy[i].ffei);
//tol++;
}
}
//单个完全56个
printf("%d\n",cas);
/*for(i=0; i<cas; i++){
for(j=0; j<8; j++)printf("%d",xll[i].arr[j]);
printf("\n");
}*/
int tol2=0,ftol2=0,p;
int countt=0,t0;
Maxlevel=5;
cshzzb();
memset(vis2,0,sizeof(vis2));
memset(vis3,0,sizeof(vis3));
for(i=0; i<cas; i++)
{
for(j=i+1; j<cas; j++)
{
qi=i,qj=j;
val[qi][qj].cnt=0;
memset(vissum,0,sizeof(vissum));
int r1=finall(i,j,1),r2=finall(j,i,1);
if(r1+r2>0)
{
tol2++;
vis2[i][j]++;
fprintf(fo,"%d %d\n",xll[i].xu,xll[j].xu);
}
else
{
/*for(int k=0; k<8; k++)
{
fla[2][ftol2].arr[0][k]=xll[i].arr[k];
fla[2][ftol2].arr[1][k]=xll[j].arr[k];
}*/
fla[2][ftol2].x=i;
fla[2][ftol2].y=j;
fla[2][ftol2].maxj=j;
ftol2++;
}
cnum=0;
}
}
//两个完全
printf("%d %d\n",tol2,ftol2);
int a,b,c;
int tol3=0,ftol3=0,flag=0;
for(i=0; i<ftol2; i++)
{
for(j=fla[2][i].maxj+1; j<cas; j++)
{
a=fla[2][i].x,b=fla[2][i].y;
if(vis2[a][j]||vis2[b][j])continue;
flag=0;
for(c=0; c<val[a][b].cnt; c++)
{
int yy=val[a][b].op[c];
if(vis2[yy][j]||vis2[j][yy])
{
tol3++;
vis3[a][b][j]++;
fprintf(fo3,"%d %d %d\n",xll[a].xu,xll[b].xu,xll[j].xu);
flag=1;
break;
}
}
if(!flag){
for(c=0; c<val[a][j].cnt; c++)
{
int yy=val[a][j].op[c];
if(vis2[yy][b]||vis2[b][yy])
{
tol3++;
vis3[a][b][j]++;
fprintf(fo3,"%d %d %d\n",xll[a].xu,xll[b].xu,xll[j].xu);
flag=1;
break;
}
}
}
if(!flag){
for(c=0; c<val[b][j].cnt; c++)
{
int yy=val[b][j].op[c];
if(vis2[yy][a]||vis2[a][yy])
{
tol3++;
vis3[a][b][j]++;
fprintf(fo3,"%d %d %d\n",xll[a].xu,xll[b].xu,xll[j].xu);
flag=1;
break;
}
}
}
if(!flag)
{
fla[3][ftol3].x=a;
fla[3][ftol3].y=b;
fla[3][ftol3].z=j;
fla[3][ftol3].maxj=j;
ftol3++;
}
}
}
printf("%d %d\n",tol3,ftol3);
int tol4=0,ftol4=0,d,e,sw,tz;
for(i=0; i<ftol3; i++)
{
for(j=fla[3][i].maxj+1; j<cas; j++)
{
a=fla[3][i].x,b=fla[3][i].y,c=fla[3][i].z;
if(vis2[a][j]>=1||vis2[b][j]>=1||vis2[c][j]>=1)continue;
if(vis3[a][b][j]>=1||vis3[a][c][j]>=1||vis3[b][c][j]>=1)continue;
flag=0;
for(d=0;d<val[a][b].cnt&&!flag;d++){
sw=val[a][b].op[d];
int ma=sw>c?sw:c;
int mi=sw<c?sw:c;
for(e=0;e<val[mi][ma].cnt;e++){
tz=val[mi][ma].op[e];
if(vis2[tz][j]||vis2[j][tz]){
tol4++;
fprintf(fo4,"%d %d %d %d\n",xll[a].xu,xll[b].xu,xll[c].xu,xll[j].xu);
flag=1;
break;
}
}
}
if(!flag){
for(d=0;d<val[a][c].cnt&&!flag;d++){
sw=val[a][c].op[d];
int ma=sw>b?sw:b;
int mi=sw<b?sw:b;
for(e=0;e<val[mi][ma].cnt;e++){
tz=val[mi][ma].op[e];
if(vis2[tz][j]||vis2[j][tz]){
tol4++;
fprintf(fo4,"%d %d %d %d\n",xll[a].xu,xll[b].xu,xll[c].xu,xll[j].xu);
flag=1;
break;
}
}
}
}
if(!flag){
for(d=0;d<val[b][c].cnt&&!flag;d++){
sw=val[b][c].op[d];
int ma=sw>a?sw:a;
int mi=sw<a?sw:a;
for(e=0;e<val[mi][ma].cnt;e++){
tz=val[mi][ma].op[e];
if(vis2[tz][j]||vis2[j][tz]){
tol4++;
fprintf(fo4,"%d %d %d %d\n",xll[a].xu,xll[b].xu,xll[c].xu,xll[j].xu);
flag=1;
break;
}
}
}
}
if(!flag){
ftol4++;
}
}
}
printf("%d %d\n",tol4,ftol4);
printf("%d\n",56+tol2+tol3+tol4);
fclose(fp);
fclose(fo);
fclose(fo3);
fclose(fo4);
return 0;
}