MATLAB Answers

0

Moving players into teams - equal as possible random

eyal lampel さんによって質問されました 2016 年 10 月 25 日
最新アクティビティ Cory Johnson さんによって 編集されました 2016 年 11 月 1 日
hello all , i am a beginner at matlab , i have 33 players in my league , every player has an avg score ,
players_AVG=[166.29,156.57,155.72,171.29,156.76,155.67,168.36,161.77,155.65,173.92,162.06,149.21,177.44,161.79,148.64,177.25,162.15,146.02,175.28,162.72,142.59,174.21,164.88,141.91,180.69,168.75,127.06,184.18,165.39,133.26,191.41,185.23,90];
i want to insert the 33 players into 11 teams of 3 players each , i want the team_AVG to be as equal as possible . example output:
TEAM1=[player1(166.29),player5(156.57),player7(155.72)] --> TEAM1_AVG=159.53
TEAM2=[player2(171.29),player3(156.76),player4(155.67)] --> TEAM2_AVG=161.24
etc...
At the end of the year we want to reshuffle the teams.
i dont know where to start , how can i achieve this ??
thanks lampel.

  0 件のコメント

サインイン to comment.

タグ

3 件の回答

Walter Roberson
回答者: Walter Roberson
2016 年 10 月 25 日
編集済み: Walter Roberson
2016 年 10 月 25 日
 採用された回答

Repeat several times: randperm(33), group by 3, use that to index averages, sum by team, std(), if lower than any found so far then remember the permutation

  3 件のコメント

eyal lampel 2016 年 10 月 25 日
wow thanks walter!
such an easy / elegant solution !
if someone is interested this is how i implemented it :
players_AVG=[166.29,156.57,155.72,171.29,156.76,155.67,168.36,161.77,155.65,173.92,162.06,149.21,177.44,161.79,148.64,177.25,162.15,146.02,175.28,162.72,142.59,174.21,164.88,141.91,180.69,168.75,127.06,184.18,165.39,133.26,191.41,185.23,90];
teams_avg=ones(1,11)*9;
teams_player_candidate=ones(11,3)*9;
a=ones(1,10000)*9;
bestCombination=9;
index=1;
for i=1:5000
rand_position=randperm(33);
for j=0:10
index=index+1;
teams_avg(j+1)=(players_AVG(rand_position(1+3*j))+players_AVG(rand_position(2+3*j))+players_AVG(rand_position(3+3*j)))/3;
teams_player_candidate(j+1,1)=players_AVG(rand_position(1+3*j));
teams_player_candidate(j+1,2)=players_AVG(rand_position(2+3*j));
teams_player_candidate(j+1,3)=players_AVG(rand_position(3+3*j));
end
if bestCombination>std(teams_avg)
bestCombination=std(teams_avg);
optimalteams=teams_player_candidate;
optimal_teams_avg=teams_avg;
end
end
optimal_teams_avg
This is a great community thanks all.
Walter Roberson
2016 年 10 月 25 日
You can simplify a lot:
idx = reshape(randperm(33), 11, 3);
this_std = std(sum(players_AVG(idx), 2));
if this_std < bestCombination
bestCombination = this_std;
optimalteams = idx;
end
eyal lampel 2016 年 10 月 25 日
Even better :)
THANKS!
randperm is a very powerful function , its nice to know it.

サインイン to comment.


John D'Errico
回答者: John D'Errico
2016 年 10 月 25 日

There are lots of similar problems out there that can be formulated as an integer programming problem of some sort. In this case though, I'd be lazy, and just use a greedy method.
Start out with a random permutation of the integers 1:33. Then reshape those integers into an 11x3 array. So each row of the array indicates one team.
You know the overall sum of the players. So
target_average = mean(scores);
is the target average for each team.
Choose a tolerance, for how close to the goal you need to get all teams. Now pick one player from a team that is under the target average, and swap them for a player from a team with a average above the target average. Repeat this process until you can do no better, or you are within the goal tolerance for all teams.

  0 件のコメント

サインイン to comment.


回答者: Cory Johnson 2016 年 10 月 25 日
編集済み: Cory Johnson 2016 年 10 月 25 日

What a great question!
Try matching the highest and lowest scores, then filling in the middle with the average score that would round out the team the best. This technique would work well for teams of two, but teams of three get more complex.
  • Sort the player average scores
  • Assign team(n).players, one from the high end, and one from the low end for as many teams as desired
  • Sort the created teams based on the sum of player scores
  • Add the third player using the same method, adding the lowest scoring player to the highest summing team
As an example:
scores 1 3 4 5 6 7
would go into two teams as follows:
1-7, 3-6
the sum of these teams:
8, 9
Add the remaining scores to balance the teams based on these sums:
(8)-5, (9)-4
So the final teams would be:
1-7-5, 3-6-4
Both teams have a total score of 13!
Hope that helps!

  2 件のコメント

eyal lampel 2016 年 10 月 25 日
Thanks Cory ,
If it helps its a bowling game (highest score=300, lowest=0).
i am trying to implement your algorithm , i am stuck at the:
"Add the remaining scores to balance the teams based on these sums:"
here's what i've got so far:
players_AVG=[166.29,156.57,155.72,171.29,156.76,155.67,168.36,161.77,155.65,173.92,162.06,149.21,177.44,161.79,148.64,177.25,162.15,146.02,175.28,162.72,142.59,174.21,164.88,141.91,180.69,168.75,127.06,184.18,165.39,133.26,191.41,185.23,90];
players_AVG_sorted=sort(players_AVG);
Two_Player_sum=0;
for i=1:17
Two_Player_sum=[Two_Player_sum,players_AVG_sorted(34-i)+players_AVG_sorted(i)];
end
Two_Player_sum=Two_Player_sum(2:end)
i am not sure how to manipulate the Two_Player_sum ??
thanks lampel
Cory Johnson 2016 年 11 月 1 日
It is not as elegant as the solution above, but here is an attempt:
players_AVG=[166.29,156.57,155.72,171.29,156.76,155.67,168.36,161.77,155.65,173.92,162.06,149.21,177.44,161.79,148.64,177.25,162.15,146.02,175.28,162.72,142.59,174.21,164.88,141.91,180.69,168.75,127.06,184.18,165.39,133.26,191.41,185.23,90];
players_AVG_sorted=sort(players_AVG);
% divide into sections, high, med, and low
set1 = players_AVG_sorted(1:11);
set2 = players_AVG_sorted(12:22);
set3 = players_AVG_sorted(23:33);
% match high values to low values. Teams are by column
teams = [set1; flip(set3)];
% sort by the sum of each team, get index value
[~,b] = sort(sum(teams));
% Use index value to sort remaining set, make sure to flip so high/low are
% matched
set3_sort = flip(set3(b));
% add sorted set to teams
teams = [teams;set3_sort];
% Verify results
The numbers I get with this method are as follows:
465.5900 497.5200 508.8500 500.0400 500.7200 500.5200 498.1300 498.7000 503.4900 498.2500 493.2200
Not bad!

サインイン to comment.



Translated by