使用 itertools 获取加起来为 1 的所有可能组合

get all possible combinations that add up to 1 using itertools

我想创建一个包含 3 个元素(0.05 增量)加起来为 1 的列表列表,即 [[0,0,1],[0,0.05,0.95],[0,0.1, 0.9],[0,0.15,0.85]...[0.95,0.05,0],[1,0,0]].

这是我写的代码:

import itertools.product
possible_contributions = [i/100 for i in range(0,101,5)]
all_model_combs = itertools.product(possible_contributions, repeat=3)
usable_list = [comb for comb in all_model_combs if sum(comb)==1]

usable_list 的长度为 226。我注意到我的 usable_list 中缺少几个可能的组合,例如 [0.2,0.7,0.2]、[0.3,0.35, 0.35],[0.3,0.6,0.1]...我没有找到缺失的模式。我发现很难排除故障 itertools.product,我想知道我遗漏了什么/

这是一个舍入错误,如果您尝试使用整数,它会起作用:

import itertools
possible_contributions = [i for i in range(0,101,5)]
all_model_combs = itertools.product(possible_contributions, repeat=3)
usable_list = [comb for comb in all_model_combs if sum(comb)==100]
(20, 60, 20) in usable_list
(30, 35, 35) in usable_list
(30, 60, 10) in usable_list

但是30/100 + 35/100 + 35/100 != 100/100

我建议你

  • 仅在最后除以 100 或
  • 给你的总和比较更多的空间abs(sum(comb) - 1) < 0.0001

这是浮点运算的局限性。使用 math.isclose() 并将可接受的接近度容差设置为 1:

import itertools
import math
possible_contributions = [i/100 for i in range(0,101,5)]
all_model_combs = itertools.product(possible_contributions, repeat=3)
usable_list = [comb for comb in all_model_combs if math.isclose(sum(comb),1, rel_tol=1e-06)]

print(len(usable_list)) #231