背景:我正在为一个小型多人视频游戏项目开发“匹配系统”。每个球员都有一个从0-10的排名,每支球队有4名球员。我试图找到一个平衡球队的好方法,让他们的平均排名尽可能接近,比赛尽可能公平。
我目前有缺陷的方法如下所示:
def create_teams(players)
teams = Hash.new{|hash, team| hash[team] = []}
players.sort_by(&:rank).each_slice(2) do |slice|
teams[:team1] << slice[0]
teams[:team2] << slice[1]
end
teams
end
如果等级已经非常相似,这可以很好地工作,但这不是解决这个问题的正确方法。例如,它在这样的情况下失败:
require "ostruct"
class Array
def avg
sum.fdiv(size)
end
end
dummy_players = [9, 5, 5, 3, 3, 3, 2, 0].map{|rank| OpenStruct.new(rank: rank)}
teams = create_teams(dummy_players)
teams.each do |team, players|
ranks = players.map(&:rank)
puts "#{team} - ranks: #{ranks.inspect}, avg: #{ranks.avg}"
end
这导致了非常不公平的团队:
team1 - ranks: [0, 3, 3, 5], avg: 2.75
team2 - ranks: [2, 3, 5, 9], avg: 4.75
相反,我希望这种情况下的团队是这样的:
team1 - ranks: [0, 3, 3, 9], avg: 3.75
team2 - ranks: [2, 3, 5, 5], avg: 3.75