【问题标题】:Generate all combinations that sum to 1 of array of length 7生成长度为 7 的数组的总和为 1 的所有组合
【发布时间】:2022-01-04 13:34:45
【问题描述】:

我需要找到最佳方法来生成一个数组,该数组包含值 0 到 1.0 的所有可能组合,增量为 0.1,其中每个组合的总和正好等于 1。

我已使用以下代码对长度为 3 的数组执行此操作:

portfolios = []
for i in np.arange(0,1.1,0.1):
    for j in np.arange(0,1-i,0.1):
        k = 1 - i - j
        x = [i,j,k]
        portfolios.append(x)
portfolios = np.array(portfolios)

这给了我以下内容

print(portfolios)
#Output:
array([[0. , 0. , 1. ],
       [0. , 0.1, 0.9],
       [0. , 0.2, 0.8],
       [0. , 0.3, 0.7],
       [0. , 0.4, 0.6],
       [0. , 0.5, 0.5],
       [0. , 0.6, 0.4],
       [0. , 0.7, 0.3],
       [0. , 0.8, 0.2],
       [0. , 0.9, 0.1],
       [0.1, 0. , 0.9],
       [0.1, 0.1, 0.8],
       [0.1, 0.2, 0.7],
       [0.1, 0.3, 0.6],
       [0.1, 0.4, 0.5],
       [0.1, 0.5, 0.4],
       [0.1, 0.6, 0.3],
       [0.1, 0.7, 0.2],
       [0.1, 0.8, 0.1],
       [0.2, 0. , 0.8],
       [0.2, 0.1, 0.7],
       [0.2, 0.2, 0.6],
       [0.2, 0.3, 0.5],
       [0.2, 0.4, 0.4],
       [0.2, 0.5, 0.3],
       ...
       [0.7, 0. , 0.3],
       [0.7, 0.1, 0.2],
       [0.7, 0.2, 0.1],
       [0.8, 0. , 0.2],
       [0.8, 0.1, 0.1],
       [0.9, 0. , 0.1]])

但是,我想对长度为 7 的数组执行此操作。也就是说,我想要的输出应该如下所示:

#Desired output
array([[0. , 0., 0., 0., 0., 0., 1.],
       [0. , 0., 0., 0., 0., 0.1, 0.9],
       [0. , 0., 0., 0., 0., 0.2, 0.8],
       ... 
       [0.2, 0.8, 0., 0., 0., 0., 0.],
       [0.1, 0.9, 0., 0., 0., 0., 0.],
       [.1, 0., 0., 0., 0., 0., 0.]])
       

有没有一种聪明的方法来扩展我以前的代码?接受所有建议和替代方法。

【问题讨论】:

  • 顺序重要吗?即只要您拥有所有独特的组合就可以了吗?另外,在一定长度的数组之后,您不只是添加更多的零吗?例如,在长度为 5 的数组(.1+.2+.3+.4+.5>1,5 个最小正增量)之后,没有 .1 增量的总和小于 1,所以没有新的组合?
  • @RichardKYu 订单很重要。例如:在长度为 3 的情况下,数字为 0.7、0.3 和 0.0,我想生成所有组合:[0.7,0.3,0.0],[0.7,0.0,0.3],[0.3,0.7,0.0][0.3, 0.0,0.7],[0.0,0.3,0.7],[0.0,0.7,0.3]。但是,这些组合的顺序无关紧要。此外,长度为 7 的数组可能看起来像:[0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.4],这意味着数字可以重复。

标签: python arrays list-comprehension


【解决方案1】:

这是我的尝试。

我在整个代码中添加了 cmets 来帮助解释部分。

此外,最后会输出一个文本文件供您检查结果。

from collections import deque
import numpy as np
import itertools, sys


#We use a recursive approach to get all unique sums to 1.0
def combinations_of_sum(n):
    result = []
    build_combinations(n, deque(), result)

    return result

def build_combinations(sum, combinations, result):
    for i in range(sum, 0, -1):
        combinations.append(i)
        if i == sum:
            #print(list(combinations))
            adjusted_arr = [n/10 for n in list(combinations)]
            result.append(adjusted_arr)
            #print(result)
        else:
            build_combinations(sum-i, combinations, result)
        combinations.pop()




#First, we get all the unique lists of sums,
# ...with possibility of repeating numberes

uniques = combinations_of_sum(10)

#Then we filter out based on the array length you want.
#We specify 7 here:
array_length_limit = 7
filtered = []

for unique in uniques:
    if len(unique)<=array_length_limit:
        filtered.append(unique)

#Now, we fill the filtered arrays with 0s and calculate all
#... permutations, like  [0.7,0.3,0.0],[0.7,0.0,0.3], etc.

final = []
for arr in filtered:
    padding_length = array_length_limit - len(arr)
    arr = arr + [0]*padding_length
    
    permutations = list(set(itertools.permutations(arr,array_length_limit)))
    
    #This is just to show you what's going on
    #...You can see the permutations added to the final array.
    #print(permutations)

    for permutation in permutations:
        if list(permutation) not in final:
            final.append(list(permutation))



#finally, convert it into a numpy array.
final = np.array(final)

print(final)

np.savetxt('test.out', final, delimiter=',', fmt='%g')

我改了输出方式,因为item很多,不方便直接查看。文本文件中的输出如下所示:

由于您想要的所有不同排列,它会持续很长时间。

如果有任何问题,请告诉我,如果这是您想要的。

【讨论】:

  • 这正是我想要的。好评,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-02
  • 2011-09-05
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
相关资源
最近更新 更多