Генерация целых чисел с шансом

я задался вопросом: как сделать рандомайзер целых чисел, но с шансом. То есть есть диапазон от 0 до 100 и цифры целые. Но хотелось бы сделать так, что бы шанс выпадения какого-то числа был 20%


Ответы (3 шт):

Автор решения: Сергей

На псевдокоде, так как не пишу на java (тут 21% по факту, если надо ровно 20%, то при первой генерации надо диапазон взять от 0 до 0,95 - даст 19% и 1% даст вторая генерация):

ГЕНЕРАЦИЯ (случайного целого Числа1 в диапазоне от 0 до 5):
ЕСЛИ Число1 = 0 
   Результат=Желаемое_Число
ИНАЧЕ ГЕНЕРАЦИЯ (случайного целого Числа2 в диапазоне от 0 до 100) 
   Результат = Число2
→ Ссылка
Автор решения: Agzam

Вообразим массив (Отсортированный), где: number - числа, а chance - их количество в массиве

import java.util.Random;
import java.util.stream.IntStream;

public class Test {

    public static void main(String[] a) {

        int[] number = new int[] {0, 1,  23, 456, 7890, 12345}; // Числа
        int[] chance = new int[] {0, 50, 1, 1,    1,    10   }; // Количество

        int count = IntStream.of(chance).sum(); // Считаем количество элементов воображаемого массива

        // Вывод вероятностей:
        for (int i = 0; i < chance.length; i++) {
            System.out.println("Вероятность числа \"" + number[i] + "\":  \t" + (chance[i]*100d/count) + "%");
        }
        
        // Генерация случайного числа
        Random random = new Random();
        for (int randomNumsCount = 0; randomNumsCount < 10; randomNumsCount++) {
            
            int index = random.nextInt(count); // Выбираем случайный индекс из воображаемого массива

            for (int i = 0; i < chance.length; i++) { // Ищем элемент, которому принадлежит этот индекс
                index -= chance[i];
                if(index < 0) {
                    System.out.println("Случайное число: " + number[i]);
                    break;
                }
            }

        }
    }
}

Примеры массивов:

Число 10 - 50%
Число 100 - 50%
int[] number = new int[] {10, 100};
int[] chance = new int[] {50, 50};  // или new int[] {1, 1} или new int[] {25, 25} 
Воображаемый массив: {10, 25}

Число 15 - 20%
Число 20 - 30%
Число 25 - 50%
int[] number = new int[] {15, 20, 25};
int[] chance = new int[] {2,  3,  5};  // или new int[] {20, 30, 50} ...
Воображаемый массив: {15,15, 20,20,20, 25,25,25,25,25}

→ Ссылка
Автор решения: Qwertiy

Генерация каждого числа работает за логарифм от их количества: tio.run

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

class BinarySearch1 {
  public static int generate(Random random, int[] numbers, int[] chances) {
    int x = random.nextInt(chances[chances.length-1]);
    int i = Arrays.binarySearch(chances, x);
    if (i < 0) i = -1 - i;
    return numbers[i];
  }
  
  public static void main(String[] args) {
    Random random = new Random();
    int[] numbers = new int[] {0,  10, 20, 300, 40, 50   };
    int[] chances = new int[] {20, 10, 10, 1,   10, 10, 0};

    for (int q=1; q<chances.length; ++q) {
      chances[q] += chances[q-1];
    }

    for (int q=0; q<100; ++q) {
      System.out.println(generate(random, numbers, chances));
    }
  }
}

Вероятности выпадения:

  • p(0) = 20/(20+10+10+1+10+10) = 20/51
  • p(10) = p(20) = p(40) = p(50) = 10/51
  • p(300) = 1/51

Нельзя использовать нулевые шансы.

→ Ссылка