2

I know how to get a range of random numbers between 0 zero and any number.

But what I want to know is, since the random number generator is not truly random, and follows a specific algorithm, for example if you pass a seed of 20. then it will always generate the same sequence of numbers: 17, 292, 0, 9.

So I get that. Since it follows a specific algorithm, is there a way I can force the generator to always start at zero or any other number?

But specifically zero in my case.

chinloyal
  • 1,023
  • 14
  • 42
  • which benefit are you expecting? – Roland Nov 22 '18 at 11:38
  • I'm suppose to generate the start time for some processes but the start time should be random. At least one should start at zero. And I have no control over whether any of the processes start at zero, since its random. @Roland – chinloyal Nov 22 '18 at 11:42
  • 5
    Sounds like an XY problem. (You think you want to modify the random number generator, but you really just want a different application of random numbers....) Easy solution: Let's say you have N processes. Given them all a random start time. Then re-assign `process_start_times[RAND() % N] = 0` after that. – selbie Nov 22 '18 at 11:44
  • `Random.nextInt(1);` will give you zero. Otherwise, you'll have some `Random.nextInt(xxx)` and you could generate random numbers until you get zero. Then record the seed that led to that value. So you could seed your Random object to that value and the nextInt(xxx) will give you zero. If you change xxx it might not give you zero anymore. – matt Nov 22 '18 at 11:46
  • Somewhat related: https://stackoverflow.com/questions/2911432/reversible-pseudo-random-sequence-generator – Thilo Nov 22 '18 at 11:49

2 Answers2

5

No need to hack the Random class, just write your own:

public class RandomGenerator {

    private int bound;
    private Random random;
    private boolean firstCall = true;

    public RandomGenerator(int bound, long seed) {
        this.bound = bound;
        random = new Random(seed)
    }

    public int next() {
        if (firstCall) {
            firstCall = false;
            return 0;
        }
        return random.nextInt(bound);
    }
}
Benoit
  • 5,118
  • 2
  • 24
  • 43
  • 1
    I prefer this answer over the other since it preserves all entropy. The other answer which searches for a suitable seed effectively shrinks the seed-space by factor 100 (in case of xxx=100), which causes you to loose randomness (the pool of all possible sequences reduces) – Mark Jeronimus Nov 22 '18 at 12:30
  • @MarkJeronimus it is a psuedo random number generator. I don't really get what you mean by "preserves all the entropy". This one uses a seed just like the other one. You can use a SecureRandom if you need a true random seed. – matt Nov 22 '18 at 12:35
  • I thought the seed space was 32 bit, but it's in fact 48 bit, mitigating the problem. – Mark Jeronimus Nov 22 '18 at 13:09
0
public static void main (String[] args) throws java.lang.Exception
    {
        int x = -1;
        long seed = 0;
        int xxx = 100;
        while(x!=0){

            Random s = new Random(seed++);
            x = s.nextInt(xxx);

        }
        System.out.println("seed " + (seed-1) + " gives " + new Random(seed-1).nextInt(xxx));

    }

This will find a seed that the next int will be zero for a given modulus. (Happens to be 18 for this example).

matt
  • 10,892
  • 3
  • 22
  • 34
  • What makes it complicated, because you have to know that if you seed a Random, then a call to nextInt will produce the same result? – matt Nov 22 '18 at 12:36
  • Sorry @matt IMHO it's a complete non-sense to loop among random numbers until you get a 0. If you need a 0, just return a 0 (see my solution) – Benoit Nov 22 '18 at 12:39
  • @Benoit I saw your answer, but you don't know the context of what the op is asking. They might be testing something and specifically need a random number generator set at a specific seed. So yes, your answer is simpler, but it might not actually be solving the problem. – matt Nov 22 '18 at 12:41
  • 1
    Benoit's answer gives perfect reproducibility (the reason for using an explicit seed), enables multiple reproducible sequences that are controlled by the seed after the first zero, and is way more computationally efficient than this. – pjs Nov 22 '18 at 16:36
  • @pjs this gives you the first seed that meets the criteria, it is doing a different thing than what Benoit's answer is doing. – matt Nov 22 '18 at 17:05
  • 1
    @matt Yes, and it does so very inefficiently. It also provides no mechanism for if you want a *different* sequence of values after the initial zero. These issues make Benoit's answer a better choice. – pjs Nov 22 '18 at 17:39
  • @pjs if you want a different series of values re-seed your random number, that doesn't make sense. One way that this is better is because it maintains the statistics of the random number generator. – matt Nov 22 '18 at 18:02
  • 1
    It's very common to want reproducibility for comparison purposes between two or more configurations of a system, while wanting to be able to generate different random number sequences to build up statistical degrees of freedom. See [Wolfram](http://demonstrations.wolfram.com/TheMethodOfCommonRandomNumbersAnExample/) or [Wikipedia](https://en.wikipedia.org/wiki/Variance_reduction) for details. – pjs Nov 22 '18 at 18:14
  • This is completely reproducible. – matt Nov 22 '18 at 19:09
  • But not changeable. You're missing the point that both reproducible **AND** changeable are desirable properties when using PRNGs. Repeating the same seed gives you reproducibility. Being able to change the seed gives degrees of freedom via replication. Your approach does one but not the other. – pjs Nov 22 '18 at 19:49