Распределите призы по турнирной системе - PullRequest
3 голосов
/ 04 августа 2010

Я ищу способ распределить число по x единицам.Я даже не знаю, как написать эти слова, поэтому приведу пример:

Есть турнир, в котором общий выигрыш составляет 1000 долларов.Я хочу, чтобы 20 лучших победителей / участников выиграли что-то из этого.
Мне нужен математический алгоритм / формула, который распределит его по всем игрокам и который даст мне возможность контролировать некоторые другие факторы распределения.

Например, я хочу, чтобы победитель № 1 получил 300 долларов.Победитель # 2 получит меньший процент от него.Общее распределение должно дать каждому что-то, пока победитель # 20 (последний), который получит как минимум X $.
X $, не станет еще одним фактором, который я хочу контролировать.

Есть идеи?У этой проблемы есть имя (и как это называется)?Любой пример кода?

Редактировать # 1 - мое первое предложение :

#include <conio.h>
#include <vector>

#define TOTAL                       100
#define WINNERS                     15
#define FIRST_WINNER_PERCENTAGE     0.30

void distribute_1(::std::vector<double> * const prizes)
{
    prizes->clear();

    double total = TOTAL;
    double winning_percentage = FIRST_WINNER_PERCENTAGE;
    double slope = 0.5;
    int winners = WINNERS;

    double winning = 0;
    for(int i = 0; i < winners; i++, total -= winning, winning_percentage /= 2)
    {
        winning = total * winning_percentage;
        prizes->push_back(winning);
    }
}
void distribute_2(::std::vector<double> * const prizes)
{
    prizes->clear();

    double total = TOTAL;
    double winning_percentage = FIRST_WINNER_PERCENTAGE;
    double slope = 0.5;
    int winners = WINNERS;

    double winning = 0;
    for(int i = 0; i < winners; i++, total -= winning/*, winning_percentage /= 2*/)
    {
        winning = total * winning_percentage;
        prizes->push_back(winning);
    }
}
void distribute_3(::std::vector<double> * const prizes)
{
    prizes->clear();

    double total = TOTAL;
    double winning_percentage = FIRST_WINNER_PERCENTAGE;
    double slope = 0.0005;
    int winners = WINNERS;

    double winning = 0;
    for(int i = 0; i < winners; i++, total -= winning, winning_percentage -= slope)
    {
        winning = total * winning_percentage;
        prizes->push_back(winning);
    }
}
void distribute_4(::std::vector<double> * const prizes)
{
    prizes->clear();

    double total = TOTAL;
    double winning_percentage = FIRST_WINNER_PERCENTAGE;
    double slope = 1 / WINNERS;
    int winners = WINNERS;

    double winning = 0;
    for(int i = 0; i < winners; i++, total -= winning, winning_percentage -= slope)
    {
        winning = total * winning_percentage;
        prizes->push_back(winning);
    }
}

void main()
{
    ::std::vector<double> prizes;

    distribute_1(&prizes);
    distribute_2(&prizes);
    distribute_3(&prizes);
    distribute_4(&prizes);

    double total_granted = 0;
    for(int i = 0; i < WINNERS; i++)
    {
        total_granted += prizes[i];
        printf("%lf\n", prizes[i]);
    }
    printf("-\n%lf\n", total_granted);

    _getch();
}

Это насколько я мог достичь.Проблема с этим, например, заключается в том, что если вы установите, например, «ПОБЕДИТЕЛИ» на 5, алгоритм не достигнет значения «ВСЕГО» (100 в этом примере) или даже ближе (я получаю всего 83).

раствор Кристи :

#include <conio.h>
#include<iostream>
//using arithmetic progression
using namespace std;
int i;
float ratio;
float first_prize;
float s;
int main()
{
    float money=1000;
    const int total_prizes =        10;
    float last_prize =              99;
    float prizes[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(i=total_prizes-1;i>=1;i--){
       prizes[i]=prizes[i+1]+ratio;
       money-=prizes[i];
    }
    for(i=1;i<=total_prizes;i++){
        printf("%d) %.2f\n",i,prizes[i]);
        s+=prizes[i];
    }
    printf("TOTAL SUM:%.2f\n",s);
    printf("Ratio: %.2f", ratio);
    _getch();
}

Ответы [ 5 ]

3 голосов
/ 05 августа 2010

Здесь 1:15 утра, и я решаю математику:)).
Используя арифметическую прогрессию.
Я сделал все, используя определения, чтобы вы могли легко их изменить.

#include<iostream>
//using arithmetic progression
using namespace std;
FILE *g=fopen("output.out","w");
#define last_prize 10
#define total_prizes 20
int i;
float prizes[total_prizes+1];
float money=1000;
float ratio;
float first_prize;
float s;
//a1=last_prize
//an=first_prize
int main(){
 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(i=total_prizes-1;i>=1;i--)
       prizes[i]=prizes[i+1]+ratio;
 for(i=1;i<=total_prizes;i++){
  fprintf(g,"%d) %.2f\n",i,prizes[i]);
  s+=prizes[i];
 }
 fprintf(g,"TOTAL SUM:%.2f",s);
return 0;
}

