【问题标题】:Generating r-length permutations of list with repeated elements python使用重复元素python生成列表的r长度排列
【发布时间】:2014-08-01 09:37:24
【问题描述】:

我的问题类似于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-length 有一个很好的置换解决方案。如何采用该算法进行挖矿?或者有没有更好的方法?

【问题讨论】:

  • 您提到您使用过itertools.permutations,但您是否尝试过itertools.combinations_with_replacement
  • @PabloFranciscoPérezHidalgo 是的,我试过了。在我的情况下 itertools 的问题,它不比较值 - 不查看列表中的元素是否相等 - 这实际上是问题所在。 itertools.combinations_with_replacement 也返回重复元素。
  • @PabloFranciscoPérezHidalgo combination_with_replacement 与我所问的不同。它重复列表的所有元素,在我的情况下,我需要过滤它们
  • 你的列表总是排序的吗?
  • 然后我想一个更简单(但不一定有效)的方法是通过 itertools 模块生成组合并仅显示与其邻居不同的组合(我的意思是重复将是连续的)。

标签: python permutation itertools


【解决方案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

【讨论】:

  • 我也考虑过这种方式,但是在这种情况下,结果中也会有 [2,2,2],这在我的情况下是无效的。
  • @genclik27:删除无效案例将由 TODO 处理。
猜你喜欢
  • 1970-01-01
  • 2011-05-14
  • 1970-01-01
  • 2020-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多