有效地存储和评估大量布尔表达式

时间:2012-07-10 14:52:54

标签: performance algorithm data-structures boolean scalability

我有一个庞大的布尔表达式集(20000)。它们由ANDORNOT运算符以及大量布尔变量A1A2A3 ......组成。 1000)。大多数表达式只包含5个,也许只有20个这些变量。

鉴于变量(A1 = true, A2 = false, A3 = false ...)的赋值,我必须找到那些评估为false的表达式。

将针对多个(10-100)作业评估同一组表达式

为此目的:

  1. 我应该如何在磁盘上存储表达式,以便我可以快速加载和解析它们(我现在将它们作为一些专门的DSL或者或多或少规范化(并且死慢)关系数据结构,但是我可以改变那个)

  2. 是否有快速算法/数据结构用于评估我可以使用的表达式?

  3. JVM上的实现是否存在?

7 个答案:

答案 0 :(得分:5)

您可能希望将表达式转换为Conjunctive Normal Form并合并相似的术语。然后,您可以将表达式双向映射到一组术语,其中任何一个评估为false意味着整个表达式的计算结果为false。对于每个变量赋值,从一组表达式开始,计算CNF项,直到一个计算结果为false。如果该术语为false,则涉及该术语的所有表达式也将为false,因此也可以从集合中删除这些表达式。

如果没有查看表达式,这种方法是否适合您的情况是不容易的 - 使用1000个变量和20000个表达式,可能并不是因为它们有许多共同的CNF术语。

在Java之外,对于更多的表达式,DNF可能更有用,因为它在GPU上的实现是显而易见的。

答案 1 :(得分:2)

SOP对此的回答是将表达式存储为RPN(反向波兰表示法)中的字符串,然后编写一个简单的堆栈机器解析器来评估它们。

通常,RPN字符串的计算速度几乎与已经存储在内的AST(抽象符号树)一样快。并且堆栈机器解析器很容易编写。

答案 2 :(得分:0)

您似乎对Java很感兴趣,但您是否考虑过将这些内容提供给具有eval()函数的语言?它可能会减少将表达式保存在文件中并对其进行评估的问题。请注意,如果您不信任(表达式)表达式,则会产生安全隐患!

Jython浮现在脑海中,但可能会有几个人会对此做很短的工作。

如果你与java结婚,你可能可以为布尔代数实现递归下降解析器。但这涉及到更多。

答案 3 :(得分:0)

更新:以下网站有code可能会有帮助。

将表达式列表转换为函数的源代码,当使用变量值调用时,将评估所有函数并返回指示哪些表达式求值为false。编译该函数,然后调用它以获取不同的变量值。

我做过类似的并使用过Python。我必须编写的唯一解析和解释是将输入布尔运算符'&','|','〜'转换为它们的Python等价物。

对于Python解决方案,您的问题大小似乎相当不错。

答案 4 :(得分:0)

您可以构建一个索引,其中每个变量记录两组表达式,即变量正向出现的变量和负变态出现的表达式。根据变量的值,您可以收集由于此变量而可能变为false的表达式(如果变量设置为false则为正值,反之亦然)。 编辑:这些只是候选人,您仍需要对其进行评估,以确定它们是否真的变为虚假。

与仅评估所有表达式相比,这是否有帮助取决于表达式的结构以及评估为false的数量。

答案 5 :(得分:0)

尝试将它们转换为CNF并使用MiniSat检查表达式是否为真或假

答案 6 :(得分:0)

尝试将它们转换为CNF并使用MiniSat检查表达式是否为true或false 很容易说,你为此编码