Вероятность получения конкретной суммы из n m-sided кости c # - PullRequest
0 голосов
/ 08 октября 2018

Я пытаюсь сгенерировать вероятность получения определенного числа из n кубиков, без гарантии того, что у них одинаковое количество сторон.(например, 1d6 + 2d10)

Я знаю, что есть действительно дорогой способ сделать это (с рекурсией), но если есть математический способ определения вероятности того или иного события, это было бы намного лучше.

Ответы [ 3 ]

0 голосов
/ 08 октября 2018

Один из способов сделать это:

  • Создать выходной массив count с суммой длины (стороны всех кубиков) +1, т. Е. Так, чтобы максимальное значение, которое может быть выброшено, работало как индекс.
  • Это число способов, которыми индекс может быть свернут.Инициализируйте это с [0] = 1.
  • Для каждого кубика из N сторон перечислите результаты каждого возможного броска.
    • Скопируйте существующий массив счетчиков в prev, скажем, и создайте новый пустой массив счетчиков
    • для roll = от 1 до N, для total = от 0 до count.length-1-roll, count[total + roll] + = prev [total]
  • Теперь вероятность скользящего значения = count [value] / sum (count)

Примечания:

  • Это, как вы и опасались, не слишком дорого или требует рекурсии.Это будет O (N ^ 2), где N - общее количество граней на всех кубиках.
  • Это вычислит вероятность всех выходов, а не только одного интересующего вас выхода, что может быть проблемой.если общее количество граней чрезвычайно велико, а значение, которое вас интересует, мало.Вы можете ограничить массив count длиной (интересующее вас значение) + 1, если это необходимо, и вычислить общее количество бросков как произведение каждой матрицы, когда вы обрабатываете его, а не из суммы (количества), как я.мы предложили выше.
0 голосов
/ 08 октября 2018

@ Rup уже дал одно стандартное решение - метод динамического программирования снизу вверх.

Подход сверху вниз - написать рекурсивную функцию ... а затем запомнить ее .То есть, когда вызывается ваша функция, вы сначала проверяете, видели ли вы это раньше (т. Е. Заглядываете в словарь, чтобы узнать, есть ли у вас «памятка» об ответе), а если нет, вычисляете ответ исохрани это.Затем вы возвращаете запомненный ответ.

Применяются обычные компромиссы:

  1. Сверху легче вычислить и написать.
  2. Снизу вверх вы видите, что выне нужно хранить ответы с 2 кубиками, когда у вас есть 3 кубика, и, следовательно, снижает требования к рабочей памяти.

Поэтому полезно знать оба подхода, но я всегда беру сверху внизподход первый.

0 голосов
/ 08 октября 2018

Здесь я сгенерировал 2 броска костей

1 Randon () будет сгенерирован из n граней

2 здесь n раз бросается на

3 отображается сумма дляn roll

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dicerolling
{
    class Program
    {
        static void Main(string[] args)
        {

            Random x = new Random();
            int throw_times = 1;
            int sum = 0;
            int[] dice = new int[2];
            dice[0] = x.Next(1, 7);
            dice[1] = x.Next(1, 7);
            Console.WriteLine("enter the no of rollings :");
            var n = int.Parse(Console.ReadLine());
            for (int i = 1; i <= n; i++)
            {
                dice[0] = x.Next(1, 7);
                dice[1] = x.Next(1, 7);

                int total_var = dice[0] + dice[1];
                sum +=  dice[0] + dice[1] ;//total in array

                Console.Write("Throw " + throw_times + ": " + dice[0] + " d " + dice[1] + " = ");
                Console.WriteLine(total_var);
                throw_times++;

                Array.Sort(dice);

                for (int a = dice.Length - 1; a >= 0; a--)
                {
                    int s = dice[a];
                    Console.WriteLine("#" + s);
                }
            }

            Console.WriteLine("Total sum: " + sum);//only returns sum of last 2 rolls


            Console.ReadLine();
        }
    }
}
...