遗传性下的极大集

时间:2011-11-23 17:48:25

标签: algorithm

我在S的子集上有一个集合S和一个布尔值函数f。函数f具有“遗传属性”:如果f(A)为真且B是A的子集,则f(B)是的。

是否有算法可以找到S的最大子集,其中f的计算结果为真?在f(A)为真的意义上,集合A是最大的,但如果B包含A并且大于A,则f(B)为假。

3 个答案:

答案 0 :(得分:1)

使用回溯。伪代码:

def A(c,r,u):
    # c - current set
    # r - remaining elements
    # u - unused, forbidden elements
    if r == []:
        for i in u:
            if f(c + [i]):   # Check if c is really maximal
               return
        print c
    else:
        x = r[0]
        r' = r without first element
        if f(c + [x]):
            A(c + [x], r', u)
        A(c, r', u + [x])

运行A([],[a_1,a_2,...,a_n],[])

这具有指数复杂性,你无法避免它,例如,如果f(A)= A A最多有n / 2个元素,则指数多个最大集合。你需要更多地考虑f以获得更好的算法。

答案 1 :(得分:0)

遗传属性可以让您对搜索空间进行很好的修剪。如果元素已经存在,则对元素创建排序。然后,只创建具有已排序元素的集合。

从单元素集开始 - 找到满足......(1)

的集合

然后创建所有两个元素集 - 对于每个元素集,尝试追加(1)中更大的所有集合...(2)重要:记住它们的关系:for sets {s}和{b}( s< b)from(1)如果{s,b}在(2)中,请记住{s,b} .tail为{b}并将{s,b}添加到集合{s} .offspring。

现在只需要增加元素数量。叫(2)“旧”并开始创建“新”。对于旧的每个s,尝试在s.tail.offspring中追加每个t,用另外一个元素形成集合。如果满足,则将其添加到“new”,将其.tail(设置为t)设置为s.offspring。因此,您将获得所有令人满意的3元素。 (为了优化你现在可以忘记来自“old”的所有.tails并让gc摆脱上一代)重复从3元素中获取4个元素等。

最大集是那些在s时不成功的集,也是空的.offspring。

答案 2 :(得分:0)

评估f意味着测试CNF公式的可满足性。我倾向于将搜索最大集合与SAT求解器集成。

DPLL基础开始,进行以下修改。

  1. true false 外,还可以删除变量。当DPLL选择要分支的变量时,分支会有三种方式。

  2. 单位传播是相同的。

  3. 纯文字消除现在不起作用。但是,我们可以对纯变量(有用的真值或删除)进行双向分支,而不是三向分支。

  4. 逐步检查对于每个已分配的变量,是否只有该分配满足的子句。如果没有,修剪 - 这个子树不包含最大解。

  5. 如果部分赋值满足所有子句,则将已删除和未分配的变量集添加到输出中。可能有重复。