Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从n个元素生成所有4元组对_Python_Algorithm_Combinatorics - Fatal编程技术网

Python 从n个元素生成所有4元组对

Python 从n个元素生成所有4元组对,python,algorithm,combinatorics,Python,Algorithm,Combinatorics,我想生成一个所有可能的4元组对的列表,给定一个大小为n的数组n至少为8,因此始终可以找到至少1对 作为一个有助于理解问题的示例,我使用了问题的一个较小版本,2元组对给定一个大小为5的数组。2元组对的预期结果将产生15项(元组是有序的,没有重复): [(1,2)、(3,4)]、[(1,2)、(3,5)]、[(1,2)、(4,5)]、[(1,3)、(2,4)]、[(1,3)、(2,5)]、[(1,3)、(4,5)]、[(1,4)、(2,3)]、[(1,4)、(2,5)]、[(1,4)、(3,5)]、

我想生成一个所有可能的4元组对的列表,给定一个大小为
n
的数组
n
至少为8,因此始终可以找到至少1对

作为一个有助于理解问题的示例,我使用了问题的一个较小版本,2元组对给定一个大小为
5
的数组。2元组对的预期结果将产生15项(元组是有序的,没有重复):

[(1,2)、(3,4)]、[(1,2)、(3,5)]、[(1,2)、(4,5)]、[(1,3)、(2,4)]、[(1,3)、(2,5)]、[(1,3)、(4,5)]、[(1,4)、(2,3)]、[(1,4)、(2,5)]、[(1,4)、(3,5)]、[(1,5)、(2,3)]、[(1,5)、(2,4)]、[(1,5]、[(1,5]、[(1,5)、(3,4)]、[(2,4]、[(2,5)]、[(2,5)]、[(2,5)]、[(2,5)]、[(2,5)]、[(2,5)]、[(2,5)]、[(2,5)]

我目前的做法是使用python中的
itertools
,检查
itertools.compositions返回的所有元素,执行两个循环,找到两个不共享单个元素的对,然后使用该元素

为了用python代码表达这一点,我准备了一个小片段:

arr = list(range(30)) # example list 
comb = list(itertools.combinations(range(0, len(arr)), 4))

for c1 in comb:
    for c2 in comb:  # go through all possible pairs
        if len([val for val in c1 if val in c2]) == 0:  # intersection of both sets results in 0, so they don't share an element
            ... # do something and check for duplicates
此方法正在发挥作用,但由于存在两个循环,效率低下,并且在给定的时间范围内仅适用于较小的
n
。这样做能更有效率吗


更新:在回答了一些问题后,我评估了这些建议。对于我的具体情况,最好的方法是MSeifert(现已删除)答案提供的(扩展)算法,该算法执行速度最快:

def generate_four_pairs(n):
    valids = range(0, n)
    for x00, x01, x02, x03, x10, x11, x12, x13 in itertools.combinations(valids, 8):
      yield [x00, x01, x02, x03], [x10, x11, x12, x13]
      yield [x00, x01, x02, x10], [x03, x11, x12, x13]
      yield [x00, x01, x02, x11], [x03, x10, x12, x13]
      yield [x00, x01, x02, x12], [x03, x10, x11, x13]
      yield [x00, x01, x02, x13], [x03, x10, x11, x12]
      yield [x00, x01, x03, x10], [x02, x11, x12, x13]
      yield [x00, x01, x03, x11], [x02, x10, x12, x13]
      yield [x00, x01, x03, x12], [x02, x10, x11, x13]
      yield [x00, x01, x03, x13], [x02, x10, x11, x12]
      yield [x00, x01, x10, x11], [x02, x03, x12, x13]
      yield [x00, x01, x10, x12], [x02, x03, x11, x13]
      yield [x00, x01, x10, x13], [x02, x03, x11, x12]
      yield [x00, x01, x11, x12], [x02, x03, x10, x13]
      yield [x00, x01, x11, x13], [x02, x03, x10, x12]
      yield [x00, x01, x12, x13], [x02, x03, x10, x11]
      yield [x00, x02, x03, x10], [x01, x11, x12, x13]
      yield [x00, x02, x03, x11], [x01, x10, x12, x13]
      yield [x00, x02, x03, x12], [x01, x10, x11, x13]
      yield [x00, x02, x03, x13], [x01, x10, x11, x12]
      yield [x00, x02, x10, x11], [x01, x03, x12, x13]
      yield [x00, x02, x10, x12], [x01, x03, x11, x13]
      yield [x00, x02, x10, x13], [x01, x03, x11, x12]
      yield [x00, x02, x11, x12], [x01, x03, x10, x13]
      yield [x00, x02, x11, x13], [x01, x03, x10, x12]
      yield [x00, x02, x12, x13], [x01, x03, x10, x11]
      yield [x00, x03, x10, x11], [x01, x02, x12, x13]
      yield [x00, x03, x10, x12], [x01, x02, x11, x13]
      yield [x00, x03, x10, x13], [x01, x02, x11, x12]
      yield [x00, x03, x11, x12], [x01, x02, x10, x13]
      yield [x00, x03, x11, x13], [x01, x02, x10, x12]
      yield [x00, x03, x12, x13], [x01, x02, x10, x11]
      yield [x00, x10, x11, x12], [x01, x02, x03, x13]
      yield [x00, x10, x11, x13], [x01, x02, x03, x12]
      yield [x00, x10, x12, x13], [x01, x02, x03, x11]
      yield [x00, x11, x12, x13], [x01, x02, x03, x10]
      yield [x01, x02, x03, x00], [x10, x11, x12, x13]
      yield [x01, x02, x03, x10], [x00, x11, x12, x13]
      yield [x01, x02, x03, x11], [x00, x10, x12, x13]
      yield [x01, x02, x03, x12], [x00, x10, x11, x13]
      yield [x01, x02, x03, x13], [x00, x10, x11, x12]
      yield [x01, x02, x10, x00], [x03, x11, x12, x13]
      yield [x01, x02, x10, x11], [x00, x03, x12, x13]
      yield [x01, x02, x10, x12], [x00, x03, x11, x13]
      yield [x01, x02, x10, x13], [x00, x03, x11, x12]
      yield [x01, x02, x11, x00], [x03, x10, x12, x13]
      yield [x01, x02, x11, x12], [x00, x03, x10, x13]
      yield [x01, x02, x11, x13], [x00, x03, x10, x12]
      yield [x01, x02, x12, x00], [x03, x10, x11, x13]
      yield [x01, x02, x12, x13], [x00, x03, x10, x11]
      yield [x01, x02, x13, x00], [x03, x10, x11, x12]
      yield [x01, x03, x10, x00], [x02, x11, x12, x13]
      yield [x01, x03, x10, x11], [x00, x02, x12, x13]
      yield [x01, x03, x10, x12], [x00, x02, x11, x13]
      yield [x01, x03, x10, x13], [x00, x02, x11, x12]
      yield [x01, x03, x11, x00], [x02, x10, x12, x13]
      yield [x01, x03, x11, x12], [x00, x02, x10, x13]
      yield [x01, x03, x11, x13], [x00, x02, x10, x12]
      yield [x01, x03, x12, x00], [x02, x10, x11, x13]
      yield [x01, x03, x12, x13], [x00, x02, x10, x11]
      yield [x01, x03, x13, x00], [x02, x10, x11, x12]
      yield [x01, x10, x11, x00], [x02, x03, x12, x13]
      yield [x01, x10, x11, x12], [x00, x02, x03, x13]
      yield [x01, x10, x11, x13], [x00, x02, x03, x12]
      yield [x01, x10, x12, x00], [x02, x03, x11, x13]
      yield [x01, x10, x12, x13], [x00, x02, x03, x11]
      yield [x01, x10, x13, x00], [x02, x03, x11, x12]
      yield [x01, x11, x12, x00], [x02, x03, x10, x13]
      yield [x01, x11, x12, x13], [x00, x02, x03, x10]
      yield [x01, x11, x13, x00], [x02, x03, x10, x12]
      yield [x01, x12, x13, x00], [x02, x03, x10, x11]

对于一般方法,我建议使用NPE提供的答案,因为这是这个问题最短、最容易阅读的答案。

生成所有组合对,然后丢弃几乎所有组合,因为它们包含公共元素,这会做很多不必要的工作

下面通过首先获取四个数字的所有子集(在2元组示例中),然后将每个子集拆分为所有可能的对来解决此问题:

import itertools

def gen_pairs(n, m):
  for both_halves in itertools.combinations(xrange(1, n + 1), 2 * m):
    for first_half in itertools.combinations(both_halves, m):
      second_half = tuple(sorted(set(both_halves) - set(first_half)))
      yield [first_half, second_half]

print sorted(gen_pairs(5, 2))
请注意,这并不能消除重复项(例如,
[(4,5)(2,3)]
vs
[(2,3)、(4,5)]
),因此产生的元素数量是预期的两倍


然而,删除重复项并不重要。这是留给读者的练习。

您可以使用排列和拆分,这可能会更快:

array = ...
size = 4
c = itertools.permutations(array)
for t in c:
    a = []
    for i in range(0, len(t), size):
        if i + size <= len(t):
            a.append(t[i:i+size])
    yield a
array=。。。
尺寸=4
c=itertools.排列(数组)
对于c中的t:
a=[]
对于范围内的i(0,长度(t),尺寸):
如果i+size我会:

from itertools import combinations

sample = range(1,6)
x1 = [subset for subset in combinations(sample,2)] #getting the set of tuples
x2 = [list(subset) for subset in combinations(x1,2)] #getting the pair of tuples
x3 = [x for x in x2 if (set(x[0]) & set(x[1]) == set())] #finally filtering the tuples with no intersection
输出:

[[(1, 2), (3, 4)],
 [(1, 2), (3, 5)],
 [(1, 2), (4, 5)],
 [(1, 3), (2, 4)],
 [(1, 3), (2, 5)],
 [(1, 3), (4, 5)],
 [(1, 4), (2, 3)],
 [(1, 4), (2, 5)],
 [(1, 4), (3, 5)],
 [(1, 5), (2, 3)],
 [(1, 5), (2, 4)],
 [(1, 5), (3, 4)],
 [(2, 3), (4, 5)],
 [(2, 4), (3, 5)],
 [(2, 5), (3, 4)]]

下面是生成MSeifert的yield语句的代码:)(它只生成其中的35条语句,这意味着没有重复的语句:)

def g(L,n,k,A,B):
如果len(A)==k:
返回[[tuple(A),tuple([L[i]表示x范围内的i(0,n+1)]+B)]]
elif len(B)=k:
返回[[tuple([L[i]表示xrange(0,n+1)中的i)]+A,tuple(B)]]
返回g(L,n-1,k,A[L[n]]+B[0:])+g(L,n-1,k[L[n]]+A[0:],B)
def f(L):
断言(len(L)>3,len(L)%2==0)
返回g(L,len(L)-2,len(L)/2,[],[L[-1]]
对于f中的i(['x00','x01','x02','x03','x10','x11','x12','x13']):
印刷品(一)

什么是
arr
,您确定
itertools
解决方案真的有效吗?为什么是15个元素而不是30个?例如,
[(4,5)(2,3)]
有什么问题?@MSeifert,它相当于列表中已有的
[(2,3)、(4,5)]
。“元组是有序的,没有重复。”但是所提供的
itertools
解决方案实际上给出了
[(4,5),(2,3)]
如果
itertools.compositions(范围(0,len(arr)),4)
itertools.compositions(范围(1,6),2)
所取代,这就是为什么我想知道该解决方案是否有效或正确。如果假定
len(arr)
5
,那么目前肯定不会。是的,上述解决方案也存在重复。它们在最后被过滤,因为我不知道有什么比在最后过滤它们更容易的解决方案。很抱歉,这一误解仍然存在一个问题,即
arr
未定义,并且
组合中的
4
似乎是错误的,因为您需要2个2元组。但是你的方法会给出2个4元组。很好的解决方案!读者提示:仅当
上半部分的第一个元素小于
下半部分的第一个元素时,才调用
yield