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 do开发者_Go百科main)
So, a Population
is nothing more than an array of Individual
s. Each Individual
consists of an array of Gene
s, that are nothing more than an alias for integers. genNum
will just generate a random integer for us.
I am not particularly happy with my genPop
implementation. Although it works fine and as expected, I'd like to try out an implementation that'd made use of the forward pipe operator |>
, instead of those sub functions.
Any tips on how to proceed on this? Ideally I'd say that one could start of with popSize
, that would be transformed into a Population, that'd have as its members Individuals that'd consist of Genes. The problem is that we generally need to do things the other way around. We first need to create the Genes, and then the Individuals, and only then we can have a Population!
How would you implement this (other than the way I did it)? Maybe there are other ways that are not currently apparent to me?
Replace fst
and snd
with pattern matching:
let genGene (x, y) = genNum x y
Your whole function can become:
let genPop domain popSize =
Array.init popSize (fun _ -> Array.map (fun (x, y) -> genNum x y) domain)
or:
let genPop domain popSize =
[|for _ in 1..popSize ->
[|for x, y in domain ->
genNum x y|]|]
The function can be reduced to (using pipe):
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)
Here is my (second) try:
let genPop (domain : Domain) popSize : Individual [] =
(fun _ ->
domain
|> Array.map (fun (a, b) -> genNum a b))
|> Array.init popSize
|> Array.map (Array.copy)
精彩评论