如何在 Python 中生成 4 个值加起来为 1 的列表?
How to generate a list of 4 values that adds up to 1 in Python?
我正在尝试生成一个包含 4 个值的完整列表,这些值加起来为 1。每个值可以增加 10%。
例如,
这些是有效列表
[0, 0, 0, 1]
[0.1, 0.8, 0.1, 0]
[0.2, 0.2, 0.2, 0.4]
这些是无效列表
[1, 0.1, 0, 0]
[0.5, 0.5, 0.1, 0]
我相信排列是
10!/6!
我可能是错的。
您需要的是 integer partition。在网络上搜索该术语应该会出现很多结果。长度为 m 的 n 的整数分区只是 m 个正整数的列表,它们加起来为 n.
一旦你有一个长度为 4 的 10 的整数分区,你可以将整数除以 10 以获得 0.1 的增量和 1 的总和。
编辑:我看到列表可能少于 4 个项目(某些元素可能为零)。所以你正在寻找长度 <= 4 的整数分区(不是长度 == 4)。
这会将区间 [0, 10] 截成三个整数,得到四个子区间,其长度只需除以 10。
>>> import itertools
>>> for a, b, c in itertools.combinations_with_replacement(range(11), 3):
print([a/10, (b-a)/10, (c-b)/10, (10-c)/10])
[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.0, 0.0, 0.3, 0.7]
[0.0, 0.0, 0.4, 0.6]
[0.0, 0.0, 0.5, 0.5]
[0.0, 0.0, 0.6, 0.4]
[0.0, 0.0, 0.7, 0.3]
[0.0, 0.0, 0.8, 0.2]
[0.0, 0.0, 0.9, 0.1]
[0.0, 0.0, 1.0, 0.0]
[0.0, 0.1, 0.0, 0.9]
[0.0, 0.1, 0.1, 0.8]
[0.0, 0.1, 0.2, 0.7]
[0.0, 0.1, 0.3, 0.6]
...
...
...
[0.7, 0.2, 0.0, 0.1]
[0.7, 0.2, 0.1, 0.0]
[0.7, 0.3, 0.0, 0.0]
[0.8, 0.0, 0.0, 0.2]
[0.8, 0.0, 0.1, 0.1]
[0.8, 0.0, 0.2, 0.0]
[0.8, 0.1, 0.0, 0.1]
[0.8, 0.1, 0.1, 0.0]
[0.8, 0.2, 0.0, 0.0]
[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]
或更一般(只需将 3 替换为您想要的切割次数):
>>> for cuts in itertools.combinations_with_replacement(range(11), 3):
print([(b-a)/10 for a, b in zip((0,) + cuts, cuts + (10,))])
Stefan 的解决方案更好,但是,您也可以使用列表理解和 itertools
库来做到这一点:
import itertools
perm = [[x /10.0 for x in t] for t in itertools.product(range(11), repeat=4) if sum(t)==10]
我正在尝试生成一个包含 4 个值的完整列表,这些值加起来为 1。每个值可以增加 10%。
例如,
这些是有效列表
[0, 0, 0, 1]
[0.1, 0.8, 0.1, 0]
[0.2, 0.2, 0.2, 0.4]
这些是无效列表
[1, 0.1, 0, 0]
[0.5, 0.5, 0.1, 0]
我相信排列是
10!/6!
我可能是错的。
您需要的是 integer partition。在网络上搜索该术语应该会出现很多结果。长度为 m 的 n 的整数分区只是 m 个正整数的列表,它们加起来为 n.
一旦你有一个长度为 4 的 10 的整数分区,你可以将整数除以 10 以获得 0.1 的增量和 1 的总和。
编辑:我看到列表可能少于 4 个项目(某些元素可能为零)。所以你正在寻找长度 <= 4 的整数分区(不是长度 == 4)。
这会将区间 [0, 10] 截成三个整数,得到四个子区间,其长度只需除以 10。
>>> import itertools
>>> for a, b, c in itertools.combinations_with_replacement(range(11), 3):
print([a/10, (b-a)/10, (c-b)/10, (10-c)/10])
[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.0, 0.0, 0.3, 0.7]
[0.0, 0.0, 0.4, 0.6]
[0.0, 0.0, 0.5, 0.5]
[0.0, 0.0, 0.6, 0.4]
[0.0, 0.0, 0.7, 0.3]
[0.0, 0.0, 0.8, 0.2]
[0.0, 0.0, 0.9, 0.1]
[0.0, 0.0, 1.0, 0.0]
[0.0, 0.1, 0.0, 0.9]
[0.0, 0.1, 0.1, 0.8]
[0.0, 0.1, 0.2, 0.7]
[0.0, 0.1, 0.3, 0.6]
...
...
...
[0.7, 0.2, 0.0, 0.1]
[0.7, 0.2, 0.1, 0.0]
[0.7, 0.3, 0.0, 0.0]
[0.8, 0.0, 0.0, 0.2]
[0.8, 0.0, 0.1, 0.1]
[0.8, 0.0, 0.2, 0.0]
[0.8, 0.1, 0.0, 0.1]
[0.8, 0.1, 0.1, 0.0]
[0.8, 0.2, 0.0, 0.0]
[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]
或更一般(只需将 3 替换为您想要的切割次数):
>>> for cuts in itertools.combinations_with_replacement(range(11), 3):
print([(b-a)/10 for a, b in zip((0,) + cuts, cuts + (10,))])
Stefan 的解决方案更好,但是,您也可以使用列表理解和 itertools
库来做到这一点:
import itertools
perm = [[x /10.0 for x in t] for t in itertools.product(range(11), repeat=4) if sum(t)==10]