2016-02-13 3 views
1

У меня есть список рейтингов для игроков в спорте и вы хотите назначить их для команд, чтобы распределение рейтингов было как можно более справедливым (т. Е. Устранение команд с большим количеством игроков с высоким рейтингом и наоборот).C# - честное распределение команды с рейтингами

В настоящее время я делаю это, но это, кажется, не дают оптимальное решение:

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

возможного дубликат [Как получить альтернативные элементы с использованием перечислимой в C#] (HTTP: //stackoverflow.com/questions/4123685/how-to-get-alternate-elements-using-enumerable-in-c-sharp) – Rhumborl

ответ

1

После сортировки их в порядке убывания попробовать этот

var team1List = ratingList.Where((r, i) => i % 2 != 0).ToList(); 
var team2List = ratingList.Where((r, i) => i % 2 == 0).ToList(); 
+0

Это не сработает, вы должны поставить 0 и 9 в первой команде, а не 0 и 8 на по крайней мере, это было сделано оператором – mybirthname

+0

Что вы подразумеваете под 0 и 9? – Alby

+0

@Alby, я думаю, он имеет в виду, если у вас 10 рейтингов (игроков), то на основе описания вы хотели бы иметь 0 и 9 (на основе ранжирования) игроков в одной команде. Но я предполагаю, что идея вопроса состоит в том, чтобы иметь ровное (справедливое) распределение – mariovalens

0

Для оптимального решения, идея состоит в том, чтобы рассмотреть ratingList дважды бок о бок ascending против 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 

The evens go in 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 ... 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^