Python:生成所有成对唯一配对

时间:2013-05-12 19:05:49

标签: python itertools

我正在寻找一种Pythonic方法来生成所有成对唯一唯一配对(其中配对是由对组成的系统,而成对唯一表示(a,b) ≠ (b,a))用于包含偶数{{1物品。

我喜欢here的代码:

n

除了它生成所有顺序唯一,成对唯一的配对,或者比我想要的for perm in itertools.permutations(range(n)): print zip(perm[::2], perm[1::2]) 倍配对(冗余),虽然我可以过滤掉,但是我的程序真的陷入困境{{ 1}}。

也就是说,对于(n/2)!,我正在寻找以下输出(12个唯一配对):

n

请注意n = 4

这可能吗?我也可以使用一个函数为[(0, 1), (2, 3)] [(0, 1), (3, 2)] [(1, 0), (2, 3)] [(1, 0), (3, 2)] [(1, 2), (0, 3)] [(1, 2), (3, 0)] [(1, 3), (0, 2)] [(2, 0), (1, 3)] [(2, 0), (3, 1)] [(3, 1), (0, 2)] [(0, 3), (2, 1)] [(3, 0), (2, 1)] (a,b) ≠ (b,a)生成3个非成对唯一的配对,因为它可以直接从我那里置换我需要的东西。 我的主要目标是避免配对中对的顺序多余的排列。

提前感谢您的帮助和建议 - 我真的很感激。

3 个答案:

答案 0 :(得分:2)

我认为这可以为您提供所需的基本配对:1 N=2时; 3 N=4时; 15 N=6时; 105 n=8等时

import sys

def pairings(remainder, partial = None):
    partial = partial or []

    if len(remainder) == 0:
        yield partial

    else:
        for i in xrange(1, len(remainder)):
            pair = [[remainder[0], remainder[i]]]
            r1   = remainder[1:i]
            r2   = remainder[i+1:]
            for p in pairings(r1 + r2, partial + pair):
                yield p

def main():
    n = int(sys.argv[1])
    items = list(range(n))
    for p in pairings(items):
        print p

main()

答案 1 :(得分:0)

在链接问题"生成所有唯一对排列",(here)中,给出了一种算法,可以为任何给定的 n 生成循环调度。也就是说, n 团队的每组可能的比赛/配对。

因此,对于n = 4(假设为独占),那将是:

[0, 3], [1, 2]
[0, 2], [3, 1]
[0, 1], [2, 3]

现在我们已经获得了每个分区,我们只需找到它们的排列就可以获得完整的配对列表。即[0,3],[1,2]是四个一组中的一员: [0,3],[1,2] (本身)和 [3,0 ],[1,2] [0,3],[2,1] [3,0],[2,1]

要从一个成员中获取一个组的所有成员,你可以采用排列,其中每一对都可以翻转或不翻转(例如,如果它们是n元组而不是成对,那么就会有n!每个选项)。因此,因为你有两对和选项,每个分区产生2 ^ 2对。所以你总共有12个。

执行此操作的代码,其中round_robin(n)返回对列表的列表。所以round_robin(4) - > [[[0,3],[1,2]],[[0,2],[3,1]],[[0,1],[2,3]]]。

def pairs(n):
    for elem in round_robin(n):
        for first in [elem[0], elem[0][::-1]]:
            for second in [elem[1], elem[1][::-1]]:
                print (first, second)

这种方法生成的比你想要的少,然后上升而不是产生超过你想要的数量并且摆脱一堆,所以它应该更有效率。 ([:: - 1]是巫毒的,可以不可逆转地反转名单。)

这里是其他帖子的循环算法(由Theodros Zelleke编写)

from collections import deque

def round_robin_even(d, n):
    for i in range(n - 1):
        yield [[d[j], d[-j-1]] for j in range(n/2)]
        d[0], d[-1] = d[-1], d[0]
        d.rotate()

def round_robin_odd(d, n):
    for i in range(n):
        yield [[d[j], d[-j-1]] for j in range(n/2)]
        d.rotate()

def round_robin(n):
    d = deque(range(n))
    if n % 2 == 0:
        return list(round_robin_even(d, n))
    else:
        return list(round_robin_odd(d, n))

答案 2 :(得分:0)

我不确定我是否理解这个问题,无论如何,这是我的解决方案:

import itertools
n = 4
out = set()
for perm in itertools.permutations(range(n)):
    pairs = tuple(sorted(zip(perm[::2], perm[1::2])))
    out.add(pairs)

for i, p in enumerate(sorted(out)):
    print i,p

对于n = 4,它返回12个唯一对,对于n = 6,它返回120.

相关问题