Java Math. random repeats the values. Galton Board

This program demonstrates the work of the Galton board. This board has a N slot on the bottom and one hole on the top. The top is served with balls that randomly fall into one of the N slots. The board is used to explore the theory of probability.

See here https://ru.wikipedia.org/wiki/Доска_Гальтона

During testing, it was found that the methods Math.random(), Random.nextInt(), Random.nextBoolean() , etc., return the same results.


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


public class Main {

    public static Scanner scan = new Scanner(System.in);

    // Генератор случайных чисел
    public static Random rand = new Random();

    public static void main(String[] args) {
        // слоты
        int[] slots;

        // количество слотов
        int n;

        // количество шариков
        int balls;

        // показывает на какую сторону катиться шарик false - налево, true - направо
        boolean side;

        // индекс слота в которую должен попасть текущий шарик
        int k;

        // середина массива
        int middle;

        // количество повторения эксперимента
        int times;

        // показывает наибольшое количество шариков в одном слоте
        int max;

        // initialization
        System.out.print("Enter number of repetitions: ");
        times = scan.nextInt();

        System.out.print("Enter number of balls: ");
        balls = scan.nextInt();

        System.out.print("Enter number of slots: ");
        n = scan.nextInt();
        slots = new int[n];
        middle = n / 2;

        while (times > 0) {
            while (balls > 0) {
                k = 0;
                for (int i = 0; i < n - 1; i++) {
                    // "случайный" true или false, от которого зависит значения k
                    side = rand.nextBoolean();
                    k = (side) ? k + 1 : k - 1;
                }

                // так как 2 катание шарика соответствуют одному изменению индекса
                // делим на 2, слагаем алгебраически
                k = middle + k / 2;

                // добавляем шарик в слоте, уменьшаем количество оставшейся шариков
                slots[k]++;
                balls--;
            }

            // находим максимум, рисуем
            max = Max(slots);
            while(max > 0) {
                for(int slot : slots) {
                    if (slot >= max) {
                        System.out.print(" O ");
                    } else {
                        System.out.print("   ");
                    }
                }
                System.out.println();
                max--;
            }

            System.out.println(Arrays.toString(slots) + "\n");
            times--;
        }
    }

    public static int Max(int[] array) {
        int max = 0;
        for (int i = 1; i < array.length; i++) {
            if(array[max] < array[i]) {
                max = i;
            }
        }
        return array[max];
    }
}

Despite the fact that everyone each time the program is run, different random values are obtained, and during program execution, when the experiment is repeated in a loop, the methods return the same values with the same sequence as on the first attempt.

testing

Here I repeat the experiment 2 times, but the 2nd experiment is no different from the 1st.
Why is this so, what is the reason for this, and how do I always get unique values?

P.S. Tried

    public static Random rand = new Random(System.currentTimeMillis());

And in the loop attempts

    while (times > 0) {
        //code...
        rand = new Random(System.currentTimeMillis());
   }
   // code...

Or

    while (times > 0) {
        //code...
        rand.setSeed(System.currentTimeMillis());
   }
   // code...

It didn't help

Author: Հայկ Ավետիսյան, 2020-03-05

1 answers

You need to initialize the random number generator.

 Random rand = new Random(System.currentTimeMillis());

By default, initialization is the same number.

But the main problem is different and you would easily see it if you ran the program step by step.

See:

// добавляем шарик в слоте, уменьшаем количество оставшейся шариков
                slots[k]++;
                balls--;

What will balls be equal to after the first pass through the loop? It is clear that zero and the second pass will simply print out the contents of slots.

Since the number of balls at the beginning of each pass must be equal to entered from the keyboard, and the slots must be empty, then they must be initialized before starting the process of simulating the fall of the ball.

Here is the corrected code.

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


public class Main {

    public static Scanner scan = new Scanner(System.in);

    // Генератор случайных чисел
    public static Random rand = new Random(System.currentTimeMillis());

    public static void main(String[] args) {
        // слоты
        int[] slots;

        // количество слотов
        int n;

        // количество шариков
        int balls;

        // показывает на какую сторону катиться шарик false - налево, true - направо
        boolean side;

        // индекс слота в которую должен попасть текущий шарик
        int k;

        // середина массива
        int middle;

        // количество повторения эксперимента
        int times;

        // показывает наибольшое количество шариков в одном слоте
        int max;

        // initialization
        System.out.print("Enter number of repetitions: ");
        times = scan.nextInt();

        System.out.print("Enter number of balls: ");
        balls = scan.nextInt();
        int balls_current;

        System.out.print("Enter number of slots: ");
        n = scan.nextInt();

        middle = n / 2;


        while (times > 0) {
            balls_current=balls;
            slots = new int[n];
            while (balls_current > 0) {
                k = 0;
                for (int i = 0; i < n - 1; i++) {
                    // "случайный" true или false, от которого зависит значения k
                    side = rand.nextBoolean();
                    k = (side) ? k + 1 : k - 1;
                }

                // так как 2 катание шарика соответствуют одному изменению индекса
                // делим на 2, слагаем алгебраически
                k = middle + k / 2;

                // добавляем шарик в слоте, уменьшаем количество оставшейся шариков
                slots[k]++;
                balls_current--;
            }

            // находим максимум, рисуем
            max = Max(slots);
            while(max > 0) {
                for(int slot : slots) {
                    if (slot >= max) {
                        System.out.print(" O ");
                    } else {
                        System.out.print("   ");
                    }
                }
                System.out.println();
                max--;
            }

            System.out.println(Arrays.toString(slots) + "\n");
            times--;
        }
    }

    public static int Max(int[] array) {
        int max = 0;
        for (int i = 1; i < array.length; i++) {
            if(array[max] < array[i]) {
                max = i;
            }
        }
        return array[max];
    }
}
 2
Author: becouse, 2020-03-06 08:51:58