python-constraint - 变量为来自域

时间:2016-03-10 23:58:40

标签: python constraint-programming

我一直在尝试使用python-constraint模块来解决一个问题,该问题的输出必须是包含较大列表中随机样本的列表列表,其中每个列表必须包含至少一个元素的值大于前面列表中的任何元素。

因此,如果我们的输入列表是[63, 70, 72, 79, 85, 90, 95, 96, 107, 121],那么令人满意的输出将是:

[[63, 79], [70, 72], [85, 90], [95, 107], [96, 121]]

但是,以下满足,因为最后一个列表中的所有元素都低于前一个列表中的所有元素:

[[63, 79], [70, 72], [90, 95], [107, 121], [85, 96]]

我想我可能能够使用python-constraint来解决这个问题,但似乎模块只能在平面列表域上工作,其中变量对应于列表中的唯一元素:

from constraint import *

problem = Problem()
problem.addVariable("a", [1,2,3])
problem.addVariable("b", [4,5,6])

problem.addConstraint(lambda a, b: a*2 == b, ("a", "b"))
problem.getSolutions()
>>> [{'a': 3, 'b': 6}, {'a': 2, 'b': 4}]

所以在上面的" a"和" b"被绑定到来自各个域的随机选择的单个元素。我需要做的是从较大的集合中提取子列表,然后在这些子列表的连续对上设置约束。但是,使用python-constraint似乎不太可能。

我提出的一个解决方案是预先计算源列表中所有可能的值对,然后将 作为域传递:

from constraint import *
import itertools

source = [63, 70, 72, 79, 85, 90, 95, 96, 107, 121]
all_combs = list(itertools.combinations(source, 2))

problem = Problem()
problem.addVariables(["a", "b"], all_combs)
problem.addConstraint(lambda a, b: set(a).isdisjoint(b) and min(a)<max(b), ("a", "b"))
problem.getSolutions()

虽然这看起来很粗糙但确实有效。然而,它的问题是我可能想要在特定模式中具有不同长度的子列表,例如大小为2,2,3,3的模式,因此解决方案将始终具有该形式:

[[63, 79], [70, 72], [85, 90, 121], [95, 96, 107]]

有没有(优雅/更好)的方法来实现这一目标?

0 个答案:

没有答案