ВЫХОД:

1) 90.00
2) 85.79
3) 81.58
4) 77.37
5) 73.16
6) 68.95
7) 64.74
8) 60.53
9) 56.32
10) 52.11
11) 47.89
12) 43.68
13) 39.47
14) 35.26
15) 31.05
16) 26.84
17) 22.63
18) 18.42
19) 14.21
20) 10.00
TOTAL SUM:1000.00

Как вы можете видеть, они составляют в сумме ровно 1000,00 $: D

Другие результаты:
ВХОД:

#define last_prize 30
#define total_prizes 5

ВЫХОД:

1) 370.00
2) 285.00
3) 200.00
4) 115.00
5) 30.00
TOTAL SUM:1000.00
2 голосов
/ 05 августа 2010

Вы можете сделать простую формулу, как.

#include<iostream>
using namespace std;
FILE *g=fopen("output.out","w");
int i;
int prizes[21];
int money=1000;
int main(){
    for(i=1;i<=20;i++){
       prizes[i]=(float)(15+(20-i))/100*money;
       money-=prizes[i];
    fprintf(g,"%d) %d\n",i,prizes[i]);
      }
return 0;
}

Будет выведено:

1) 340
2) 217
3) 141
4) 93
5) 62
6) 42
7) 29
8) 20
9) 14
10) 10
11) 7
12) 5
13) 4
14) 3
15) 2
16) 2
17) 1
18) 1
19) 1
20) 0

Но вы можете изменить значения на что угодно:).
Это просто быстрый и простой способ сделать это.

Начальная идея для этого алгоритма:
1-й приз: 30% от всех денег (1000 $) = ~ 330 $
2-й приз: 30% от остальных (670 $) = ~ 201
3-й приз: 30% от остальных ... и т.д ...
Если вы замените (15+ (20-i)) на 20, скажем, вы получите такой вывод:
Просто измените это значение, чтобы получить разные результаты.

1) 200
2) 160
3) 128
4) 102
5) 82
6) 65
7) 52
8) 42
9) 33
10) 27
11) 21
12) 17
13) 14
14) 11
15) 9
16) 7
17) 6
18) 4
19) 4
20) 3

EDIT: И еще кое-что. После разделения всех денег с использованием этих алгоритмов могут остаться некоторые деньги (потому что последний получает х% от остальных). Вы можете добавить оставшийся на первое место ...

1 голос
/ 04 августа 2010

У меня была эта проблема для пула - я хотел, чтобы 3 уровня отдельных призов имели одинаковое относительное соотношение (70% / 20% / 10%), но признавал вероятность связей, поэтому я должен был это учитывать. Я не хотел просто делить банк, а затем присуждать призы, поскольку у вас могут получиться связи за второе место, а отдельный победитель, занявший второе место, получит меньше, чем обладатель третьего места.

P (i) = размер приза N (i) = количество победителей

1) Сумма (по i) P (i) * N (i) = 1000

2) P (1) / P (2) = 70/20

3) P (2) / P (3) = 20/10

В моем случае 3 уравнения на 3 неизвестных - которые я решил получить, чтобы получить единственное решение.

Для вашего примера P (1) = 300 долларов. Я бы просто указал последовательные соотношения призов и решил бы линейную систему уравнений.

Также рассмотрите возможность здесь для раздачи призов для гольфа на недавнем Открытом чемпионате Великобритании. Я не говорю, что PGA мог бы работать лучше, чем талант на этом сайте, но это демонстрация вашего вопроса в действии.

0 голосов
/ 24 сентября 2015

Формула в первой строке Кристи неверна.first_prize = 2 * деньги / total_prizes + last_prize;Это должно быть first_prize = 2 * money / total_prizes - last_prize;

Вот мое решение в python, это добавит остаточную сумму к лучшим победителям.

starting_amount = (((winnings * 2) / float(no_of_winners)) - last_amount)

difference = (last_amount - starting_amount) / float(no_of_winners - 1)
for rank in range(1, no_of_winners + 1):
    reward = starting_amount + difference * (rank - 1) 
    reward = round_amount(reward)
    winnings -= reward
    winning_amount[rank] = reward

residual_winnings = winnings
residual_shares = {1: 0.5, 2: 0.3, 3: 0.2} 

if no_of_winners < 3: 
    winning_amount[1] += residual_winnings
else:
    for rank in residual_shares:
        reward = residual_winnings * residual_shares[rank]
        reward = round_amount(reward)
        winning_amount[rank] += reward
0 голосов
/ 05 августа 2010

Предположим, что все деньги M, вы хотите распределить по n пулам таким образом, чтобы первый получал в k раз больше, чем второй, а второй получал в k раз больше, чем третий, и так далее. Предположим, что последний получил х сумму денег, тогда

x + k * x + k ^ 2 * x ... k ^ (n-1) * x = M x (k ^ n-1) / (k-1) = M

Решите для х из этого уравнения на основе значения к вы выбираете и распределите деньги: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...