Dice Sum Probability with Different types of Dice

偶尔善良 提交于 2021-01-27 14:50:45

问题


I am currently working on a java application where I need to calculate the probabilities of rolling each sum for a variety of dice. The dice types I am supporting are d4 (4 sided dice), d6 (6 sided dice), d8 (8 sided dice), d10, d12, and d20. The user will be able to input the number of each type of dice they want to use in the calculation. For example, a user may enter 6 d6 and 4 d4.

With this given information (the number of dice of each type), I am looking to calculate the probability that each possible sum could be rolled. I will then be using this information to create a chart showing the probability distribution from the selected combination of dice provided.

This application is being written in Java.

Where I am currently at is I have a function that will calculate the probability of a specific sum for a using only one size of dice

/*
    Recursively calculates the probability of rolling a particular number
    when rolling multiple dice of one type
    @param dice Number of dice
    @param seekedValue Value whose probability is being calculated
    @param sides Number of sides on the type of die
     */
    private double diceProb(int dice, int seekedValue, int sides){
        if (dice == 0){
            if (seekedValue == 0){
                return 1.0;
            } else {
                return 0.0;
            }
        } else {
            double sum = 0;
            for (int i = seekedValue - sides; i < seekedValue; i++){
                sum += diceProb(dice -1, i, sides) / sides;
            }
            return sum;
        }

    }

I then use this code to find all the possible probabilites

/*
Variable Explanations:
diceEntries: This array list contains the number of each dice supplied by the user.
It is ordered by number of sides, with d4 at the beginning and d20 at the end
diceValues: This array contains the sides of the dice types
probArray: this array list will contain the probabilities of each sum possible
min: the minimum sum  possible
max: the maximum sum possible
*/
ArrayList<Integer> diceEntries
ArrayList<Float> probArray = new ArrayList<>();
int[] diceValues = {4,6,8,10,12,20};
float prob = 0;
for (int i = min; i <= max; i++){
    for (int j = 0; j <= 5; j++) {
        prob = (float) diceProb(diceEntries.get(j), i, diceValues[j]);
        if (prob != 0) {
            probArray.add(prob);
        }
    }
}

My current code is only able to handle dice of one size, ie only d6s or d4s and not a mix of them.

If the community can provide some guidance, it would be greatly appreciated. I am open to over approaches as well. For example, I have read that generating functions might be a better way of doing this, but my combinatorics statistics are a bit weak and if someone did have a way of coding that up, it would nice to see it.

Thanks a lot folks


回答1:


Another entry for the brute force method, using a list of Integers(dice sides) to handle multiple die types. The advantage is that if you want a lot of probabilities, you can run it once then just query the various probabilities. The disadvantage is that as a brute force method it's very inefficient for just getting a single probability.

public int[] probs;

public void genRolls(int sum, List<Integer> sides)
{
    if (sides.size() == 0)
    {
        probs[sum]++;
        return;
    }
    int top = sides.get(0);
    for (int x = 1; x <= top; x++)
        genRolls(sum+x, sides.subList(1, sides.size()));
}

public void diceprob(int target, List<Integer> sides)
{
    int maxval = 0;
    double possibilities = 1;
    for (Integer i : sides)
    {
        maxval+= i;
        possibilities *= i;
    }
    probs = new int[maxval+1];
    genRolls(0, sides);
    System.out.println("Probability is " + (probs[target]/possibilities));
}



回答2:


You could simply simulate all combinations. The code below does this for nD6, but the example should be expandable to multiple dice types.

public class Main {

    static final int FACES = 6;
    int[] buckets;
    int[] currentCombination;
    int totalCombinations;

    public Main(int numberOfDices) {
        this.buckets = new int[FACES * numberOfDices];
        this.currentCombination = new int[numberOfDices];
        this.totalCombinations = 0;
    }

    public void calculate() {
        calculate(this.currentCombination.length);
        for (int i = 0; i < this.buckets.length; ++i) {
            System.out.println((i + 1) + ":\t" + this.buckets[i] + " / "
                    + this.totalCombinations);
        }
    }

    public void calculate(int dicesLeft) {
        if (0 == dicesLeft) {
            int sum = 0;
            for (int die : this.currentCombination) {
                sum += die;
            }
            ++this.buckets[sum - 1];
            ++this.totalCombinations;
        } else {
            --dicesLeft;
            for (int die = 1; die <= FACES; ++die) {
                currentCombination[dicesLeft] = die;
                calculate(dicesLeft);
            }
        }
    }

    public static void main(String... args) {
        int n = Integer.parseInt(args[0]);
        Main m = new Main(N);
        m.calculate();
    }
}



回答3:


The probability of a sum of independent variables is the convolution of the probability of each variable. For discrete variables, the convolution is a simple summation which you can easily implement in Java. My advice is to organize the calculation like this:

get numbers of dice and numbers of sides
for each die
    construct array with length=number of sides and each element=1/(number of sides)

let convolution result=first array
for second through rest of arrays
    let convolution result = convolution(result, next array)

output result

The convolution of several functions can be computed two at a time; it doesn't matter what order.

The convolution for two arrays a and b is just:

for i=0 through length(a) + length(b) - 2 inclusive,
    conv[i] = sum(a[j]*b[i - j], j, max(0, i - length(b) + 1), min(length(a) -1, i))

You can check your results very conveniently with, say, Octave. conv is the convolution function in Octave.



来源:https://stackoverflow.com/questions/29854866/dice-sum-probability-with-different-types-of-dice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!