6

您如何编写以下算法?

想象一下这样的“事实”列表,其中字母代表绑定到数值的变量:

x = 1
y = 2
z = 3
a = 1
b = 2
c = 3
a = x
b = z
c = z

这些“事实”显然不一定都是“真实的”:b=z 而 b=2 和 z=3 是不可能的。如果 b=z 或 b=2 被删除,所有事实都将是一致的。如果 z=3 并且 b=z 或 c=z 被删除,那么所有事实都将是一致的,但会比上面少一个事实。该集合包含许多这样的一致子集。例如,a=1、b=2、c=3 是一致的子集,许多其他子集也是如此。

在此示例中,两个一致子集大于任何其他一致子集:

x = 1
y = 2
z = 3
a = 1
b = 2
c = 3
a = x
c = z

x = 1
y = 2
z = 3
a = 1
c = 3
a = x
b = z
c = z

使用适当的编程语言(我在想 PROLOG,但也许我错了)你将如何处理包含一致和不一致事实的大集合,然后输出最大可能的一致事实子集(或多个子集,如上面的例子)?

4

2 回答 2

5

这与 NP-hard 多路切割问题密切相关。在(未加权)多路切割问题中,我们有一个无向图和一组终端顶点。目标是删除尽可能少的边,以便每个终端顶点位于其自己的连接组件中。

对于这个问题,我们可以将每个变量和每个常量解释为一个顶点,将每个等式解释为从其左侧到右侧的一条边。终端顶点是与常数相关联的顶点。

对于只有两个终端,多路割问题是多项式时间可解的 st 最小割问题。我们可以使用最小割来获得多路割问题的多项式时间 2 逼近,方法是找到分离两个终端的最便宜割,删除所涉及的边,然后在剩余的连接组件上递归。在多路切割的理论文献中已经提出了几种具有更好比率的近似算法。

实际上,多路切割出现在计算机视觉的应用中,所以我希望在获得精确解决方案方面已经做了一些工作。不过,我不知道外面有什么。

于 2014-09-13T23:34:58.970 回答
0

Prolog 可以作为一种方便的实现语言,但对算法的一些思考表明,一种专门的方法可能是有利的。

在这些类型的陈述中(两个变量之间或一个变量和一个常数之间的相等性),唯一可能出现的不一致是连接两个不同常数的路径。

因此,如果我们找到连接不同常数对的所有“不一致”路径,则有必要且足够找到断开所有这些路径的一组边(原始等式)。

很容易认为贪心算法在这里是最优的:总是选择一条边来删除,这条边对​​于最大数量的剩余“不一致”路径是常见的。因此我提议:

1) 找出所有P连接两个不同常数的简单路径(不经过任何第三个常数),并在这些路径及其边之间构造一个链接结构。

E2)计算沿那些“不一致”路径出现的边缘的频率P

3)通过采用贪心策略找到足够数量的边来删除,删除最常出现的下一条边并相应地更新剩余路径中的边数。

4) 考虑到需要删除的边的上限(以保留一致的语句子集),应用回溯策略来确定是否有更少量的边就足够了。


如应用于问题中的示例,证明恰好有两个“不一致”路径:

    2 -- b -- z -- 3
 2 -- b -- z -- c -- 3

删除这两条路径共有的两条边中的任何一条,2 -- bb -- z足以断开两条“不一致”路径(删除剩余语句之间的所有不一致)。

此外,很明显,没有其他单个边缘的去除足以实现这一点。

于 2014-09-15T01:18:40.403 回答