Сгенерировать случайные числа в цикле

Я хотел бы создать базовый генетический алгоритм для вывода набора входных данных для ввода в эмулятор. В основном, что он делает:

  • Создание входного листа
  • Элемент списка
  • Запустить указанный вход
  • слегка изменить его
  • Запустить его
  • Посмотрите, какой набор входных данных лучше выполнен и "вилка" его и повторите, пока проблема не будет решена

Итак: вот мой код для генерации первого набора входов:

(* RNG initialization 
 * unit *)
Random.self_init();;


(* Generating a starting input file 
 * array 
 * 500 inputs long *)
let first_input =
let first_array = Array.make 500 "START" in
for i = 1 to 499 do
 let input = 
 match Random.int(5) with
 | 0 -> "A "
 | 1 -> "B "
 | 2 -> "DOWN "
 | 3 -> "LEFT "
 | 4 -> "RIGHT "
 | _ -> "START " in
 first_array.(i) <- input
done;
first_array;;

И вот моя функция "мутации", которая случайным образом изменяет некоторые входы:

(* Mutating input_file 
 * Rate : in percent, must be positive and <= 100 
 * a must be an array of strings *)

let mutation a n=
let mutation_rate = n in
for i = 0 to ((Array.length(a) * mutation_rate / 100) - 1) do
 let input = 
 match Random.int(5) with
 | 0 -> "A "
 | 1 -> "B "
 | 2 -> "DOWN "
 | 3 -> "LEFT "
 | 4 -> "RIGHT "
 | _ -> "START " in
 a.( Random.int(498) + 1) <- input
done;;

Тем не менее, я не чувствую, что моя функция эффективна, потому что мне пришлось вставить часть соответствия шаблону в функцию мутации, и я думаю, что должен быть более разумный способ продолжения. Если я определяю свою функцию "ввода" как глобальную функцию, тогда она оценивается только один раз (пусть говорят как "ПРАВО", и все вхождения "ввода" вернут "ПРАВО", что не очень полезно.

Благодарю.

1 ответ

Нет ничего плохого в том, чтобы поместить это в свою собственную функцию. То, что вам не хватает, является аргументом, чтобы заставить функцию работать с побочным эффектом Random.int. Поскольку вы не используете этот аргумент, часто/всегда используется случай, когда люди используют unit.

let random_input () = match Random.int 5 with
 | 0 -> "A "
 | 1 -> "B "
 | 2 -> "DOWN "
 | 3 -> "LEFT "
 | 4 -> "RIGHT "
 | _ -> "START "

То, что вы здесь делаете, это шаблон, сопоставляющий аргумент, и поскольку существует только один конструктор, это сопоставление является исчерпывающим. Но технически вы можете заменить () выше на _. Это будет соответствовать тому, что делает функцию полиморфной против этого аргумента, 'a → string. В этом случае это плохая форма, так как это может привести к путанице в отношении того, для чего предназначен параметр.

licensed under cc by-sa 3.0 with attribution.