我的问题类似于提问here的问题。与此问题不同,我需要一种算法,该算法生成具有重复元素的给定列表的r元组排列。
举个例子:
list1 = [1,1,1,2,2]
for i in permu(list1, 3):
print i
[1,1,1]
[1,1,2]
[1,2,1]
[2,1,1]
[1,2,2]
[2,1,2]
[2,2,1]
似乎itertools.permutations在这里可以正常工作,添加一个简单的过滤来删除重复的过滤。然而,在我的实际情况中,列表比这个例子长得多,因为你已经知道itertools.permutations的复杂性随着列表长度的增加而呈指数增长。
到目前为止,我的内容如下。此代码执行所描述的作业,但效率不高。
def generate_paths(paths, N = None):
groupdxs = [i for i, group in enumerate(paths) for _ in range(len(group))]
oldCombo = []
result = []
for dxCombo in itertools.permutations(groupdxs, N):
if dxCombo <= oldCombo: # as simple filter
continue
oldCombo = dxCombo
parNumbers = partialCombinations(dxCombo, len(paths))
if not parNumbers.count(0) >= len(paths)-1: # all of nodes are coming from same path, same graph
groupTemps = []
for groupInd in range(len(parNumbers)):
groupTemp = [x for x in itertools.combinations(paths[groupInd], parNumbers[groupInd])]
groupTemps.append(groupTemp)
for parGroups in itertools.product(*groupTemps):
iters = [iter(group) for group in parGroups]
p = [next(iters[i]) for i in dxCombo]
result.append(p)
return result
def partialCombinations(combo, numGruops):
tempCombo = list(combo)
result = list([0] * numGruops)
for x in tempCombo:
result[x] += 1
return result
在第一个for循环中,我需要生成所有可能的r长度元组,这会使算法变慢。在上面的链接中没有使用r长度的排列有一个很好的解决方案。我怎样才能采用这种算法来挖掘?还是有更好的方法吗?
答案 0 :(得分:1)
对于你的情况,我还没有想到这一点,但这是另一种方法。
您可以提供一个没有重复项的小列表,而不是为列表提供大型列表。您可以使用combination_with_replacement生成这些较小的列表(您需要过滤它们以匹配原始输入中的重复数量),然后获取每个组合的排列。
possible_values = (1,2)
n_positions = 3
sorted_combinations = itertools.combinations_with_replacement(possible_values, n_positions)
unique_permutations = set()
for combo in sorted_combinations:
# TODO: Do filtering for acceptable combinations before passing to permutations.
for p in itertools.permutations(combo):
unique_permutations.add(p)
print "len(unique_permutations) = %i. It should be %i^%i = %i.\nPermutations:" % (len(unique_permutations), len(possible_values), n_positions, pow(len(possible_values), n_positions))
for p in unique_permutations:
print p