我正在用Java实现。
目前我正在尝试使用BDD(二进制决策图)来存储数据结构中的关系。
E.g。 R = {(3,2),(2,0)}和相应的BDD:
出于这个原因,我一直在寻找具有BDD功能的库,以帮助我。
我发现了两种可能性:JavaBDD和JDD。
但是在这两种情况下,我都不明白如何将一个简单的整数编码为BDD,因为我如何或何时给出整数的值?或者,如果BDD由整数表示,是什么意思?
在这两种情况下,都有类似的方法:
int variable = createBDD(); //(JBDD)
或
BDD bdd = new BDD(1000,1000);
int v1 = bdd.createVar(); // (JDD)
如何像我的例子一样简单地创建BDD?
非常感谢!!
答案 0 :(得分:0)
所以我找到了一个解决方案,但它不是很令人满意,因为我无法知道我用来表示二进制整数的布尔变量有多少布尔变量。所以我必须在开头定义例如:我的所有整数都小于64,因此它们由6个二进制变量表示。如果我想在之后添加一个大于64的整数,我有一个问题,但我不想从头开始使用最大的整数大小,以节省时间,因为我想使用BDD以便节省运行时间,否则比BDD更容易表示元组。
我使用JDD作为我的BDD库,因此在JDD中,BDD表示为整数。
这就是我将如何从整数元组中获取BDD:
在开始时你必须创建BDD变量,maxVariableCount
是二进制变量的最大数量,它代表整数(在本答案的开头说明):
variablesDefinition
只是我想在BDD中稍后表示的整数变量的数量。所以在我的问题变量的例子中,变量定义为2,因为每个元组都有两个整数变量。
数组variables
是一个二维数组,其中包含所有BDD变量。因此,例如,如果我们的元组有2个元素,则表示第一个整数变量的BDD变量可以在variables[0]
中找到。
BDD bddManager = new BDD(1000,100);
private int variablesDefinition;
private int[][] variables;
private void createVariables(int maxVariableCount) {
variables = new int[variablesDefinition][maxVariableCount];
for(int i = 0; i < variables.length; i++) {
for(int j = 0; j < maxVariableCount; j++) {
variables[i][j] = bddManager.createVar();
}
}
}
然后我们可以从给定的整数元组创建一个bdd。
private int bddFromTuple(int[] tuple) {
int result;
result = bddManager.ref(intAsBDD(tuple[0],variables[0]));
for(int i = 1; i < tuple.length; i++) {
result = bddManager.ref(bddManager.and(result, intAsBDD(tuple[i], variables[i])));
}
return result;
}
private int intAsBDD(int intToConvert, int[] variables) {
return bddFromBinaryArray(intAsBinary(intToConvert, variables.length), variables);
}
private int[] intAsBinary(int intToConvert, int bitCount) {
String binaryString = Integer.toBinaryString(intToConvert);
int[] returnedArray = new int[bitCount];
for (int i = bitCount - binaryString.length(); i < returnedArray.length; i++) {
returnedArray[i] = binaryString.charAt(i - bitCount + binaryString.length()) - DELTAConvertASCIIToInt;
}
return returnedArray;
}
static int DELTAConvertASCIIToInt = 48;
private int bddFromBinaryArray(int[] intAsBinary, int[] variables) {
int f;
int[] tmp = new int[intAsBinary.length];
for(int i = 0; i < intAsBinary.length; i++) {
if(intAsBinary[i] == 0) {
if (i == 0) {
tmp[i] = bddManager.ref(bddManager.not(variables[i]));
}
else {
tmp[i] = bddManager.ref(bddManager.and(tmp[i-1], bddManager.not(variables[i])));
bddManager.deref(tmp[i - 1]);
}
}
else {
if (i == 0) {
tmp[i] = bddManager.ref(variables[i]);
}
else {
tmp[i] = bddManager.ref(bddManager.and(tmp[i-1], variables[i]));
bddManager.deref(tmp[i - 1]);
}
}
}
f = tmp[tmp.length-1];
return f;
}
我的第一个目的是将这些元组添加到BDD中,然后能够在BDD中的整数中执行算术函数,但这只有在将BDD转换回元组并执行函数并将其返回到BDD,它破坏了我想使用BDD的所有原因。
答案 1 :(得分:0)
使用k子集编码算法(如lex,colex,revdoor,coolex等)简单编码整数元组。 Lex以字典顺序编码n个整数中的k元组,例如: n = 4,k = 2产生(1基)编码
tuple rank
(0,1) -> 1
(0,2) -> 2
(0,3) -> 3
(1,2) -> 4
(1,3) -> 5
(2,3) -> 6
你需要一个rank(tuple)和unrank(rank)例程来将元组转换为排名和返回。