【问题标题】:Doing constraint-satisfaction in Python在 Python 中进行约束满足
【发布时间】:2014-09-02 03:30:57
【问题描述】:

假设我有许多用户,每个用户都有一组介于0n 之间的数字。例如,一个用户可能有一组{3, 7},另一个可能有{7, 8, 9},等等。

我想获得最少数量的用户,如果我取他们所有集合的并集,我将获得0n 之间所有数字的集合。

如果您想出一种方法,让我为每个用户分配可变价格(而不是像上面那样使用 1),那么该算法将找到具有最低总价的用户组合。

p>

我见过在 Python (like this one) 中处理约束满足的包,但我不知道如何使用它们。如果它们可以用于此,那就太好了。

【问题讨论】:

  • 看起来是个难题。我认为暴力破解是不可能的?
  • 确实是被套住了,所以很可能没有多项式时间解。您可以使用指数动态程序或将问题表述为 ILP 并为此使用通用求解器。

标签: python algorithm constraints


【解决方案1】:

这是PuLP/GLPK 的解决方案。我以前从未使用过 PuLP,但它在 PyPI 上并且似乎可以完成这项工作。 GLPK 非常好而且免费。

from collections import defaultdict, namedtuple
from pulp import *


User = namedtuple('User', ('coverage', 'price'))


def solvesetcover(users):
    vars = [LpVariable('x{}'.format(i), 0, 1, cat='Binary') for i, user in enumerate(users)]
    prob = LpProblem()
    totals = defaultdict(int)
    for user, var in zip(users, vars):
        prob += user.price * var
        for elt in user.coverage:
            totals[elt] += var
    for total in totals.values():
        prob += total >= 1
    GLPK(msg=0).solve(prob)
    return [user for user, var in zip(users, vars) if value(var)]


if __name__ == '__main__':
    users = []
    users.append(User({1, 2, 3, 4, 5, 6, 7}, 1.16))
    users.append(User({8, 9, 10, 11, 12, 13, 14}, 1.08))
    users.append(User({1, 8}, 1.04))
    users.append(User({2, 3, 9, 10}, 1.02))
    users.append(User({4, 5, 6, 7, 11, 12, 13, 14}, 1.01))
    print(solvesetcover(users))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 2016-02-09
    相关资源
    最近更新 更多