I had one day to create a program that, when setting up a CSV file with columns: [Name] | [Elo Rating] will output another CSV file with balanced commands. The user can choose how many players they want per team.
This is probably the programming project that I enjoyed the most, but it is very inefficient, given the urgent time frame and my limited knowledge of how best to implement such a task. This is similar to a question , but I would prefer not to simplify the process by simply placing players in teams based on the order of evaluation (faster, but less accurate than what I already have). Can you give suggestions on how I could do this faster without sacrificing accuracy?
The logic I came across is this:
- Find all possible combinations of commands.
- Find the average rating of all combinations of teams and find the closest team rating to this average.
- Choose the first team that has an average rating from step 2.
- Remove all teams that have any of these players.
- Repeat # 2, # 3 and # 4 until all commands are created.
Step 1 was completed with this answer and works great.
Step 2 may be more of a math question. I’m not sure if the average rating of players matches the average ratings of all teams. I use a slightly modified version of this answer because I use a dictionary to store the name and rating. I do not need this dictionary if it was just averaging the ratings of the players was as accurate.
float average = teamScoreDict.Average(s => s.Value);
var closestScoreToAvg = teamScoreDict.Values.Aggregate((x, y) =>
Math.Abs(x - average) < Math.Abs(y - average) ? x : y);
Step 3
static Team FindTeam(float targetScore)
{
var selectedTeam = new Team();
for (int i = 0; i < teams.Count; i++)
{
if (teams[i].TeamRating == targetScore)
{
selectedTeam = teams[i];
foreach (var player in teams[i].Player)
if (!usedPlayers.Contains(player.Key))
usedPlayers.Add(player.Key);
teamScoreDict.Remove(teams[i].Id);
teams.Remove(teams[i]);
break;
}
}
return selectedTeam;
}
4 - , . , , , , .
static void RemoveTeamsWithUsedPlayers()
{
for (int i = teams.Count - 1; i >= 0; i--)
{
if (teams[i].Player.Any(kvp => usedPlayers.Contains(kvp.Key)))
{
teamScoreDict.Remove(teams[i].Id);
teams.Remove(teams[i]);
}
}
}
( 40 5 1300-2200 8 19 [8498 8517]).
, . 12 3 . 32 4 . 40 5 , K- , .
, , .
EDIT: , , . 12 3 (220 k-).
- 00: 00: 00,0014493
- 00: 00: 00,0083637
- 00: 00: 00,0015608
- 00: 00: 00,0015930
, . 1 2 IEnumerable , , . 00: 00: 00.0042700
foreach (var team in teamList)
{
Team teamClass = new Team();
teamScore = 0.0F;
foreach (var player in team)
{
if (participants.TryGetValue(player, out tempInt))
{
teamScore += tempInt;
teamClass.Player.Add(player, tempInt);
}
}
teamClass.TeamRating = teamScore;
teamClass.Id = count;
teamScoreDict.Add(count, teamScore);
teams.Add(teamClass);
count++;
}
2 ( ): , , , , , , . 3 12 , 4 32 4.5229176 0.4067160s. , :
- . , .
- , , .
- , , ( + ) ( ).
- .
- 2 3, .