迭代数组中所有可能的值,总和为1

时间:2014-10-02 19:34:06

标签: python arrays algorithm math

我有一个包含4个值的数组。例如:[0.1, 0.1, 0.5, 0.3](元素总和= 1) 如何使用增量0.1迭代所有可能的值以得到总和1.

示例:

[1.0, 0.0, 0.0, 0,0]
[0.9, 0.1, 0.0, 0,0]
[0.9, 0.0, 0.1, 0,0]
......
[0.7, 0.2, 0.0, 0,1]

最好是在python或java中。或者只是伪代码中的算法解释

4 个答案:

答案 0 :(得分:1)

这基本上是一个整数问题 浮点问题。它可以解决为 FP问题,但float表示的不精确性 以及range之类的Python内置函数无法实现 提供浮点范围使其更加困难。 因此更容易在整洁,精确的整数领域中解决它 然后将结果显示为浮点值。

可以生成所有可能的组合 值,然后测试它们是否与目标值相加。 这就是其他一些提议的解决方案所做的事情。 但那是一种蛮力。它也有可能 仅生成 那些与之相加的向量/列表 目标价值。这个解决方案是递归的 发电机。

def vectors(length, target):
    """
    Generate all lists of whole numbers of given
    length that add up to the target value.
    """
    if length == 1:
        yield [target]
    else:
        for firstval in range(target+1):
            for rest in vectors(length-1, target-firstval):
                yield [firstval] + rest

TARGET=10
LENGTH=4
for vec in vectors(LENGTH, TARGET):
    print [ v / float(TARGET) for v in vec ]

这会产生:

[0.0, 0.0, 0.0, 1.0]
[0.0, 0.0, 0.1, 0.9]
[0.0, 0.0, 0.2, 0.8]
...
[0.9, 0.0, 0.0, 0.1]
[0.9, 0.0, 0.1, 0.0]
[0.9, 0.1, 0.0, 0.0]
[1.0, 0.0, 0.0, 0.0]

答案 1 :(得分:0)

查看 itertools.permutations

import itertools
allPermutations = itertools.permutations([0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]*4, 4)
Sum1Permutations = [x for x in allPermutations if sum(x) == 1]

正如@HuStmpHrrr所指出的那样,这是用蛮力来解决问题。用于生成添加到1.0的所有排列的算法是这样的:

Sum1Permutations = []
for x in range(10):
    for y in range(10-x+1):
        for z in range(10-x-y+1):
            Sum1Permutations.append([float(x)/10, float(y)/10, float(z)/10, float(10 - x - y - z)/10])

或者,使用列表理解:

Sum1Permutations = [[float(x)/10,float(y)/10,float(z)/10,float(10-x-y-z)/10] for x in range(10) for y in range(10-x+1) for z in range(10-x-y+1)]

答案 2 :(得分:0)

尝试以下列表理解:

>>> from itertools import product
>>> s = [list(p/10. for p in prd) 
         for prd in product(range(11), repeat=4) if sum(prd) == 10]
>>> len(s)
286
>>> [0.,1.,0.,0.] in s
True
>>> [.8,.2,.0,.0] in s
True
>>> 

这里需要 itertools.product

答案 3 :(得分:0)

而不是这些值,假装你将四个子区间放入长度为1的区间。然后这四个值由这些子区间的三个端点精确确定。

from itertools import combinations_with_replacement as cwr

for (one,onetwo,onetwothree) in cwr(range(11),3):
    print([one/10,(onetwo-one)/10,(onetwothree-onetwo)/10,(10-onetwothree)/10])