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名球员。很抱歉,我本应该说得更清楚一些,不过我将使用您给出的建议来清理我的代码。