b.lopes
b.lopes

Reputation: 475

get dynamic ration for distrubution prize java

I have this algorithm that works, but I want to change it to have a dynamic ratio in order to have the distance of values for the first positions higher than those ones for the lastest positions.

So for instance if prize money = 1000, total_prizes = 5, last_prize = 50 I got:

1) 350.00
2) 275.00
3) 200.00
4) 125.00
5) 50.00
TOTAL SUM: 1000.00

What I would like to see should be:

1) 475.00
2) 250.00
3) 150.00
4) 75.00 
5) 50.00
TOTAL SUM: 1000.00

Instead of having between positions always a fixed value of 75. Have an increase distance approaching the first positions, in this case from 5) to 4) 25 from 4) to 3) 75 from 3) to 2) 100 from 2) to 1) 225

Here the current code:

public static void main(String[] aa){
        float ratio;
        float first_prize;
        float s=0;
        float money = 1000;
        int total_prizes = 5;
        float last_prize = 50;
        float prizes[] = new float[total_prizes+1];

        first_prize=2*(money/total_prizes)-last_prize; //last member of the progresion

        ratio=(first_prize-last_prize)/(total_prizes-1);

        prizes[total_prizes]=last_prize;

        for (int j = total_prizes-1; j >=1; j--) {
        prizes[j]=prizes[j+1]+ratio;
        }

        for(int k=1;k<=total_prizes;k++){
            System.out.printf("%d) %.2f\n",k,prizes[k]);
            s+=prizes[k];
        }
        System.out.printf("TOTAL SUM: %.2f\n",s);
    }

Inside the loop:

for (int j = total_prizes-1; j >=1; j--) {
  //ratio here should be calculated dynamically based on position...
    prizes[j]=prizes[j+1]+ratio;
        }

Thanks! :)

Upvotes: 0

Views: 81

Answers (1)

btilly
btilly

Reputation: 46497

If I understand you, what you want is to have the following conditions:

  1. Fixed total sum. In this case 1000.
  2. Approximately a geometric ratio r with n terms. In this case 1.75.
  3. All "round" numbers. In this case to the nearest 25.

I would suggest that you solve it by first creating an exact geometric sequence, and then tweak it to be round numbers.

The first step is easy because all geometric series with n terms look like this:

x + r * x + r^2 * x + ... + r^(n-1) * x
    = x * (1 + r + r^2 + ... + r^(n-1))
    = x * (1 + r + r^2 + ... + r^(n-1)) * (r - 1) / (r - 1)
    = x * ((r - 1) + (r^2 - r) + (r^3 - r^2) + ... + (r^(n) - r^(n-1)) / (r - 1)
    = x * (-1 + (r - r) + (r^2 - r^2) + ... + (r^(n-1) - r^(n-1)) + r^n) / (r - 1)
    = x * (r^n - 1) / (r - 1)

So in we want

1000 = x * (r^n - 1) / (r - 1)
     = x * (1.75^5 - 1) / (1.75 - 1)
     = x * (16.4130859375 - 1) / 0.75
     = 20.55078125 x

That gives us the following starting solution.

48.6599505797377
85.154913514541
149.021098650447
260.786922638282
456.377114616993

After that it is a question of tweaking those numbers up and down to get the answer that you want. There are a lot of ways you can do that. One is simply to start with the smallest and move it to a rounded number, and redistribute among the others in proportion to their weights, and continue. That gives you the following sequence of partial answers.

48.6599505797377
85.154913514541
149.021098650447
260.786922638282
456.377114616993

50
85.034965034965
148.811188811189
260.41958041958
455.734265734266

50
75
150.537634408602
263.440860215054
461.021505376344

50
75
150
263.636363636364
461.363636363636

50
75
150
275
450

This is not exactly your desired answer. But it is pretty darned close and hopefully acceptable as a strategy.

UPDATE I had tried 1.75 because it was close to (475/50)^(1/4). When I tried 1.8 instead I got your exact desired answer.

Furthermore note that we do not need to produce all of those intermediate answers. Each time we only need the smallest term. Which is given by target * (r-1) / (r^n - 1). Every time you find the smallest term, you subtract that from the target, reduce n by one, and repeat.

Upvotes: 2

Related Questions