我想生成一个最多包含两个'1'的4个元素的排列的完整列表。
例如,我有n = 4和m = 2:
我想要所有最多包含两个“ 1”的排列:
[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1], [1,0,1,0],[0,0,1,1],[1,1,0,0],[1,1,0,0],[1,0,0,1]。 ..你明白了。
我试图生成所有排列的完整列表,然后执行SUM <3,然后将其提供给我。当n较小时,效果很好。问题是我需要在n> 30时这样做。
如您所见,迭代将达到2 ^ N,这是不可行的。
由于m较小(我处理的m小于5),所以与所有可能的组合相比,我只需要很小百分比的排列。 迭代的数量级变为N ^ M,因此在这种情况下为N ^ 5。
是否有一种简单的方法来生成此列表?
[编辑:至少写而不是最多写]
答案 0 :(得分:0)
from itertools import permutations
l = list(permutations([0, 0, 1, 1]))
如果只需要唯一的,则可以将其包装在set
中:
set(list(permutations([0, 0, 1, 1])))
如果您只担心计算排列/组合的数量,并且您无需在数据中使用排列的实际实例,只需使用数学即可。所有这些东西都有封闭形式的表达式,请参见combinatorics。
答案 1 :(得分:0)
长度为n
且布尔值精确为m
的布尔数组的排列集与{{1}的集合的m
-组合的集合基本相同}}事物,即n
返回的事物。 (在这种情况下,itertools.combinations
是n
真实值的索引。)
要获得到 m
个真值的排列,我们只需要将{{1}中m
的{{1}}个值的组合链接在一起}},可以轻松地通过i
完成:
i
将这些索引数组转换为布尔数组有点烦人,但仍然可行:
range(m + 1)
请注意,与您的示例不同,这包括不存在True值的情况。
可能功能过度的up_to_m_of_n_true可能更易读为:
itertools.chain.from_iterable
答案 2 :(得分:0)
不确定这是否符合您的效果期望,这是一种方法:
说明:
n
是我们将要生成的二进制序列的统一长度(例如5)。max_ones
是最大数目的二进制序列(例如3)ones
是有效排列之一中的1的数目。它的范围从0到max_ones
。ones
(例如ones == 3
)的每个这样的有效值,通过取“种子”(例如(1,1,1,0,0)
)并进行迭代来生成该序列的排列,从而获得排列。 “种子”序列,最后,将该迭代器传递给set()
(这样它会自动避免重复)。表达式(1,)*ones + (0,)*(n-ones)
创建“种子”序列。max_ones
,我们将获得许多这样的集合。我们最终chain()
将所有这些集合在一起。代码:
import itertools as itr
n = 4
max_ones = 2
my_all_atmost = set(itr.chain.from_iterable([set(itr.permutations(seed_row))
for seed_row in {(1,)*ones + (0,)*(n-ones)
for ones in range(0,max_ones+1)}]))
输出:(例如n == 4, max_ones == 2)
的示例:
print (my_all_atmost)
{(1, 0, 0, 0), (1, 0, 1, 0), (1, 1, 0, 0),
(0, 0, 0, 1), (1, 0, 0, 1), (0, 0, 1, 0),
(0, 1, 0, 0), (0, 1, 1, 0), (0, 0, 0, 0),
(0, 1, 0, 1), (0, 0, 1, 1)}