我有此代码:
from itertools import groupby
from itertools import combinations
teams = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
combo = list(combinations(teams, 2))
输出是45个元组的列表。
[(1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9), (1, 10), (2, 3), (2, 4), (2, 5), (2, 6), (2, 7), (2, 8), (2, 9), (2, 10), (3, 4), (3, 5), (3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (4, 5), (4, 6), (4, 7), (4, 8), (4, 9), (4, 10), (5, 6), (5, 7), (5, 8), (5, 9), (5, 10), (6, 7), (6, 8), (6, 9), (6, 10), (7, 8), (7, 9), (7, 10), (8, 9), (8, 10), (9, 10)]
我想将45个元组分为9组,每组5个元组,每个组都是唯一的项。例如这样的
list_1 = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
list_2 = [(1, 3), (2, 4), (5, 7), (6, 9), (8, 10)]
list_3 =
list_4 =
list_5 =
因此,每个列表都包含元组,其中的项从1到10,没有重复。
答案 0 :(得分:5)
这是一种基于round robin tournament scheduling algorithm的相当简单的方法。基本上,此方法将列表分为两半,并将列表的前半部分与列表后半部分的反向版本配对。然后,对于每个阶段,它都会“轮换”除列表中的第一支球队之外的所有球队(基于阶段或轮次的循环和列表串联正在模拟轮换)。
import ipaddress
srcIp = ipaddress.ip_network(str('10.0.0.0/24'))
答案 1 :(得分:2)
尝试一下:
d = {}
for i in combo:
s = set(teams) - set(i)
d[i] = [list(s)[k:k+2] for k in range(0, len(s), 2)]
输出:
{(5, 9): [[1, 2], [3, 4], [6, 7], [8, 10]], (4, 7): [[1, 2], [3, 5], [6, 8], [9, 10]], (1, 3): [[2, 4], [5, 6], [7, 8], [9, 10]], (4, 8): [[1, 2], [3, 5], [6, 7], [9, 10]], (5, 6): [[1, 2], [3, 4], [7, 8], [9, 10]], (2, 8): [[1, 3], [4, 5], [6, 7], [9, 10]], (6, 9): [[1, 2], [3, 4], [5, 7], [8, 10]], (8, 9): [[1, 2], [3, 4], [5, 6], [7, 10]], (1, 6): [[2, 3], [4, 5], [7, 8], [9, 10]], (3, 7): [[1, 2], [4, 5], [6, 8], [9, 10]], (2, 5): [[1, 3], [4, 6], [7, 8], [9, 10]], (5, 8): [[1, 2], [3, 4], [6, 7], [9, 10]], (1, 2): [[3, 4], [5, 6], [7, 8], [9, 10]], (4, 9): [[1, 2], [3, 5], [6, 7], [8, 10]], (2, 9): [[1, 3], [4, 5], [6, 7], [8, 10]], (3, 10): [[1, 2], [4, 5], [6, 7], [8, 9]], (6, 10): [[1, 2], [3, 4], [5, 7], [8, 9]], (8, 10): [[1, 2], [3, 4], [5, 6], [7, 9]], (1, 5): [[2, 3], [4, 6], [7, 8], [9, 10]], (3, 6): [[1, 2], [4, 5], [7, 8], [9, 10]], (1, 10): [[2, 3], [4, 5], [6, 7], [8, 9]], (7, 9): [[1, 2], [3, 4], [5, 6], [8, 10]], (4, 10): [[1, 2], [3, 5], [6, 7], [8, 9]], (2, 6): [[1, 3], [4, 5], [7, 8], [9, 10]], (7, 10): [[1, 2], [3, 4], [5, 6], [8, 9]], (4, 5): [[1, 2], [3, 6], [7, 8], [9, 10]], (1, 4): [[2, 3], [5, 6], [7, 8], [9, 10]], (2, 10): [[1, 3], [4, 5], [6, 7], [8, 9]], (9, 10): [[1, 2], [3, 4], [5, 6], [7, 8]], (3, 9): [[1, 2], [4, 5], [6, 7], [8, 10]], (2, 3): [[1, 4], [5, 6], [7, 8], [9, 10]], (1, 9): [[2, 3], [4, 5], [6, 7], [8, 10]], (6, 8): [[1, 2], [3, 4], [5, 7], [9, 10]], (6, 7): [[1, 2], [3, 4], [5, 8], [9, 10]], (3, 5): [[1, 2], [4, 6], [7, 8], [9, 10]], (2, 7): [[1, 3], [4, 5], [6, 8], [9, 10]], (5, 10): [[1, 2], [3, 4], [6, 7], [8, 9]], (4, 6): [[1, 2], [3, 5], [7, 8], [9, 10]], (7, 8): [[1, 2], [3, 4], [5, 6], [9, 10]], (5, 7): [[1, 2], [3, 4], [6, 8], [9, 10]], (3, 8): [[1, 2], [4, 5], [6, 7], [9, 10]], (1, 8): [[2, 3], [4, 5], [6, 7], [9, 10]], (1, 7): [[2, 3], [4, 5], [6, 8], [9, 10]], (3, 4): [[1, 2], [5, 6], [7, 8], [9, 10]], (2, 4): [[1, 3], [5, 6], [7, 8], [9, 10]]}
答案 2 :(得分:2)
我对这个问题的看法:
from itertools import combinations
teams = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
combo = list(combinations(teams, 2))
sets = []
def is_combo_value_in_set(c, s):
for val in c:
for val_s in s:
for v in val_s:
if val == v:
return True
return False
for c in combo:
should_add_set = True
for current_set in sets:
if is_combo_value_in_set(c, current_set) is False:
should_add_set = False
current_set.add(c)
break
if should_add_set:
sets.append(set())
sets[-1].add(c)
for v in sets:
print(sorted(v))
打印:
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
[(1, 3), (2, 4), (5, 7), (6, 8)]
[(1, 4), (2, 3), (5, 8), (6, 7)]
[(1, 5), (2, 6), (3, 7), (4, 8)]
[(1, 6), (2, 5), (3, 8), (4, 7)]
[(1, 7), (2, 8), (3, 5), (4, 6)]
[(1, 8), (2, 7), (3, 6), (4, 5)]
[(1, 9), (2, 10)]
[(1, 10), (2, 9)]
[(3, 9), (4, 10)]
[(3, 10), (4, 9)]
[(5, 9), (6, 10)]
[(5, 10), (6, 9)]
[(7, 9), (8, 10)]
[(7, 10), (8, 9)]
编辑:
也许不是最有效的解决方案,但它可以工作。我们随机选择5个匹配项,直到匹配项唯一,然后将其添加到结果列表中:
from itertools import combinations, chain
from random import choice
teams = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
combo = list(combinations(teams, 2))
available = combo.copy()
rv = []
def random_pop(l):
ch = choice(l)
l.remove(ch)
return ch
num_tries = 0
while True:
num_tries += 1
if num_tries > 99999:
available = combo.copy()
rv = []
num_tries = 0
l = [random_pop(available), random_pop(available), random_pop(available), random_pop(available), random_pop(available)]
flat = list(chain.from_iterable(l))
if len(set(flat)) == len(flat):
#is unique
rv.append(l)
else:
for i in l:
available.append(i)
if len(available) == 0:
break
for l in rv:
print(sorted(l))
打印(例如):
[(1, 8), (2, 4), (3, 5), (6, 10), (7, 9)]
[(1, 5), (2, 7), (3, 6), (4, 9), (8, 10)]
[(1, 10), (2, 6), (3, 8), (4, 7), (5, 9)]
[(1, 3), (2, 9), (4, 8), (5, 6), (7, 10)]
[(1, 9), (2, 3), (4, 6), (5, 10), (7, 8)]
[(1, 4), (2, 5), (3, 7), (6, 8), (9, 10)]
[(1, 7), (2, 10), (3, 4), (5, 8), (6, 9)]
[(1, 6), (2, 8), (3, 9), (4, 10), (5, 7)]
[(1, 2), (3, 10), (4, 5), (6, 7), (8, 9)]
答案 3 :(得分:2)
每个团队出现9次,因此您至少需要9个列表(回合),以确保所有45对都出现在一个非重复列表中。如果我们允许每个列表使用不同数量的游戏,那么无需重复就可以轻松生成游戏列表。但是,如果您希望9个列表中的每个列表有5个游戏,则需要使用更复杂的算法。
这里有这样一种算法:https://nrich.maths.org/1443
这是Python中的算法示例(适用于偶数和奇数组):
def roundRobin(teams):
result = []
count = len(teams)
even = 1-(count&1)
poly = teams[even:]
for _ in range(count-even):
games = [(teams[0],poly[0])]*even
games += [(poly[i],poly[count-i-even]) for i in range(1,(count+1)//2)]
result.append(games)
poly = poly[1:]+poly[:1]
return result
# Odd number of teams (7)
for games in roundRobin(["A","B","C","D","E","F","G"]):
print(games)
# [('B', 'G'), ('C', 'F'), ('D', 'E')] ("A" sits out)
# [('C', 'A'), ('D', 'G'), ('E', 'F')] ("B" sits out)
# [('D', 'B'), ('E', 'A'), ('F', 'G')] ("C" sits out)
# [('E', 'C'), ('F', 'B'), ('G', 'A')] ("D" sits out)
# [('F', 'D'), ('G', 'C'), ('A', 'B')] ("E" sits out)
# [('G', 'E'), ('A', 'D'), ('B', 'C')] ("F" sits out)
# [('A', 'F'), ('B', 'E'), ('C', 'D')] ("G" sits out)
# Even number of teams (10)
for games in roundRobin(["A","B","C","D","E","F","G","H","I","J"]):
print(games)
# [('A', 'B'), ('C', 'J'), ('D', 'I'), ('E', 'H'), ('F', 'G')]
# [('A', 'C'), ('D', 'B'), ('E', 'J'), ('F', 'I'), ('G', 'H')]
# [('A', 'D'), ('E', 'C'), ('F', 'B'), ('G', 'J'), ('H', 'I')]
# [('A', 'E'), ('F', 'D'), ('G', 'C'), ('H', 'B'), ('I', 'J')]
# [('A', 'F'), ('G', 'E'), ('H', 'D'), ('I', 'C'), ('J', 'B')]
# [('A', 'G'), ('H', 'F'), ('I', 'E'), ('J', 'D'), ('B', 'C')]
# [('A', 'H'), ('I', 'G'), ('J', 'F'), ('B', 'E'), ('C', 'D')]
# [('A', 'I'), ('J', 'H'), ('B', 'G'), ('C', 'F'), ('D', 'E')]
# [('A', 'J'), ('B', 'I'), ('C', 'H'), ('D', 'G'), ('E', 'F')]
答案 4 :(得分:1)
我认为以下代码将起作用:
import copy
def extract_one_list(xdata):
"""
`xdata` .......... `external data`
"""
old_type = type(xdata[0])
# we are going to be testing for whether
# two tuples have any elements in common.
# For example, do (4, 5) and (7, 8) have any elements common?
# the answer is `no`.
prohibited_elements = set(xdata.pop(0))
iout = [copy.copy(prohibited_elements)]
# `iout`.......... `internal output`
candi = 0
while True:
# `candi`......... candidate index
# `candy`......... candidate
if candi >= len(xdata):
break
candy = set(xdata[candi])
if len(prohibited_elements.intersection(candy)) == 0:
iout.append(candy)
prohibited_elements.update(xdata.pop(candi))
candi = candi + 1
# Next, convert sets into the type of container
# which was originally used (tuples, lists,
# or some other type of container
# Let external iout (xout) be:
# the old_type of the internal element (ielem)
# for each internal element in the internal iout (iout)
xout = [old_type(ielem) for ielem in iout]
return xout
def extract_all_lists(xdata):
lol = list()
# `lol`...... `list of lists`
while len(xdata) > 0:
lyst = extract_one_list(unsorted_data)
lol.append(lyst)
return lol
unsorted_data = [(1, 2), (1, 3), (1, 4), (1, 5), (1, 6),
(1, 7), (1, 8), (1, 9), (1, 10), (2, 3),
(2, 4), (2, 5), (2, 6), (2, 7), (2, 8),
(2, 9), (2, 10), (3, 4), (3, 5), (3, 6),
(3, 7), (3, 8), (3, 9), (3, 10), (4, 5),
(4, 6), (4, 7), (4, 8), (4, 9), (4, 10),
(5, 6), (5, 7), (5, 8), (5, 9), (5, 10),
(6, 7), (6, 8), (6, 9), (6, 10), (7, 8),
(7, 9), (7, 10), (8, 9), (8, 10), (9, 10)]
lol = extract_all_lists(unsorted_data)
print('\n'.join([str(x) for x in lol]))
输出为:
[(1, 2), (3, 4), (5, 6), (8, 7), (9, 10)]
[(1, 3), (2, 4), (5, 7), (8, 6)]
[(1, 4), (2, 3), (8, 5), (6, 7)]
[(1, 5), (2, 6), (3, 7), (8, 4)]
[(1, 6), (2, 5), (8, 3), (4, 7)]
[(1, 7), (8, 2), (3, 5), (4, 6)]
[(8, 1), (2, 7), (3, 6), (4, 5)]
[(1, 9), (2, 10)]
[(1, 10), (9, 2)]
[(9, 3), (10, 4)]
[(10, 3), (9, 4)]
[(9, 5), (10, 6)]
[(10, 5), (9, 6)]
[(9, 7), (8, 10)]
[(10, 7), (8, 9)]
答案 5 :(得分:1)
您可以使用递归来生成包含groupingBy()
的所有元素的partitionBy()
组合,然后使用迭代器进行过滤:
for (Map.Entry<String, Response> entry: responses.entrySet()) {
String key = entry.getKey();
Response value = entry.getValue();
if (key.equals("foo") && !value.equals("bar")) {
res1 = value;
} else if (key.equals("some other key")) {
res2 = value;
}
}
Response finalResponse = res1 != null ? res1 : res2;
输出:
Optional<Response> res1 = Optional.empty();
Response res2;
res1 = responses.entrySet().stream()
.filter(entry -> entry.getKey().equals("foo") &&
!entry.getValue().equals("bar"))
.map(Map.Entry::getValue)
.findFirst();
res2 = responses.entrySet().stream()
.filter(entry -> entry.getKey().equals("some other key"))
.map(Map.Entry::getValue)
.findFirst().orElse(null);
Response finalResponse = res1.orElse(res2);
答案 6 :(得分:0)
除非我缺少有关此问题的信息,也许使用frozenset
s这样的东西可以做到吗?
from itertools import combinations
teams = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
games = set(frozenset(combo) for combo in combinations(teams, 2))
brackets = []
while games:
bracket = []
while games and len(bracket) < 5:
bracket.append(tuple(sorted(games.pop())))
brackets.append(bracket)
for bracket in brackets:
print(bracket)
输出(例如)
[(4, 10), (2, 8), (1, 4), (4, 6), (2, 3)]
[(3, 9), (2, 6), (4, 5), (7, 9), (7, 8)]
[(4, 9), (1, 10), (2, 9), (5, 9), (3, 4)]
[(6, 9), (1, 7), (7, 10), (8, 10), (2, 4)]
[(1, 8), (5, 6), (3, 5), (1, 6), (5, 8)]
[(1, 3), (4, 7), (3, 7), (6, 7), (3, 6)]
[(3, 8), (1, 5), (6, 8), (5, 10), (2, 7)]
[(5, 7), (1, 9), (2, 10), (9, 10), (1, 2)]
[(8, 9), (6, 10), (2, 5), (3, 10), (4, 8)]