javarandomweighting

Why are the mean values not much closer to the original weightings?


I run the following program and a typical console output is as follows.

Mean percentage points for weighting 0 is: 57.935590153643616
Mean percentage points for weighting 1 is: 42.06440984635654

Why are these printed means not much closer to 60 and 40?

public static void main(String[] args) {
    Random rand = new Random();

    int numCycles = 5000;

    double[] weightings = {60.0, 40.0};
    double[] weightedRandoms = new double[weightings.length];
    double[] totPercentagePoints = {0.0, 0.0};

    for (int j = 0; j < numCycles; j++) {

        for (int k = 0; k < weightings.length; k++) {
            weightedRandoms[k] = (rand.nextInt(10) + 1) * weightings[k]; // +1 to the random integer to ensure that the weighting is not multiplied by 0
        }

        for (int k = 0; k < weightings.length; k++) {
            totPercentagePoints[k] += weightedRandoms[k] / DoubleStream.of(weightedRandoms).sum() * 100;
        }
    }

    for (int i = 0; i < weightings.length; i++) {
        System.out.println("Mean percentage points for weighting " + i + " is: " + totPercentagePoints[i] / numCycles);
    }
}

Solution

  • You are estimating 100*E(X/(X+Y)] and 100*E(Y/(X+Y)] where X = 60*U(1,10) and Y = 40*U(1,10) (where U(1,10) is the discrete uniform distribution on 1,..,10). Since there are only 10*10 = 100 possible ways to generate two such uniform variables, you can compute the expressions for each such pair and then compute these expectations directly. In Python define:

    def f(x,y): return 60*x/(60*x + 40*y)
    

    and then:

    >>> sum(f(x,y) for x in range(1,11) for y in range(1,11))
    58.36068355253924
    

    Note that the 100 you multiply by cancels out exactly the factor of 1/100 that you would need in computing the expectation.

    Similarly if you define:

    def g(x,y): return 40*y/(60*x + 40*y)
    

    Then:

    >>> sum(g(x,y) for x in range(1,11) for y in range(1,11))
    41.639316447460756
    

    These do mesh with what you are observing.