Prize distribution algorithm - algorithm

I have written an algorithm for prize distribution for my tournaments. I just want to know if anyone can see any bug or edge case that I haven't figured out or even write something better and more efficient.
So assuming that at the end of a tournament players get a final scores and based on their score they will be sorted and ranked for example:
Rank Score %total prize
1 50 40%
2 50 25%
3 40 15%
4 20 10%
5 20 5%
6 16 3%
7 10 2%
I want it be in a way that in case of tie of Rank A and Rank B, the prize of these ranked be summed and divided by 2 OR in case of tie between Rank A,Rank B and C the sum of these ranks prizes divide by 3 , etc. If there is no tie between ranks they get their predefined prize. so here is the pseudo code for what I have written so far:
rank=0
while(rank < Max # prizes)
{
prize= %prizeForRank(rank)
offset=1
while(scoreList[rank+offset]!=null && scoreList[rank]==scoreList[rank+offset])
{
prize += %prizeForRank(rank+offset)
offset++
}
prize= prize / offset
for(int k=0; k<offset;k++)
{
prizeOfPlayer[k+rank] = prize
}
rank+=offset
}

Related

How to devide some fixed amount of reward points to players of a racing game in a fair way depending on their finishing time

I'm in need of some kind of algorithm I can't figure out on my own sadly.
My biggest problem is that I have no good way to describe the problem... :/
I will try like this:
Imagine you have a racing game where everyone can try to be the fastest on a track or map. Every Map is worth 100 Points in total. If someone finished a map in some amount of time he gets a record in a database. If the player is the first and only player to finish this map he earns all the 100 points of this map.
Now, that's easy ;) but...
Now another player finishes the map. Let's imagine the first player finishes in 50 Seconds and the 2nd player finishes in 55 seconds, so a bit slower. I now need a calculation depending on both records in the database. Each of both players now earn a part of the 100 points. The faster player a bit more then the slower player. Let's say they finished the exact same time they both would get 50 points from 100, but as the first one is slightly faster, he now earns something around 53 of the points and the slower player just 47.
I started to calculate this like this:
Sum of both records is 105 seconds, the faster player took 50/105 in percent of this, so he earns 100-(50/105*100) points and the slower player 100-(55/105*100) points. The key to this is, that all points distributed among the players always equals to 100 in total. This works for 2 players, but it breaks at 3 and more.
For example:
Player 1 : 20 seconds
Player 2 : 20 seconds
Player 3 : 25 seconds
Calculation would be:
Player 1: 100-(20/65*100) = 69 points
Player 2: 100-(20/65*100) = 69 points
Player 3: 100-(25/65*100) = 61 points
This would no longer add up to 100 points in total.
Fair would be something around values of:
Player 1 & 2 (same time) = 35 points
Player 3 = 30 points
My problem is i can't figure out a algorithm which solves this.
And I need the same algorithm for any amount of players. Can someone help with an idea? I don't need a complete finished algorithm, maybe just an idea at which step i used the wrong idea, maybe the sum of all times is already a bad start.
Thx in advance :)
We can give each player points proportional to the reciprocal of their time.
One player with t seconds gets 100 × (1/t) / (1/t) = 100 points.
Of the two players, the one with 50 seconds gets 100 × (1/50) / (1/50 + 1/55) ≈ 52.4, and the one with 55 gets 100 × (1/55) / (1/50 + 1/55) ≈ 47.6.
Of the three players, the ones with 20 seconds get 100 × (1/20) / (1/20 + 1/20 + 1/25) ≈ 35.7, and the one with 25 seconds gets 100 × (1/25) / (1/20 + 1/20 + 1/25) ≈ 28.6.
Simple observation: Let the sum of times for all players be S. A person with lower time t would have a higher value of S-t. So you can reward points proportional to S-t for each player.
Formula:
Let the scores for N players be a,b,c...,m,n. Total sum S = a+b+c...+m+n. Then score for a given player would be
score = [S-(player's score)]/[(N-1)*S] * 100
You can easily see that using this formula, the sum of scores of all players will be always be 100.
Example 1:
S = 50 + 55 = 105, N-1 = 2-1 = 1
Player 1 : 50 seconds => score = ((105-50)/[1*105])*100 = 52.38
Player 2 : 55 seconds => score = ((105-55)/[1*105])*100 = 47.62
Similarly, for your second example,
S = 20 + 20 + 25 = 65
N - 1 = 3 - 1 = 2
For Player 1, (S-t) = 65-20 = 45
Player 1's score => (45/(2*65))*100 = 34.6
Player 2 => same as Player 1
For Player 3, (S-t) = 65-25 = 40
Player 3's score => (40/(2*65))*100 = 30.8
This method avoids any division in the intermediate states, so there will be no floating point issues for the calculations.

Algorithm to distribute a jackpot between winners

I'm building a betting pool system and I have to split the jackpot between all participants given the number of hits (accurate predictions of a certain sport game) they achieved, where more hits means a bigger prize.
For example, if we want to distribute a 1000 coins jackpot for this betting pool, we could use this distribution:
Is there any algorithm to calculate the prize given to each winner given this conditions?
Without knowing how you want to split the prize, one option is to calculate the total number of hits by all users, and divide the jackpot by that number to find the prize awarded to each hit.
You can then just go through and give each user a prize that is this number multiplied by the number of hits.
You can simply define how big the share for which number of hits is
Hits, winWeight, numberOfWinners
5, 24, n(5)
4, 12, n(4)
3, 4, n(3)
2, 2, n(2)
1, 1, n(1)
than you multiply these values with number of winners and get:
total=24*n(5)+12*n(4)+4*n(3)+2*n(2)+1*n(1)
Now you calculate how many coins:
jackpot/total * 24 = pricePerWinner for 5 hits
jackpot/total * 12 = pricePerWinner for 4 hits
jackpot/total * 4 = pricePerWinner for 3 hits
jackpot/total * 2 = pricePerWinner for 2 hits
jackpot/total * 1 = pricePerWinner for 1 hit
Calculating the amount of total hits.
5*6 = 30
4*40 = 160
3*80 = 240
2*20 = 40
1*15 = 15
0*2 = 0
If you add them all up together it would total up to
30+160+240+40+15+0=485
Since there are 1000 coins for the jackpot.
1000/485 ~= 2
This means that for each hit, it would grant 2 coins.
Eg. 5 hits would mean 10 coins per winner

Algorithm: Fill different baskets

Let's assume I have 3 different baskets with a fixed capacity
And n-products which provide different value for each basket -- you can only pick whole products
Each product should be limited to a max amount (i.e. you can maximal pick product A 5 times)
Every product adds at least 0 or more value to all baskets and come in all kinds of variations
Now I want a list with all possible combinations of products fitting in the baskets ordered by accuracy (like basket 1 is 5% more full would be 5% less accurate)
Edit: Example
Basket A capacity 100
Basket B capacity 80
Basket C capacity 30
fake products
Product 1 (A: 5, B: 10, C: 1)
Product 2 (A: 20 B: 0, C: 0)
There might be hundreds more products
Best fit with max 5 each would be
5 times Product 1
4 times Product 2
Result
A: 105
B: 50
C: 5
Accuracy: (qty_used / max_qty) * 100 = (160 / 210) * 100 = 76.190%
Next would be another combination with less accuracy
Any pointing in the right direction is highly appreciated Thanks
Edit:
instead of above method, accuracy should be as error and the list should be in ascending order of error.
Error(Basket x) = (|max_qty(x) - qty_used(x)| / max_qty(x)) * 100
and the overall error should be the weighted average of the errors of all baskets.
Total Error = [Σ (Error(x) * max_qty(x))] / [Σ (max_qty(x))]

How to define a algorithm that gives a ranking number for at dentist?

I have some problems with defining a algorithm that will calculate a ranking number for a dentist.
Assume, we have three different dentists:
dentist number 1: Got 125 patients and out of the 125 patients the
dentist have booked a time with 75 of them. 60% of them got a time.
dentist number 2: Got 5 patients and out of the 5 patients the
dentist have booked a time with 4 of them. 80% of them got a time.
dentist number 3: Got 25 patients and out of the 14 patients the
dentist have booked a time with 14 of them. 56% got a time.
If we use the formula:
patients booked time with / totalpatients * 100
it will not be the right way to calculate the ranking, as we will get an output of the higher percentage is, the better the dentist is, but it's wrong. By doing it in that way, the dentists would have a ranking:
dentist number 2 would have a ranking of 1. (80% got a time).
dentist number 1 would have a ranking of 2 (60% got a time).
dentist number 3 would have a ranking of 3. (56% got a time).
But, it should be in this way:
dentist number 1 = ranking 1
dentist number 2 = ranking 2
dentist number 3 = ranking 3
I don't know to make a algorithm that also takes the amount of patients as a factor to the ranking-calculation.
It is quite arbitrary how you define what makes a better dentist in terms of number of patients and the percentage of those that have an appointment with them.
Let's call the number of patients P, the number of those that have an appointment A, and the function determining how "good" a dentist is f. So f would be a function of P and A: f(P, A).
One component of f could indeed be what you already calculated: A/P.
Another component would have to be P, but I would think that the effect on f(P, A) of increasing P with 1 would be much higher for a low P, than for a high P, so this component should not be a linear function. It would also be practical if this component would have a value between 0 and 1, just like the other component.
Taking all this together, I suggest this definition of f, which will give a number between 0 and 1:
f(P,A) = 1/3 * P/(10 + P) + 2/3 * A/P
For the different dentists, this results in:
1: 1/3 * 125/135 + 2/3 * 75/125 = 0.7086419753...
2: 1/3 * 5/15 + 2/3 * 4/5 = 0.6444444444...
3: 1/3 * 25/35 + 2/3 * 14/25 = 0.6114285714...
You could play a bit with the constant factors in the formula, like increasing the term 10. Or you could change the factors 1/3 and 2/3 making sure that their sum is 1.
This is just one way to do it. There are an infinity of other ways...

Calculate the Ranks of Candidates based on Votes and Total Candidates

How can I claulate the rank of each candidate when I have the total candidates and votes secured by each?
I've managed the percentage part, but calculating the rank has me stuck.
I'll be using MySql in the end for this, but right now I only need the formula or method to calculate ranks.
Id be glad if you could help with just the formula. Just like the formula for interest is PTR/100.
Total Candidates
5
Total Votes
75
Votes
Name Marks Percentage Rank(What I'm trying to calculate)
A 25 33.34 1/5 ->Rank 1/5 has the most votes
B 20 26.67 2/5 ->And so on
C 10 13.34 4/5
D 5 6.67 5/5
E 15 20.00 3/5
There is a previous question on SO that addresses this, using MySQL and a ranking variable. There is some lovely stuff in the answers
MySQL rank function

Resources