I am trying to write a section of code in PHP which will work out for each team the best and worst possible outcome from a round robin type tournament.
This code will be executed after each round of games and so will lookup the current W-L-T record for each team as well as the future schedule of games for each team (all of this information is already stored in a database).
My initial thought was to run through each permutation of ranking of each team and remembering the extreme limits for each teams performance. However upon further thinking I realise that for the twelve teams in this case that would result in over 479 million permutations (which may take a little time to calculate, let alone being concise code).
I have unfortunately reached, I fear, the limit of my imagination in devising a logic system to deal with this so any help anyone could offer would be great.
Cheers in advance
Edward
I'll assume a loss is worth 0 points, a tie 1 point and a win 2 points.
For each team t
Sort the teams by their current point table so the last place
team(s) come first and the top teams come last. Put all teams tied with t before t.
Let i be the position of team t in this list
From here on I'll name teams by their position in the list. So we have
from left to right, teams currently worse than i, teams tied with team i, team i,
and finally teams better than i.
Make a working copy of your matrix. For the rest of this
iteration I'll implicitly refer to the working copy.
Suppose (in the working copy) that team i has loses all its remaining games.
For j from 0 up to i
Make a backup copy of the working copy.
for( k:=n-1 ; k < j and j is behind or tied with i ; k := k-1 )
If k hasn't played j and j is behind i
suppose that j beats k
Else if k hasn't played j /* and is tied with k */
suppose that j ties k
if j is still behind i
revert to the backup made before the preceding loop
discard the backup copy
for all games j has yet to play suppose j loses
At this point, all remaining games in the working copy are between teams ahead
of team i, assume all remaining games are ties.
Now (if we have really constructed a worst case scenario) the rank of team i
in the working copy is the worst it can do. I.e. team i beats "count
I'm not completely sure this give the exact lower bound. An upper bound would be symmetric.
Related
Consider I am writing a program to objectively select a winner in a competition. There are 'n' human judges secretly assigning a 1st, 2nd, 3rd position ranking to the top three candidates from a pool of 'm' candidates.
The program must then go through the judges decisions, and based on weights assigned to 1st place, 2nd place and 3rd place, each candidate will be rated based on the number of 1st, 2nd, and 3rd place votes they received, multiplied by the appropriate rating for each finishing position.
However, at the start, the program has no idea of what weights are appropriate, so I have created an automated "program" that is intended to "discover" the proper weights based on how the judges would pick the winner from a hypothetical situation.
I present a table where the horizontal axis contains the finishing position, and the judges' codes (e.g. Judge W, Judge X, Judge Y, Judge Z). The vertical axis has three rows (1st place, 2nd place, 3rd place), and at the intersection of each Judge/Row, I have randomly generated a candidate ID (from the set A through F).
After rendering the table, I then ask the judge who THEY would have chosen as the winner (the judge has the option to PASS if there is not sufficient information to choose).
After the judges run through an appropriate number of scenarios, I wish to now take the results of the various runs and use that information to determine the "best fit" for the weighting of 1st, 2nd, and 3rd positions.
Let's say one of the hypothetical grids looks like this:
<table border="1"><tbody><tr><th>Position</th><th>Judge 'W'</th><th>Judge 'X'</th><th>Judge 'Y'</th><th>Judge 'Z'</th></tr><tr><td>1st</td><td><center>A</center></td><td><center>F</center></td><td><center>C</center></td><td><center>B</center></td></tr><tr><td>2nd</td><td><center>D</center></td><td><center>B</center></td><td><center>E</center></td><td><center>D</center></td></tr><tr><td>3rd</td><td><center>C</center></td><td><center>E</center></td><td><center>B</center></td><td><center>C</center></td></tr></tbody></table>
and the human judge picks candidate "B" as the winner. My program should react by calculating the (w1 + w2 + w3) > (w1 + 2w3) (i.e. B better than C) and (w1 + w2 + w3) > (2 w2) (i.e. B better than D), etc.
From these various algebraic comparisons, over a number of "hypothetical scenarios", I want to be able to calculate the optimum values for w1, w2 and w3. And then, at some point when there is enough "good" data, I want to be able to use these "discovered" weights to go back over the training data an identify areas where perhaps the human judges were mistaken.
I am using PHP as the programming language and don't know which functions or possible existing libraries are appropriate to solve this kind of "fuzzy" equation.
I'm looking for some direction to help me tackle this problem.
Thank you for your assistance.
For the winning candidate count how many times he appears in each position, then do the same for all the other candidates. Then write the following formula for each candidate:
GoodForJ=w1*nw1+w2*nw2+w3*nw3>w1*nj1+w2*nj2+w3*nj3
Where nw1-3 are the times the winner appears in each position and nj1-3 are the times the j candidate appears in each position.
If goodForJ is true for all the candidates this means that the tuple of weights is good. Now you just have to try a bounch of weights combinations and find out which one fits. Trying all combinations of weights between 1 and 10 requires 1000 iterations.
To make things a bit fuzzier, for each try you could count how many timrs goodForJ is true and choose the weights that produces the highest score.
Hi i'm really stuck at a problem when I reorder multiple items at the same time, Let me state the problem more clearly using this example :
If originally i have this table :
Supposedly I want to put A and B, to rank 4 and 5, I should expect a result that looks like this :
However, I'm absolutely clueless how i'm going to do this, systematically. Initially I tried reordering them by considering the change one at a time.
My algorithm is:
1) if an item's rank is to be moved lower:
Adjust all other items above the desired rank, increase their rank by 1 until I reach the original item's rank. So suppose I want to move D from rank 4 to 2.
I will move B and C upward until the original rank of D is filled. Then I update the rank of D.
2) If an item's rank is to be moved higher, just do the opposite.
Problem :
If I use this algorithm for putting A and B to rank 4 and 5 respectively, step by step here's what happens :
This is wrong. Because of the wrong algorithm of course. I move A initially, and A gets to rank 4, but since I only adjust one by one, the A also gets moved when I try to re-rank B.
Question:
What's the best algorithm for reordering multiple items at the same time? and maintaining the sequence of rank of the affected items? I'm coding in php btw, so that would be really great if you could provide a sample code, but an algorithm is enough.
Edit :
I've added 3 examples below to demonstrate the desired movement :
1) #1 case : move C to 2, and B to 4 :
C and B are of course, moved to their respective ranks. But we do know that A,D and E, has an initial ordering of 1, 4, and 5. But since 4 will be taken, we will have to adjust to lower the rank of D instead of increasing it since rank 4 and 5 are both taken. A remains the same and unchanged as well as E.
We do know A comes first before D, and D before E, filling the gaps of 1, 3 and 5.
2) #2 case : move E to 1 and A to 4.
Logically if we move A first, then B should be on #1. But since E is a consideration, instead of going up. adjust rank down.
Still, we do know that B, C and D also has an order. That B comes first, then C then D, in the same way filling the gaps of the "untaken" spots.
3) #last example, here is to simply move A to 5.
- Adjusting all others to go up.
Personally, I'd create a stack as a temporary holder. First push in the lowest ranked value (B), then the next (A) then push in the rest of the items starting from bottom to top. After this push off the stack back into your list starting at the new highest rank first (C, D, E, A, B). If your list of items is enormous, however, this may take some considerable processing power so might not be the best solution.
With all of the daily fantasy games out there, I am looking to see if I can easily implement a platform that will help identify the optimal lineup for a fantasy league based on a salary cap and projected points for each player.
If given a pool of ~500 players and you need to find the highest scoring lineup of within the maximium salary cap restraints.
1 Quarter Back
2 Running Back
3 Wide Receiver
1 Tight End
1 Kicker
1 Defense
Each player is assigned a salary (that changes weekly) and I will assign projected points for those players. I have this information in a MySQL DB and would prefer to use PHP/Pear or JQuery if that's the best option for calculating this.
The Table looks something like this
player_id name position salary ranking projected_points
1 Joe Smith QB 1000 2 21.7
2 Jake Plummer QB 2500 6 11.9
I've tried sorting by projected points and filling in the roster, but it obviously will provide the highest scoring team, but also exceeds the salary cap. I cannot think of a way to have it intelligently remove players and continue to loop through and find the highest scoring lineup based on the salary constraints.
So, is there any PHP or Pear class that you know of that will help "Solve" this type of problem? Any articles you can point me to for reference? I'm not asking for someone to do this, but I've been Googleing for a while and the best solution I currently have is this. http://office.microsoft.com/en-us/excel-help/pick-your-fantasy-football-team-with-solver-HA001124603.aspx and that's using Excel and limited to 200 objects.
I'll suggest two approaches to this problem.
The first is dynamic programming. For brute force, we could initialize a list containing the empty partial team, then, for each successive player, for each partial team currently in the list, add a copy of that partial team with the new player, assuming that this new partial team respects the positional and budget constraints. This is an exponential-time algorithm, but we can reduce the running time by quite a lot (to O(#partial position breakdowns * budget * #players), assuming that all monetary values are integer) if we throw away all but the best possibility so far for each combination of partial position breakdown and budget.
The second is to find an integer programming library callable from PHP that works like Excel's solver. It looks like (e.g.) lpsolve comes with a PHP interface. Then we can formulate an integer program like so.
maximize sum_{player p} value_p x_p
subject to
sum_{quarterback player p} x_p <= 1
sum_{running back player p} x_p <= 2
...
sum_{defense player p} x_p <= 1
sum_{player p} cost_p <= budget
for each player p, x_p in {0, 1} (i.e., x_p is binary)
I am writing a script that creates a tournament fixtures using round robin algorithm with first team fixed. And it works well.
Problem is that when I create those fixtures I have to distribute home and away as close as possible to HAHAHA... pattern where H - is home and A - is away. Where limit is that team cannot play 3 home(or away) matches in a row.
What I tried is preserving how many home and away matches each team played and then team with lowest home or away number will play where it should.
For example
Team 1 (2 H and 1 A) VS Team 2 (with 2 H and 2 A)
Result would be :
Team 2(H) vs Team 1(A) // because Team 1 played least number away of games
Question: Is there other way to implement such home away distribution, and if is what would be the idea behind it?
The equal distribution pattern that you seek is not readily available. The suggestion to do a 'random shuffle' does not solve the problem. Distributing teams equally with opponents, equally as home & visitor, and equally to play in the time/location slots can be done. There are different requirements that must be met for an even number of teams and an odd number of teams. Add to this that the math to create each schedule is totally different (for example a 7 team league schedule is different than an 8 team league).
Checkout the information provided on this link about "equal distribution".
Equal distribution of; teams, time slots, & home & visitor is possible only if you have the correct number of time slots available for the number of teams you are scheduling. Understanding the structure of schedules is very important. Your question above about equal Home & Away (H & A) is answered in the link above. The best you can do is no more than two H or two A games in a row in each round robin. There is a minor exception where a team could have 3 Home or 3 Away games in a row when a round robin is ending and starting the next round robin. This only happens to a few teams, is unavoidable, but H & A is balanced at the end of each 2 round robins.
When scheduling teams for round robin play, in the simplest of terms you are looking to create a round robin of teams, a round robin of home & visitor status, and a round robin of time/location slots... all at the same time.
To further complicate the subject it takes a different number of round robins (one) to satisfy equal 'team' distribution, a different number of round robins (two) to satisfy 'home & visitor' balance, and a different number of round robins to satisfy 'time slot' balance. The number of round robins needed to balance all teams playing equally in all the time slots, for an even number of teams, is equal to half the number of teams being scheduled. This changes when scheduling an odd number of teams.
#Bob R The 'unavoidable' exception of 3H or 3A at the join is in fact avoidable. See D. de Werra (1981) 'Scheduling in sports', in 'Studies on Graphs and Discrete Programming' (editor P. Hansen), North Holland, pp 381-395.
I am building an application that helps manage frisbee "hat tournaments". The idea is people sign up for this "hat tournament". When they sign up, the provide us with a numeric value between 1 and 6 which represents their skill level.
Currently, we are taking this huge list of people who signed up, and manually trying to create teams out of this based on the skill levels of each player. I figured, I could automate this by creating an algorithm that splits up the teams as evenly as possible.
The only data feeding into this is the array of "players" and a desired "number of teams". Generally speaking we are looking at 120 players and 8 teams.
My current thought process is to basically have a running "score" for each team. This running score is the total of all assigned players skill levels. I loop through each skill level. I go through rounds of picks once inside skill level loop. The order of the picks is recalculated each round based on the running score of a team.
This actually works fairly well, but its not perfect. For example, I had a range of 5 pts in my sample data array. I could very easily, manually swap players around and make the discrepancy no more then 1 pt between teams.. the problem is getting that done programatically.
Here is my code thus far: http://pastebin.com/LAi42Brq
Snippet of what data looks like:
[2] => Array
(
[user__id] => 181
[user__first_name] => Stephen
[user__skill_level] => 5
)
[3] => Array
(
[user__id] => 182
[user__first_name] => Phil
[user__skill_level] => 6
)
Can anyone think of a better, easier, more efficient way to do this? Many thanks in advance!!
I think you're making things too complicated. If you have T teams, sort your players according to their skill level. Choose the top T players to be captains of the teams. Then, starting with captain 1, each captain in turn chooses the player (s)he wants on the team. This will probably be the person at the top of the list of unchosen players.
This algorithm has worked in playgrounds (and, I dare say on the frisbee fields of California) for aeons and will produce results as 'fair' as any more complicated pseudo-statistical method.
A simple solution could be to first generating a team selection order, then each team would "select" one of the highest skilled player available. For the next round the order is reversed, the last team to select a player gets first pick and the first team gets the last pick. For each round you reverse the picking order.
First round picking order could be:
A - B - C - D - E
second round would then be:
E - D - C - B - A
and then
A - B - C - D - E etc.
It looks like this problem really is NP-hard, being a variant of the Multiprocessor scheduling problem.
"h00ligan"s suggestions is equivalent to the LPT algorithm.
Another heuristic strategy would be a variation of this algorithm:
First round: pick the best, second round: pair the teams with the worst (add from the end), etc.
With the example "6,5,5,3,3,1" and 2 teams this would give the teams "6,1,5" (=12) and "5,3,3" (=11). The strategy of "h00ligan" would give the teams "6,3,3" (=12) and "5,5,1" (=11).
This problem is unfortunately NP-Hard. Have a look at bin packing which is probably a good place to start and includes an algorithm you can hopefully tweak, this may or may not be useful depending on how "fair" two teams with the same score need to be.