首先:不,这不是功课!这适合我为游戏写作的解算器。我只是将问题简化为这个简洁的陈述:
给定一组S,找到并删除S的任何元素,这些元素是S的其他元素的子集。
域的
1< = | S | < = C ^ K
1< = | S i | < = K
2 <= C <= 10
10 <= K <= 500
详细
S i 是[0,K)
的子集min(| S i |)&gt; = log C (| S |)
我目前的方法是将每个集合保存在S中,通过我称之为&#34; NatSet&#34;这只是bool[K]
。然后我通过| S i |对S进行排序并执行O(| S | ^ 2)搜索以查找作为其他元素子集的元素。不幸的是,这对我的目标值C = 6和K = 16 * 9来说太慢了。
答案 0 :(得分:2)
考虑到我无法尝试(set S
的输入对我来说是不可见的)并决定以下是否有用,我只能给他们一些提示:
比较两套:&#39;缩小&#39; binary search
:当你比较集合A(x1 ... xn)是否是集合B的子集(y1 ... ym)时,假设你找到yk = x1
(n <= m)
y1, y2, ...,yk, yk+1 ... ym
|
x1
然后您可以在x2
范围内搜索[yk+1, ym]
。另一个是相同的。
s1
和sk
,然后s1
和sk-1
),你说你按大小排序,大一个更有可能包含它S
是否可以提高您的效果,您可以尝试不排序或使用max-heap
(参见提示4)
如果没有移除叶子(即,不是它的父亲的子集),只需将其从堆中移除即可将其交换到移除叶子的位置。 (如下图所示)
注意:使用堆不能保证删除所有子集。
更多强>
1.你说你正在砍树,你想要Alpha–beta pruning吗?
2。Efficient list intersection algorithm
希望这会有所帮助。
答案 1 :(得分:0)
这里固有的问题是,给定两个集合,一个具有p个元素,另一个具有q个元素(不失一般性,我们可以说p 根据我的理解,你正在进行O(K ^ 2)搜索,所以你得到总的运行O((n ^ 2)*(K ^ 2)),其中n是S的元素数量你可以使用HashSet方法将它减少到O((n ^ 2)K)。这里是Java http://docs.oracle.com/javase/7/docs/api/java/util/HashSet.html的链接,几乎所有主要语言都在其标准库中有一些实现。虽然如果你的集合S在n = 6 ^(16 * 9)附近,那么我认为这不会有多大帮助(我甚至不确定你是否可以在现代计算机中使用任何相关数据尺寸)。 如果你可以将k驱动到&lt; = 64(或32位系统中的32),你可以使用位图来存储S中的每个集合和并行位操作,以将你的时间减少到O(n ^ 2)。这将等同于您当前的方法,但您只需执行一次或检查它是否等于相同的数字:((a1 | a2)== a1)|| ((a1 | a2)== a2)。这样您就可以在恒定时间内获得并集操作。