Python 基于约束的组合选择

Python 基于约束的组合选择,python,python-3.x,Python,Python 3.x,我正在制定我的第一个计划,我不太确定如何前进。基本上,该计划旨在根据球员等级组成平衡的球队。我已经成功地遍历了所有可能的球队组合,并显示了每个球队的总排名(球队中球员排名的总和) (我不会仅仅因为有点长就包含所有代码) 当前代码: players = {'A':1, 'B':2, 'C':3, 'D':4} compPoss = list(it.combinations(players.items(), int(numPlayers/numTeams))) #Creating possible

我正在制定我的第一个计划,我不太确定如何前进。基本上,该计划旨在根据球员等级组成平衡的球队。我已经成功地遍历了所有可能的球队组合,并显示了每个球队的总排名(球队中球员排名的总和)

(我不会仅仅因为有点长就包含所有代码)

当前代码:

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

我怎样才能做到这一点?我需要导入特定的库吗?如果是这样的话,您在这里使用哪一个?

itertools

Python有内置的,所以您不需要编写那么多代码。这是您的输出:

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)))

您不需要将数字转换为
int
,因为它已经是
int
。感谢您的回复。这个解决方案对于我提供的示例来说非常好,但是玩家的数量以及团队的数量都是基于用户输入的。所以可能会有3支球队,每个队有5名球员。很抱歉,我本应该说得更清楚一些,不过我将使用您给出的建议来清理我的代码。