在循环中重新生成随机数

时间:2014-03-10 16:35:44

标签: random ocaml

我想创建一个基本的遗传算法,以输出一组输入进入模拟器。基本上,它的作用是:

  • 生成输入表
  • 列表项
  • 运行所述输入
  • 略微修改
  • 运行它
  • 查看哪个输入集更好地执行并“分叉”并重复直到问题解决

所以:这是我的代码,用于生成第一组输入:

(* 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;;

但是,我不觉得我的功能是有效的,因为我必须在变异函数中粘贴模式匹配部分,我认为必须有一个更聪明的方法来继续。如果我将“输入”函数定义为全局函数,那么它只被评估一次(假设为“RIGHT”,并且所有出现的“input”将返回“RIGHT”,这实际上没用。

感谢。

1 个答案:

答案 0 :(得分: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匹配。在这种情况下,它是不好的形式,因为它可能导致混淆参数是什么。