Languages
[Edit]
EN

Java - own random number generator (custom implementation)

14 points
Created by:
JustMike
26150

1. Introduction

In java we can implement custom random number generator by using LCG (Linear congruential generator) algorithm. LCG is one of the oldest and best-known pseudorandom number generator algorithm. We can adjust this implementation to work on int or long.

Linear congruential generator is defined by recurrence relation:

Where:

  • Xn+1 - new seed
  • a - MULTIPLIER_A
  • Xn - current seed field
  • c - INCREMENT_C
  • m - MODULUS

In our below implementation above variables were used.

2. Implementation in java

Note:

Every time randomInt() method is called, we assign new value to seed.

public class RandomUtil {

    private final static int MULTIPLIER_A = 1103515245;
    private final static int INCREMENT_C = 12345;
    private final static int MODULUS = 2147483647; // max int

    private static int seed = 3819201;

    public static int randomInt() {
        seed = (seed * MULTIPLIER_A + INCREMENT_C) % MODULUS;
        return seed;
    }

    public static int randomPositiveInt() {
        int tmp = randomInt();
        if (tmp < 0) {
            seed = tmp * -1;
        }
        return seed;
    }

    public static void main(String[] args) {
        System.out.println(randomPositiveInt()); // 1801118106
        System.out.println(randomPositiveInt()); // 41211189
        System.out.println(randomPositiveInt()); // 11738570

        for (int i = 0; i < 7; i++) {
            System.out.println(randomPositiveInt());
        }
    }
}

Output:

1801118106
41211189
11738570
865299259
887958952
992620351
1793753076
477297891
1620379360
1194566247

Explanation

Below 2 fields:

int MULTIPLIER_A = 1103515245;
int INCREMENT_C = 12345;

are used by runtime libraries of various compilers:

  • glibc (used by GCC)
  • ANSI C: Watcom, Digital Mars, CodeWarrior, IBM VisualAge C/C++
  • C90, C99, C11: Suggestion in the ISO/IEC 9899, C18

3. Probability distribution test

import java.util.Arrays;

public class RandomUtilProbabilityTest {

    public static void main(String[] args) {
        int[] probabilityDistribution = new int[10];

        for (int i = 0; i < 30_000; i++) {
            int next = RandomUtil.randomPositiveInt() % 10;
            probabilityDistribution[next]++;
        }

        // [2976, 3019, 2973, 3132, 3000, 3006, 3021, 2959, 3030, 2884]
        System.out.println(Arrays.toString(probabilityDistribution));

        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;

        for (int i = 0; i < probabilityDistribution.length; i++) {
            int next =  probabilityDistribution[i];
            min = Math.min(min, next);
            max = Math.max(max, next);
        }

        System.out.println(" min: " + min); //  min: 2884
        System.out.println(" max: " + max); //  max: 3132
        System.out.println("diff: " + (max - min)); // diff: 248
    }
}

Output:

[2976, 3019, 2973, 3132, 3000, 3006, 3021, 2959, 3030, 2884]
 min: 2884
 max: 3132
diff: 248

4. JDK Random class - probability distribution test

import java.util.Arrays;
import java.util.Random;

public class JdkRandomProbabilityTest {

    private static final Random random = new Random(3819201);

    public static int nextInt(int min, int max) {
        return random.nextInt((max - min) + 1) + min;
    }

    public static void main(String[] args) {
        int[] probabilityDistribution = new int[10];

        for (int i = 0; i < 30_000; i++) {
            int next = nextInt(0, Integer.MAX_VALUE - 1) % 10;
            probabilityDistribution[next]++;
        }

        // [2963, 2885, 3049, 3041, 3002, 3089, 2967, 3020, 3019, 2965]
        System.out.println(Arrays.toString(probabilityDistribution));

        int min = Integer.MAX_VALUE;
        int max = Integer.MIN_VALUE;

        for (int i = 0; i < probabilityDistribution.length; i++) {
            int next =  probabilityDistribution[i];
            min = Math.min(min, next);
            max = Math.max(max, next);
        }

        System.out.println(" min: " + min); //  min: 2903
        System.out.println(" max: " + max); //  max: 3093
        System.out.println("diff: " + (max - min)); // diff: 190
    }
}

Output:

[2976, 2984, 3091, 3093, 3037, 2969, 3030, 2903, 2905, 3012]
 min: 2903
 max: 3093
diff: 190

References

Java - random numbers

Native Advertising
50 000 ad impressions - 449$
🚀
Get your tech brand or product in front of software developers.
For more information contact us:
Red dot
Dirask - friendly IT community for everyone.

❤️💻 🙂

Join