根据约束条件选择组合

时间:2020-02-08 06:18:26

标签: python python-3.x

我正在制作我的第一个程序,但我不确定如何前进。基本上,该计划旨在根据球员排名来组成一支平衡的球队。我设法遍历了所有可能的球队组合,并显示了每个球队的总排名(球员排名的总和)。

(我不会因为太冗长而包含所有代码)

当前代码:

players = {'A':1, 'B':2, 'C':3, 'D':4}

compPoss = list(it.combinations(players.items(), int(numPlayers/numTeams))) #Creating possible combinations of teams

for row in compPoss:

    # initialize variables:
    row_sum = 0

    # iterate over each point (tuple):
    for point in row:

        # convert number to int:
        number = int(point[1])

        # add to sum:
        row_sum += number

    #to add sum of rows to end of row
    new_compPoss = row + (row_sum,)

    # print row and sum:
    print(new_compPoss)

输出

(('A', '1'), ('B', '2'), 3)
(('A', '1'), ('C', '3'), 4)
(('A', '1'), ('D', '4'), 5)
(('B', '2'), ('C', '3'), 5)
(('B', '2'), ('D', '4'), 6)
(('C', '3'), ('D', '4'), 7)

我现在想打印出排名差异最小同时又拥有独特球员的球队。在此示例中为:

Team 1 ('A','D') Rank 5

Team 2 ('B','C') Rank 5

我该如何实现?我需要导入特定的库吗?如果是这样的话?

1 个答案:

答案 0 :(得分:0)

itertools在这里可以使用。

Python内置了sumlist comprehensions,因此您无需编写太多代码。这是您得到的输出:

ranks = []
for row in compPoss:
    row_sum = sum(point[1] for point in row)
    new_compPoss = row + (row_sum,)
    ranks.append(new_compPoss)

因此,等级列表由您要打印的项目组成。您可以使用此输出迭代排名差异最小的对,检查其是否形成唯一的玩家并首先返回此类对。但是我认为这里的工作很难。

我更喜欢找到所有已经形成独特球员的配对,然后返回排名差异最小的一对。如果您有一些team1,则可以找到team2的剩余成员,并找到这两个团队的排名差异:

import itertools as it
players = {'A':1, 'B':2, 'C':3, 'D':4}
compPoss = list(it.combinations(players, 2)) #Creating possible combinations of teams, like ('A', 'C')

set_of_players = set(players)
rank_differences = []
for row in compPoss:
    team1 = row
    team2 = set_of_players - set(row) #finding remaining members
    team1_rank = sum(players[n] for n in team1)
    team2_rank = sum(players[n] for n in team2)
    rank_differences.append((team1, tuple(team2), abs(team2_rank - team1_rank)))

for n in rank_differences:
    print(n)

它给出结果:

(('A', 'B'), ('C', 'D'), 4)
(('A', 'C'), ('B', 'D'), 2)
(('A', 'D'), ('B', 'C'), 0)
(('B', 'C'), ('A', 'D'), 0)
(('B', 'D'), ('C', 'A'), 2)
(('C', 'D'), ('B', 'A'), 4)

所有项目都是重复的,但是您可以忽略它,并打印出等级差异最小的项目,如下所示:

>>> result = min(rank_differences, key = lambda x: x[2])
>>> print(result)
(('A', 'D'), ('B', 'C'), 0)

额外入侵

您可以使用按字典顺序对组合进行排序的属性,这意味着可以在组合的反向列表中访问其余团队:

>>> compPoss
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('B', 'C'), ('B', 'D'), ('C', 'D')]
# first half of combinations: [('A', 'B'), ('A', 'C'), ('A', 'D')]
team1_groups = compPoss[:len(compPoss)//2]
# another half of combinations: [('C', 'D'), ('B', 'D'), ('B', 'C')]
team2_groups = compPoss[:len(compPoss)//2-1:-1] 

pairs = zip(team1_groups, team2_groups)

rank_differences = []
for team1, team2 in pairs:
    team1_rank = sum(players[n] for n in team1)
    team2_rank = sum(players[n] for n in team2)
    rank_differences.append((team1, team2, abs(team2_rank - team1_rank)))