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

问题描述

我想创建一个包含 3 个元素(0.05 增量)的列表,这些元素加起来为 1,即 [[0,1],[0,0.05,0.95],0.1,0.9],0.15,0.85]...[0.95,0],[1,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 进行故障排除,我想知道我错过了什么/

解决方法

这是浮点运算的限制。使用 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
,

这是一个四舍五入的错误,如果你用整数来尝试它是有效的:

import itertools
possible_contributions = [i for i in range(0,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,10) in usable_list

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

我建议你

  • 只在最后除以 100 或
  • 为您的总和比较留出更多空间,例如abs(sum(comb) - 1) < 0.0001

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...