type Range = int * int
type Domain = Range array
type Gene = int
type Individual = Gene array
type Population = Individual array
let genPop (domain:Domain) popSize =
let genInd (domain:Domain) : Individual =
let genGene (range:Range) = genNum (fst range) (snd range)
Array.map genGene domain
Array.init popSize (fun _ -> genInd domain)
因此,Population
只不过是Individual
的数组。每个Individual
由一个Gene
数组组成,它们只不过是整数的别名。 genNum
只会为我们生成一个随机整数。
我对genPop
实施不是特别满意。虽然它工作正常并且符合预期,但我想尝试一种使用正向管道运算符|>
的实现,而不是那些子函数。
有关如何继续这方面的任何提示?理想情况下,我会说,人们可以从popSize
开始,这将转变为一个人口,其成员是由基因组成的个体。问题是我们通常需要以相反的方式做事。我们首先需要创建基因,然后创建个体,然后才能创建人口!
你将如何实现这一点(除了我这样做的方式)?也许还有其他方法对我来说不明显?
答案 0 :(得分:5)
将fst
和snd
替换为模式匹配:
let genGene (x, y) = genNum x y
您的整个功能可以变为:
let genPop domain popSize =
Array.init popSize (fun _ -> Array.map (fun (x, y) -> genNum x y) domain)
或:
let genPop domain popSize =
[|for _ in 1..popSize ->
[|for x, y in domain ->
genNum x y|]|]
答案 1 :(得分:1)
该功能可以简化为(使用管道):
let uncurry f = fun(a,b) -> f a b //Helper function
let genPop (domain:Domain) popSize : Population =
(fun _ -> domain)
|> Array.init popSize
|> Array.map ((uncurry genNum) |> Array.map)
答案 2 :(得分:1)
这是我的(第二次)尝试:
let genPop (domain : Domain) popSize : Individual [] =
(fun _ ->
domain
|> Array.map (fun (a, b) -> genNum a b))
|> Array.init popSize
|> Array.map (Array.copy)