【发布时间】:2014-09-05 06:48:09
【问题描述】:
我正在尝试找到在给定索引的一组“0”和“1”上查找排列的最有效方法。
例如:给定 l = [0, 0, 1, 1]。所有升序排列为 {0011, 0101, 0110, 1001, 1010, 1100}。这些元素的索引范围为 0 -> 5。给定索引 = 2,结果为 0110。
我找到了算法here,它输入一个整数多重集(例如l = [1, 2, 2])。他的算法是有效的 (O(N^2))。但是,我的多重集仅包含“0”和“1”,并且需要 O(N) 或更少。 N是列表的长度
请您帮帮我。请注意,我的实际测试很大(len(l) 为 1024),因此 intertool 库不适合。我正在尝试尽可能加快速度(例如,使用 gmpy2...)
基于1,以下是我的尝试,但它是 O(N^2)
from collections import Counter
from math import factorial
import gmpy2
def permutation(l, index):
if not index:
return l
counter = Counter(l)
total_count = gmpy2.comb(len(l), counter['1'])
acc = 0
for i, v in enumerate(l):
if i > 0 and v == l[i-1]:
continue
count = total_count * counter[v] / len(l)
if acc + count > index:
return [l[i]] + permutation(l[:i] + l[i + 1:], index - acc)
acc += count
raise ValueError("Not enough permutations")
l = ['0', '0', '1', '1']
index = 2
print (l, index)
--> result = [0, 1, 1, 0]
提前致谢。
【问题讨论】:
-
所以基本上,您正在寻找具有一定数量 1 位的第 N 个二进制数?
-
@AaronDigulla:我的意思是在一组所有可能的排列中找到第 index 个排列。每个排列的长度为 n 并由给定数量的位“1”组成
-
@santa 但是顺序很重要吗?我的意思是你想要有序的可能排列集中的第 index 个排列?还是您只是想要一种一致且独特的方式来索引排列?
-
@freakish:是的,所有可能的排列都是按升序排列的。我在上面描述了我的示例:例如:给定 l = [0, 0, 1, 1]。所有升序排列为 {0011, 0101, 0110, 1001, 1010, 1100}。这些元素的索引范围为 0 -> 5。给定索引 = 2,结果为 0110。
-
@santa:和我说的一样。将输入集转换为一个大的二进制数,然后使用一组有限的移位操作将在 O(index) 时间内为您提供您想要的(即仅取决于您想要的索引)但我知道这对您没有帮助很多。不过,看看二进制模式。也许你可以使用预先计算的结果来加快这个过程。
标签: python algorithm permutation