简体   繁体   English

python遍历团队组合

[英]python iterate over team combinations

I have a list of 10 players, each with a respective skill score. 我列出了10名球员,每个球员都有各自的技能得分。 I'm trying to organise them into 2 teams of 5, where the total skill score of each team is as close as possible. 我正在尝试将他们分为5个2个小组,每个小组的总技能得分尽可能接近。

Iterating over every combination is obviously not very efficient as identical teams will occur. 迭代每个组合显然效率不高,因为会出现相同的团队。

Is there a python library or function that can either efficiently solve this problem or at least just iterate over the correct combinations? 是否有一个python库或函数可以有效解决此问题,或者至少可以迭代正确的组合?

Iterating over 10! 迭代超过10个! combinations isn't so bad if that is the easiest answer. 如果这是最简单的答案,组合还算不错。

As you said finding the perfect solution is very complex for this problem set, but you can try using greedy approach. 正如您所说的,针对此问题集找到理想的解决方案非常复杂,但是您可以尝试使用贪婪方法。

Say each player 'P' has these skills score bowling(bw) batting(b) & fielding(f) now you can come up with an equation for aggregated skill(K) with sample equation K = 2*bw+2*b+f 假设每个玩家“ P”都具有以下技能得分,即保龄球(bw)击球(b)和外地打球(f),现在您可以为方程式K = 2*bw+2*b+f提出汇总技能(K)的方程式K = 2*bw+2*b+f

Now all you have to do is split the 10 players into 2 teams with each k/2+k/2 approximately, which is straightforward if you use greedy approach. 现在您要做的就是将10个玩家分成2个团队,每个团队大约k/2+k/2 ,如果您使用贪婪的方法,这很简单。

Greedy algorithm: 贪婪算法:

  1. Sort all the player in descending order by their aggregated skill score(K). 将所有玩家按其综合技能得分(K)降序排列。
  2. Maintain two sides A & B 维持A和B双方
  3. Add the highest scorer to team A 将得分最高的球员添加到A队
  4. Add the second highest scorer to team B 将得分第二高的球员添加到B队中
  5. Keep adding the next scorer to the lowest total's team 继续将下一个得分手添加到总数最低的团队中

You can find the implementation here in Wikipedia 您可以在Wikipedia中找到实现

def find_partition(int_list):
    "returns: An attempt at a partition of `int_list` into two sets of equal sum"
    A = set()
    B = set()
    for n in sorted(int_list, reverse=True):
        if sum(A) < sum(B):
           A.add(n)
        else:
           B.add(n)
    return (A, B)

Update : The above code doesn't consider the quality of team size, Regarding that here might be useful discussion 更新 :上面的代码未考虑团队规模的质量,关于此处的讨论可能有用

https://cs.stackexchange.com/questions/33697/partition-partition-with-constraint-of-equal-size https://cs.stackexchange.com/questions/33697/partition-partition-with-constraint-of-equal-size

While not a perfect solution, could you take the average player skill and rank the n players based on this average. 虽然不是一个完美的解决方案,但您能否采用平均玩家技能并根据此平均值对n位玩家进行排名。

Then based on these values, use some heuristic to try and "balance" out these players across the two teams. 然后根据这些值,使用试探法尝试“平衡”两支球队中的这些球员。 Simple example would be to assign teams like so (highest ranked = 10, lowest ranked = 1) 一个简单的例子就是分配这样的团队(最高排名= 10,最低排名= 1)

Team 1 = 10 7 6 3 1 团队1 = 10 7 6 3 1

Team 2 = 9 8 5 4 2 小组2 = 9 8 5 4 2

Again, not perfect, but much less expensive than 10! 同样,它并不完美,但比10美元便宜得多! search. 搜索。

I solved this problem with itertools.combinations and sets, by going through each combination of the first team and using the remaining players as the second team, the search space was reduced to only 252 combinations. 我使用itertools.combinations和组合解决了这个问题,方法是遍历第一支球队的每个组合,并使用其余的球员作为第二支球队,因此搜索空间减少到只有252个组合。

from itertools import combinations

# random dictionary of players and scores
players = {
    'abc': 1234,
    'bcd': 2345,
    'cde': 3456,
    'def': 4567,
    'efg': 5678,
    'fgh': 6789,
    'ghi': 7891,
    'hij': 8912,
    'ijk': 9123,
    'jkl': 7410
}

closest_difference = None
all_players_set = set(players.keys())

for team_a in combinations(players.keys(), 5):
    team_a_set = set(team_a)
    team_b_set = all_players_set - team_a_set

    team_a_total = sum([players[x] for x in team_a_set])
    team_b_total = sum([players[x] for x in team_b_set])

    score_difference = abs(team_a_total - team_b_total)

    if not closest_difference or score_difference < closest_difference:
        closest_difference = score_difference
        best_team_a = team_a_set     
        best_team_b = team_b_set  

print("\nTeam a:")

for player in best_team_a:
    print(player)
print("with a score of " + str(sum([players[x] for x in best_team_a])))

print("\nTeam b:")

for player in best_team_b:
    print(player)
print("with a score of " + str(sum([players[x] for x in best_team_b])))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM