В этой главе сначала объясняется несколько способов генерирования случайных чисел Java, а затем демонстрирует их с помощью примеров.
Обзор:
Вы скажете здесь, какова сложность генерации случайных чисел? Разве это не только для того, чтобы использовать инкапсулированные Java, случайные? Конечно, в целом это нормально, и алгоритмы, которые должны быть объяснены в этой статье, также основаны на этой случайной библиотечной функции.
Эта статья в основном фокусируется на поведении отбора проб, а сама выборка имеет неявное правило, которое не должно иметь дублирующих данных. Хорошо, с этими инструкциями. Сначала вы можете попробовать использовать некоторые из ваших собственных идей для генерации случайных чисел без повторного генерации.
Попытки алгоритма:
Появляются некоторые хорошие алгоритмы, часто сопровождаемые некоторыми не очень хорошими алгоритмами. Однако для алгоритмов, которые не очень эффективны, они, как правило, имеют одну общую функцию, которая легко понять и реализовать. Ниже приводится краткое объяснение через пошаговый подход.
Первая попытка: наивный случайный алгоритм
Этот алгоритм легко понять, он случайный! Каждый раз, когда случайное число генерируется и добавляется в набор.
Private void SimpleRandom (int start, int end, int count) {System.out.println ("Естественный случайный алгоритм:"); StringBuffer Buffer = new StringBuffer (); for (int i = 0; i <count; i ++) {int random = numberutils.randominteger (start, end); buffer.append (i == 0? ("[" + random): ("," + случайный)); } buffer.append ("]"); System.out.println (Buffer); } Вторая попытка: проверьте на экзистенциальный случайный алгоритм
Мы знаем, что есть проблема с вышеуказанным методом, то есть есть дубликаты данных. Итак, мы подумали о том, чтобы проверить, существует ли число уже при генерации случайного числа, и, если оно существует, оно будет регенерировано.
private void checkrandom (int start, int end, int count) {System.out.println («Проверьте экзистенциальный случайный алгоритм:»); StringBuffer Buffer = new StringBuffer (); Список <Integer> save = new ArrayList <> (); for (int i = 0; i <count; i ++) {int random = numberutils.randominteger (start, end); if (выходит (save, random)) {i--; продолжать; } save.add (случайный); buffer.append (i == 0? ("[" + random): ("," + случайный)); } buffer.append ("]"); System.out.println (Buffer); } Третья попытка: удаление элемента Случайный алгоритм
Приведенный выше алгоритм решил проблему дублирования данных. Тем не менее, одна очень плохая проблема заключается в том, что нам может потребоваться много времени, чтобы генерировать образцы случайных чисел (это зависит от лица ...).
Однако здесь у нас есть новые идеи. То есть случайным образом использовать число в наборе и удалить его, когда он будет выбран. Тогда вы не будете случайным образом достичь этого числа снова, когда оно случайно? Это очень хорошо решает проблему повторения случайных чисел. Код заключается в следующем:
Private void Removerandom (int start, int end, int count) {System.out.println ("Удаление элемента Случайный алгоритм:"); StringBuffer Buffer = new StringBuffer (); Список <integer> numbers = initlist (start, end); for (int i = 0; i <count; i ++) {int random = numberutils.randominteger (count - i); buffer.append (i == 0? ("[" + numbers.get (random)): ("," + number.get (random))); numbers.remove (случайный); } buffer.append ("]"); System.out.println (Buffer); } Четвертая попытка: государство передавать случайный алгоритм
Во многих моих предыдущих блогах некоторые являются государственными процессами передачи в алгоритмах. Государственный трансфер также является одним из моих любимых алгоритмов. Рисунок-1 Ниже отмечает диапазон значений случайных чисел, а число оранжевого в последовательности-случайная последовательность в результате. В нижней последовательности есть некоторые пунктирные стрелки, представляющие переход состояния.
Рисунок-1 Алгоритм генерации случайных чисел на основе перехода на состояние
Код реализации:
Private void Statestrandom (int start, int end, int count) {System.out.println ("Случайный алгоритм передачи состояния:"); StringBuffer Buffer = new StringBuffer (); int [] status = new int [end + 1]; for (int i = 0; i <count; i ++) {int random = numberutils.randominteger (start, end); System.err.println (случайный); if (status [random] == 0) {buffer.append (i == 0? ("[" + случайный): ("," + случайный)); Статус [случайный] = случайный == end? начало: (случайный + 1); // невозможно иметь число до начала} else {// передача состояния int index = random; do {index = status [index]; } while (status [index]! = 0); buffer.append (i == 0? ("[" + index): ("," + index)); Статус [index] = index == end? начало: (индекс + 1); // невозможно иметь число перед запуском}} buffer.append ("]"); System.out.println (Buffer); } Пятая попытка: рекурсивный случайный алгоритм Floyd
Алгоритм Флойда в конечном итоге является процессом передачи состояния. Алгоритм потребуется список или массив для хранения определенного случайного числа. Как следует из названия, я буду использовать рекурсивные решения здесь. В процессе рекурсии мы переносим состояние случайного числа I-th в случайное число I-1. Код заключается в следующем:
Частный список <Integer> simplefloyd (list <Integer> list, int count, int start, int end) {if (count == 0) {return List; } list = simplefloyd (list, count - 1, start, end - 1); int random = numberutils.randominteger (начало, конец); if (list.contains (random)) {list.add (end); } else {list.add (random); } return List; } Шестая попытка: итерация над случайным алгоритмом Флойда
Идея похожа на рекурсивный случайный алгоритм Floyd выше, но здесь мы добавляем переменную для оптимизации. Больше нет необходимости повторять. Код заключается в следующем:
Частный список <integer> iteatersfloyd (int start, int end, int count) {System.out.println («Итеративный случайный алгоритм Floyd:»); List <Integer> list = new ArrayList <> (); for (int i = end - count+1; i <end; i ++) {int random = numberutils.randominteger (start, i); if (list.contains (random)) {list.add (i); } else {list.add (random); }} return List; } Результаты теста:
Рисунок-2 Результаты теста алгоритма генерации случайных чисел
В приведенных выше результатах теста мы можем четко видеть, что наивный случайный алгоритм не только имеет дублирующиеся данные, но и самый трудоемкий. Поэтому избегайте использования этого алгоритма при генерации выбранных случайных чисел. Среди последних алгоритмов государство передает случайный алгоритм, а случайный алгоритм итеративный случайный алгоритм Floyd - второе. Это может быть сделано в соответствии с личными предпочтениями.