【问题标题】:Optimizing a Huge "OR" Pattern [closed]优化巨大的“或”模式[关闭]
【发布时间】:2013-05-01 14:32:34
【问题描述】:

我有一个“OR”模式,如下例所示: (X Y Z) | (X Y A B) | (X A K) | (MA J K) | (马甲乙) | (M Z)。 我的问题是我的实际问题的 OR'ed 操作数的数量是巨大的,并且会导致大量的内存消耗问题。

但是,构成模式本身的条目很少(X、Y、Z、A、B、K、M 和 J)。 因此,将该模式转换(优化)为如下模式: (X ((Y (Z | (A B))) | (A K))) | (M ((A ((J K) | B)) | Z)) ,很可能会解决我的记忆问题。

我需要一个算法来获取输入模式(可能是字符串)和 生成优化的(也可能是字符串)。

【问题讨论】:

  • 抱歉,我们无法提供帮助。尝试自己写,遇到问题有问题再回来。
  • 用什么语言?因为这很容易,如果我知道我在回答什么,我只需要一两分钟
  • 我已经尝试解决这个问题,但是失败了。也许它需要额外的努力。 @AngryDuck 我需要一个算法而不是代码。这可能看起来微不足道,但我没有实现它。
  • 算法不是代码......好的......那么你打算如何编写/实现这个算法
  • 对于给定的非最优子句,最优简化的等效子句是什么?

标签: regex algorithm optimization tree logic


【解决方案1】:

请注意(XA)|(XB) = X(A|B)。基于这个属性,我可以提出以下贪婪的解决方案:

P 为表达式,XP 中最常见的条目:P = (XR1)|(XR2)|...|(XRn)|Q。那么,去掉括号中的XP可以表示为P = XR | Q,其中R = (R1|R2|...|Rn)。完成后,递归求解 RQ 的问题。

【讨论】:

  • 这听起来合乎逻辑。谢谢:)
  • 如果这些是序列,那么(AX)|(BX) = (A|B)X 也是如此,但您的方法不会简化这些。 (如果它们是布尔值也是如此,但处理起来更简单:只需在开始之前将所有它们按一致的顺序排列即可。)
  • @rici 能够简化这两种模式并不是一件简单的工作。确实AB|AMY|XY = A(B|MY)|XY = AB|(AM|X)Y 并不能同时简化AY。是不是很难确定哪个更好?
  • @viercc:有客观指标。例如,您可以使用结果表达式的运算符计数。但这不是重点。在某些情况下,右侧的简化显然很重要,例如:(AXYZ)|(BXYZ)。完全不能这样做是次优的,并且没有明显的理由期望大多数简化是前缀而不是后缀。
  • @rici 我明白了。很明显,获得更多的简化能力是一种改进。
【解决方案2】:

一般来说,布尔表达式的简化是 NP 难的(例如,参见 Is minimization of boolean expressions NP-Complete?)。

如果您最多有 8 个文字或非否定变量,则最多有 256 个可能的 min-terms,这不是一个很大的数字,所以我想您有比 8 个更多的变量。考虑使用 Quine-McCluskey Method简化你的表达,而不是一些特别的方法。或者,如果变量的数量很大但不是很大(例如,小于 64 的某个小的倍数),则将每个最小项表示为位掩码,并在您读入它们时将它们一起表示为 OR 项,而不是象征性地评估。

【讨论】:

    【解决方案3】:

    通过regex标签的使用,我推断要优化的表达式是正则表达式,而不是布尔表达式。

    正则表达式可以很容易地简化为 DFA(状态机),尽管状态的数量在正则表达式的大小上可能呈指数级增长。拥有 DFA 后,您可以使用其中一种众所周知的算法来处理 minimizing DFAs;在O(n log n) 中做到这一点并不难,其中n 是状态数。

    一个好的正则表达式库应该能够为您完成所有这些工作,但很多都不能。你可能想看看Ragel

    如果您的正则表达式的 DFA 实际上比正则表达式大得多(这种情况很少见但并非完全未知),您可能会发现上述过程确实会耗尽内存。出于这个原因,许多正则表达式库没有执行完整的 DFA 缩减;相反,它们仅简化为 NFA,然后懒惰地执行 powerset 构造,缓存结果。这应该以增加扫描时间为代价避免内存问题。

    显示指数膨胀的正则表达式示例:

    A(A|B)(A|B)(A|B)(A|B)(A|B)(A|B)
    

    对应的 DFA 必须至少有 32 个状态(即 25 其中5(A|B) 的重复次数。

    【讨论】:

    • 谢谢。我会看看 Ragel,然后会回复你:)
    猜你喜欢
    • 2012-01-10
    • 2015-01-07
    • 2015-04-27
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    相关资源
    最近更新 更多