确保奖池所奖励的并列参与者不比得分差的参与者 [英] Ensure prize pool doesn't award tied participants less than participants who scored worse

查看:113
本文介绍了确保奖池所奖励的并列参与者不比得分差的参与者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有$ 1000(可变),并且我想将这笔钱分配给20个(可变)人,但不是平均分配给每个人,我想给第一个人更多,第二人称,等等.

If I had $1000(variable) and I want to split that amount up and give it to 20(variable) people, but rather than give it evenly to each person, I want to give more to the 1st person, and the 2nd person, etc.

因此,第20个人的人数最少,而第5个人的人数最多.

So the 20th person gets the least, and the 5th person gets the 5th most.

人们按分数分类到一个列表中,我该如何检查以确保分数相同的人获得了相同数量的奖金,同时仍将奖金总额分配给了所有人?

People are sorted into a list by score, how could i check to make sure people with the same score are awarded the same amount of the prize while still giving out the prize total to all people?

到目前为止的公式:

int people = 20;
float prize = 1000;

List<int> list = new List<int>();

for( int i = 0; i < people; ++i )
{
    list.add(Random.Range(0,100));
}

list.Sort();

float k = (2 * prize) / ((people) * (people - 1));
float sum = 0;

for (int i = 1; i < list.Count-1; ++i)
{
    var personsPrize = i * k;
    sum += personsPrize;
    Console.WriteLine(personsPrize);
}
Console.WriteLine("sum = " + sum);

第一名将获得总奖池的25%.第二名获得20%,第三名获得15%,然后将其余部分分配给其余人员,得分相同的人获得相同的金额.

First place would get 25% of the total prize pool. Second place gets 20% and third place gets 15% then the rest is divided between the remaining people, with people on the same score getting the same amount.

首先被并列的人们应该怎么做?他们不应比别人得到的少,但不应使一等奖的价值翻倍.

What should happen for people getting tied first equal? They shouldn't get less than anybody else, but shouldn't double the first prize value.

推荐答案

我会先拆分奖金部分,然后确定由于平局应该合并哪些奖金,以做到这一点.然后,将合并的分数相加,然后将合并的数量平均分配给所有并列的参与者.

I'd do it by splitting out the prize fractions first, and determining which prizes should be merged due to ties. Then, sum up the merged fractions and divide that merged amount equally to all the tied participants.

这确保了每个并列参与者的收到的金额都小于或等于合并的最大奖励金额,并且大于或等于合并的最小奖励金额.

This ensures that the amount received for each tied participant is less than or equal to the greatest prize amount merged in and greater than or equal to the least prize amount merged in.

   public class Person
   {
      public Person(string name, int position)
      {
         Name = name;
         Position = position;
      }
      public string Name { get; set; }
      public int Position { get; set; }
   }

      static void Main(string[] args)
      {
         var winners = new Person[]
         {
            new Person("Test 1", 1),
            new Person("Test 2", 1),
            new Person("Test 3", 1),
            new Person("Test 4", 1),
            new Person("Test 5", 5),
            new Person("Test 6", 6),
            new Person("Test 7", 7),
            new Person("Test 8", 8),
            new Person("Test 9", 9),
            new Person("Test 10", 9),
            new Person("Test 11", 11),
            new Person("Test 12", 11),
            new Person("Test 13", 13),
            new Person("Test 14", 14),
            new Person("Test 15", 15),
            new Person("Test 16", 16),
            new Person("Test 17", 17),
            new Person("Test 18", 18),
            new Person("Test 19", 19),
            new Person("Test 20", 19)
         };

         var prizes = SplitPrizeFund(1000, winners.Length);
         AllocatePrizes(winners, prizes);
      }

      private static void AllocatePrizes(IEnumerable<Person> positions, double[] prizes)
      {
         var orderedPositions = positions.OrderBy(f => f.Position).ToArray();

         for (var pos = 0; pos < orderedPositions.Length;)
         {
            var currentPerson = orderedPositions[pos];
            // Find equally placed people (if any)
            var comList = orderedPositions.Skip(pos).Where(f => f.Position == currentPerson.Position).ToList();

            // We should now have one or more people in our list
            var splitWays = comList.Count;

            // Total the prize fund over the places found
            double splitFund = prizes.Skip(pos).Take(splitWays).Sum();

            // Allocate the total winnings equally between winners of this place
            bool first = true;
            foreach (var person in comList)
            {
               if (first)
               {
                  Console.WriteLine($"{person.Name,-20} {(splitFund / splitWays),10:C2}");
                  first = false;
               }
               else
               {
                  // Identify equal placed winners 
                  Console.WriteLine($"{person.Name,-19}= {(splitFund / splitWays),10:C2}");
               }
            }

            pos += splitWays;
         }
      }

      private static double[] SplitPrizeFund(double totalFund, int numberOfPrizes)
      {
         var prizes = new double[numberOfPrizes];
         var remainingFund = totalFund;
         int remainingPrizes = numberOfPrizes;

         // Special handling for top three places
         int pos = 0;
         prizes[pos] = Math.Round(remainingFund * 0.25, 2, MidpointRounding.AwayFromZero);
         pos += 1;
         prizes[pos] = Math.Round(remainingFund * 0.20, 2, MidpointRounding.AwayFromZero);
         pos += 1;
         prizes[pos] = Math.Round(remainingFund * 0.15, 2, MidpointRounding.AwayFromZero);
         pos += 1;
         remainingPrizes -= 3;
         remainingFund -= prizes[0] + prizes[1] + prizes[2];

         // Linear reducing split from 4th (replace this with whatever you want)
         int totalPortions = 0;
         for (int i = 1; i <= remainingPrizes; i++)
            totalPortions += i;

         for (int i = remainingPrizes; i >= 1; i--)
         {
            prizes[pos] = Math.Round(remainingFund * i / totalPortions, 2, MidpointRounding.AwayFromZero);
            remainingFund -= prizes[pos];
            totalPortions -= i;
            pos++;
         }

         return prizes;
      }

这篇关于确保奖池所奖励的并列参与者不比得分差的参与者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