2017-08-10 82 views
2

我有这样的数据。Python元素总和和连续次数约束

a = [10, 11, 12, 13, 14] 
    b = [15, 16, 17, 18, 19] 
    c = [20, 21, 22, 23, 24] 
  1. 我要检查是否每一个列表中的第i个元素的总和,即,逐元素总和加起来大于50,其中i = [0,1,2,3, 4]。
  2. 我也想检查总和是否大于50连续三次。

有没有办法做到这一点作为约束满意度问题在Python?

我试过以下(使用这个CSP模块:https://labix.org/python-constraint),但是这打印了每个列表中所有可能的值的组合,但我想要做一个元素明智的总和。

from constraint import * 

    problem = Problem() 
    problem.addVariable("a", [10, 11, 12, 13, 14]) 
    problem.addVariable("b", [15, 16, 17, 18, 19]) 
    problem.addVariable('c', [20, 21, 22, 23, 24]) 

    problem.addConstraint(lambda a,b,c: a+b+c>50, ("a","b","c")) 

    for x in problem.getSolutions(): 
     print x 

结果(72个答案总数)

{'a': 14, 'c': 24, 'b': 19} 
    {'a': 14, 'c': 23, 'b': 19} 
    {'a': 14, 'c': 22, 'b': 19} 
    . 
    . 
    . 
    {'a': 10, 'c': 24, 'b': 18} 
    {'a': 10, 'c': 24, 'b': 17} 

所需答案:

{'a': 12, 'c': 22, 'b': 17} 
    {'a': 13, 'c': 23, 'b': 18} 
    {'a': 14, 'c': 24, 'b': 19} 

而且,我怎么添加约束检查和进入更大的连续次数比50?

我知道我可以使用lambda函数来做到这一点,但如果可能的话,我想使用CSP库,因为稍后可能会有更多的约束条件,并且列表数量和每个列表中的元素数量可能会增加到1000s。

a = [10, 11, 12, 13, 14] 
    b = [15, 16, 17, 18, 19] 
    c = [20, 21, 22, 23, 24] 

    z = zip(a, b, c) 

    print map(lambda (x,y,z): x+y+z>50, z) 
+0

虽然我理解你的“连续”的意思在这里,这似乎并不容易翻译成一个约束。 –

+0

在三个数组中使用附加变量'i':* index *。 –

+0

关于连续:约束点编程通常是不考虑解决方案产生的顺序。良好的求解器旨在最大限度地减少生成第一个解决方案的时间,因此解决方案通常以未经过处理的方式生成。将它与数据库进行比较:如果没有指定ORDER BY,大多数数据库不会对检索顺序提供任何硬性保证。 –

回答

1

我建议你调查itertools.groupby。例如,下面是一些代码,它会发现总计为> 50的连续列的计数运行次数为&。

from itertools import groupby 

a = [10, 11, 12, 13, 14] 
b = [15, 16, 17, 18, 19] 
c = [20, 21, 22, 23, 24] 

data = [a, b, c] 

def keyfunc(t): 
    return sum(t) > 50 

for k, g in groupby(zip(*data), keyfunc): 
    if k: 
     g = list(g) 
     print(g, len(g)) 

输出

[(12, 17, 22), (13, 18, 23), (14, 19, 24)] 3