Get a randomized aberrancy around given value

后端 未结 4 2050
栀梦
栀梦 2021-01-27 02:30

I would like to add a kind of ripple to an array of known values of type double. I point that out because Random.Next / Random.NextDouble() behave different.

4条回答
  •  盖世英雄少女心
    2021-01-27 03:06

    Below is my solution.

    Basically, it "jitters" each value by some specified percentage, and then checks the difference between the original total and the "jittered" total. In order to make the final total match the original total, it adds a flat amount to each "jittered" value.

    I feel like this is not a great solution from a mathematical perspective, because I think that adding the flat amount to each value will probably distort the true percentage of abberation for each value. There is probably a more mathematically correct way to apply the remainder across the set of values in such a way as to preserve the intended percentage of abberation, but I imagine that doing so would require several passes, whereas this solution completes in a set number of passes.

    // prepare data
    double[] values = new double[20];
    for (int i = 0; i < values.Length; i++)
    {
        values[i] = 40.0;
    }
    
    // get the original total
    double originalTotal = 0.0;
    for (int i = 0; i < values.Length; i++)
    {
        originalTotal += values[i];
    }
    
    // specify an abberation percentage
    double x = 0.05;
    
    // jitter each value +/- the abberation percentage
    // also capture the total of the jittered values
    Random rng = new Random();
    double intermediateTotal = 0.0;
    for (int i = 0; i < values.Length; i++)
    {
        values[i] += values[i] * (rng.NextDouble() - 0.5) * (2.0 * x);
        intermediateTotal += values[i];
    }
    
    // calculate the difference between the original total and the current total
    double remainder = originalTotal - intermediateTotal;
    
    // add a flat amount to each value to make the totals match
    double offset = remainder / values.Length;
    for (int i = 0; i < values.Length; i++)
    {
        values[i] += offset;
    }
    
    // calculate the final total to verify that it matches the original total
    double finalTotal = 0.0;
    for (int i = 0; i < values.Length; i++)
    {
        finalTotal += values[i];
    }
    

提交回复
热议问题