我想找出以下两个布尔函数的两个BDD的交集:
F=A'B'C'D'=1
G=A XOR B XOR C XOR D=1下面是我的代码:
int main (int argc, char *argv[])
{
char filename[30];
DdManager *gbm; /* Global BDD manager. */
gbm = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); /* Initialize a new BDD manager. */
DdNode *bdd, *var, *tmp_neg, *tmp,*f,*g;
int i;
bdd = Cudd_ReadOne(gbm); /*Returns the logic one constant of the manager*/
Cudd_Ref(bdd); /*Increases the reference count of a node*/
for (i = 3; i >= 0; i--) {
var = Cudd_bddIthVar(gbm,i); /*Create a new BDD variable*/
tmp_neg = Cudd_Not(var); /*Perform NOT Boolean operation*/
tmp = Cudd_bddAnd(gbm, tmp_neg, bdd); /*Perform AND Boolean operation*/
Cudd_Ref(tmp);
Cudd_RecursiveDeref(gbm,bdd);
f = tmp;
}
for (i = 3; i >= 0; i--) {
var = Cudd_bddIthVar(gbm,i); /*Create a new BDD variable*/
tmp = Cudd_bddXor(gbm, var, bdd); /*Perform AND Boolean operation*/
Cudd_Ref(tmp);
Cudd_RecursiveDeref(gbm,bdd);
g = tmp;
}
bdd= Cudd_bddIntersect(gbm,f,g);/*Intersection between F and G */
bdd = Cudd_BddToAdd(gbm, bdd); /*Convert BDD to ADD for display purpose*/
print_dd (gbm, bdd, 2,4); /*Print the dd to standard output*/
sprintf(filename, "./bdd/graph.dot"); /*Write .dot filename to a string*/
write_dd(gbm, bdd, filename); /*Write the resulting cascade dd to a file*/
Cudd_Quit(gbm);
return 0;
}这是我得到的结果:
DdManager nodes: 7 | DdManager vars: 4 | DdManager reorderings: 0 | DdManager memory: 8949888
: 3 nodes 2 leaves 2 minterms
ID = 0xaa40f index = 0 T = 0 E = 1
0--- 1正如你在这里看到的,交集给出了A=0,而不关心B,C和D。我期望的是A,B,C和D的值,它同时满足F和G。但很明显,A=0不是F和G的解决方案。例如,有人可以选择A=0,B=1,它为函数F提供0。这里有什么问题?
发布于 2016-10-29 01:41:23
这个回复来得太晚了,但为了结束这个问题,问题是Cudd_bddAnd和Cudd_bddXor的最后一个操作数是bdd,而不是f或g。当然,f和g都应该正确初始化( bdd当前的初始化方式)。以这种方式修复代码还会注意到bdd的多次取消引用,如果垃圾收集生效,这将导致痛苦。
此外,Cudd_bddIntersect不计算两个BDD的AND,而是一个隐含AND的函数。当一个人想要证明两个BDD的合取的非空性而不计算整个结果(然后可能从中提取一个见证)时,可以使用它。
最后,bdd既用作Cudd_BddToAdd的操作数,也用作返回值的目的地。这肯定会“泄漏”BDD节点。
https://stackoverflow.com/questions/39030488
复制相似问题