子集查找算法


9

假设我有一个列表子集的。如有必要,我可以对此列表进行预处理。进行此预处理后,将看到另一个集合。我想用来识别任何集合。X{1,...,n}A{1,...,n}BXBA

最明显的算法(无任何预处理)需要时间 -您只需测试针对每个分开。有什么比这更好的了吗?O(n|X|)ABX

如果有帮助,您可以假设,对于任何,匹配的总数都由类的东西来界定。ABXO(1)

Answers:


3

这不是答案。这是一个简单但长期的观察。我希望它会有用。

您问题的决策版本是:是否包含的子集?XA

此问题与评估变量的单调布尔函数的问题有关。的一个子集相当于一个 -bitstring,所以家庭相当于一个布尔函数的变量。给定一个函数,可以定义不大于的最小单调函数,即。然后将原始问题简化为评估。相反,可以通过将天真地将评估单调布尔函数的问题简化为原始问题。n{1,,n}nXfnffg(y)=(xy,f(x))g(A)f=g或选择使变小的。fX

在实践中,BDD往往运行良好。因此,一种可能的方法是为建立BDD ,从中得出的BDD ,然后评估。的BDD的平均大小必须为,因为存在许多单调布尔函数。因此,从理论上讲,这是一个不好的解决方案。fgggΩ((nn/2))

但是(1)可能会进行更好的分析,并且(2)对该方法可能会有一些调整,使其变得更好。例如,我没有使用的大小和的BDD 大小之间的相关性。(必须存在相关性,但是我不知道它是否简单或可用。)Xg

为了完整起见,下面是用于从的BDD 计算的BDD 的简单算法。 这里是BDD的标准操作。gf

m(x?f1:f0)=x?(m(f0)m(f1)):m(f0)

2
这或多或少地等同于为每个子集预先计算答案,将所有结果缓存在大小为的二叉树中,然后向右查找得到结果(时间)?{1,2,...,n}2nO(n)A
mjqxxxx 2012年

尽管不是问题中所禁止的,但使用指数空间来存储预处理的数据听起来像是在欺骗我。但我可能对最坏情况复杂性教会有偏见。
伊藤刚(Tsuyoshi Ito)2012年

mjqxxxx和Tsuyoshi:我俩都同意。我重写了案文,以便,希望我明确表示同意。:)
Radu GRIGore 2012年

3

也许您可以使用“信息检索”技术:在预处理阶段,构建一个反向索引(在您的情况下,一个简单的二维数组就足够了)以映射元素到中包含它的集合:。n×|X|xi{1,...,n}Xinv(xi)={XjX|xiXj}

设置长度为的整数数组。occ|X|

然后对于每个检索,对于每个进行yiAinv(yi)Xjinv(yi)occ[j]=occ[j]+1

最后,您需要的集合是的集合。|Xj|=occ[j]

您可以通过将两个或多个元素索引在一起来任意加快处理速度(以指数空间为代价)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.