Java random is always delivering a negative trend on the long run?
Asked Answered
E

3

11

I'm constructing an app and for that I have a function to fill it with test data. Short outline:

        HashMap<String, Long> iIDs = new HashMap<String, Long>();
        HashMap<String, Integer> vals = new HashMap<String, Integer>();

        long iID1 = addIndicator("I1", "i1", Color.RED);
        long iID2 = addIndicator("I2", "i2", Color.BLUE);
        long iID3 = addIndicator("I3", "i3", Color.GREEN);
        long iID4 = addIndicator("I4", "i4", Color.MAGENTA);

        iIDs.put("iID1", iID1);
        iIDs.put("iID2", iID2);
        iIDs.put("iID3", iID3);
        iIDs.put("iID4", iID4);

        int v1 = 80;
        int v2 = 30;
        int v3 = 25;
        int v4 = 40;

        vals.put("v1", v1);
        vals.put("v2", v2);
        vals.put("v3", v3);
        vals.put("v4", v4);

        int numDays = 500;
        int dateDistance = 14;

        Calendar c = Calendar.getInstance();

        for(int i=0;i<numDays;i++)
        {
            c.add(Calendar.DATE, dateDistance);
            for(int j=1;j<5;j++)
            {
                int currVal = vals.get("v"+j);
                int rand = new Random().nextInt(6);
                int newVal; 

                if(rand <= 2) // 0, 1, 2
                    newVal = currVal + rand;
                else          // 3, 4, 5
                    newVal = currVal - rand;

                pseudo: addPointForIndicator();
                vals.put("v"+j, newVal);
            }
        }

No matter how often I create the test data, the picture looks always like this: Graph

So the trend of the random numbers is always negative. Why is that?

Earache answered 21/9, 2012 at 10:22 Comment(4)
Why do you create a new Random object in each loop iteration?Roach
Not that it necessarily explains your results, but your usage of Random is wrong. You must share the same instance across all calls, otherwise you are not getting a pseudorandom sequence.Guerrero
Use the same instance of java.util.Random for generation of all random numbers. This will "increase randomization" by making the randomization true pseudo-randomization.Chemosphere
Thanks, now I created the Random above the first for-loop, but as you said, the picture doesn't change. I'm just wondering...Earache
G
6

It is quite clear from your logic that it must create a negative trend, even ignoring the fact that your usage of Random doesn't follow the contract. You add a number in the range [0,2] half of the time and subtract a number in the range [3,5] the other half of the time. The code is easy to fix, though:

if(rand <= 2) // 0, 1, 2
  newVal = currVal + rand;
else          // 3, 4, 5
  newVal = currVal - rand + 3;

And a cleaner fix would be

newVal = currVal + random.nextInt(7)-3;

This has the additional benefit that it allows the value to stay unchanged sometimes, which I believe should be a more proper way to simulate your data.

Guerrero answered 21/9, 2012 at 10:28 Comment(2)
lol... you're right... :) ahh, logic, my enemy... thanks! I'll mark your post as answer in 5 minEarache
@downvoter Why on Earth would you downvote this perfectly good, accepted answer? This is certainly nothing but vandalism, and the sorriest kind -- hiding behind your anonymity.Guerrero
K
2

I am not sure what you are trying to do, but the following block would seem to produce a negative trend

if(rand <= 2) // 0, 1, 2
    newVal = currVal + rand;
else          // 3, 4, 5
    newVal = currVal - rand;

You are adding small numbers and subtracting larger ones.

Koumis answered 21/9, 2012 at 10:29 Comment(1)
Right, Marko Topolnik just brought me to this... sometimes the most obvious is the hardest to see :PEarache
N
0

I dont know what is your purpose, but try to make a lower bound. Like

2+random.nextInt()

Where random is your Random class instance. And as the others guys said, use the same instance, you cant generate a "correct" sequence like that.

Network answered 21/9, 2012 at 10:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.