我有一个体育运动员的排名列表,并希望将它们分配给团队,以便评级的分布尽可能公平(即,消除具有大量高评级玩家的团队,反之亦然)。
目前我正在这样做,但它似乎没有提供最佳解决方案:
ratingList.Sort();
ratingList.Reverse();
var team1List = ratingList.Where((r, i) => i % 2 != 0).ToList();
var team2List = ratingList.Where((r, i) => i % 2 == 0).ToList();
答案 0 :(得分:1)
按降序排序后,试试这个
var team1List = ratingList.Where((r, i) => i % 2 != 0).ToList();
var team2List = ratingList.Where((r, i) => i % 2 == 0).ToList();
答案 1 :(得分:0)
对于最佳解决方案,我们的想法是并排考虑ratingList
两次
ascending
vs descending
并采取前半部分(另一部分只是镜像)
Ex:
0, 1, 2, 3, 4 | 5, 6, 7, 8, 9
9, 8, 7, 6, 5 | 4, 3, 2, 1, 0
and keep the first half
team1 team2 team1 team2 |
0, 1, 2, 3, | 4 team1
9, 8, 7, 6, | 5 team2
evens进入team1
和team2
的赔率。如果我们有偶数对,最后一对将在两个团队之间重新分配(另请注意,这仅适用于ratingList >= 4
(由您来处理更少)。甚至我建议排除中间评级的评级数量,以及稍后决定如何处理它。
考虑到以上所有问题,解决方案应如下所示
ratingList.Sort();
var count = ratingList.Count();
// if even number of players, keep aside the one in the middle (as rating)
int? middle = null;
if (count % 2 != 0)
{
middle = ratingList[count / 2];
ratingList.RemoveAt(count / 2);
}
var ratingListDesc = ratingList.OrderByDescending(i => i).ToList();
var half = count / 2;
var take = half % 2 != 0 ? half - 1 : half;
var team1List = ratingList.Take(take).Where((r, i) => i % 2 == 0).ToList();
team1List.AddRange(ratingListDesc.Take(take).Where((r, i) => i % 2 == 0));
var team2List = ratingList.Take(take).Where((r, i) => i % 2 != 0).ToList();
team2List.AddRange(ratingListDesc.Take(take).Where((r, i) => i % 2 != 0));
// we just have to redistribute the remaining pair between each team
if (half % 2 != 0)
{
team1List.Add(ratingList[half - 1]);
team2List.Add(ratingListDesc[half - 1]);
}
if (middle.HasValue)
{
// do something, or not ...
}