Haskell =地图(dads!!)DADDINDEX main=打印新人口
如果你想为每一个现有的有机体构建一个新的有机体,你应该在现有的有机体上循环。因此,在这个样板中删去了你在问题中口头删去的内容:Haskell =地图(dads!!)DADDINDEX main=打印新人口,haskell,Haskell,如果你想为每一个现有的有机体构建一个新的有机体,你应该在现有的有机体上循环。因此,在这个样板中删去了你在问题中口头删去的内容: import Control.Applicative import Control.Monad.Random import Data.Traversable data Organism crossover :: Organism -> Organism -> Organism crossover = undefined Control.Monad.Ra
import Control.Applicative
import Control.Monad.Random
import Data.Traversable
data Organism
crossover :: Organism -> Organism -> Organism
crossover = undefined
Control.Monad.Random
模块由提供。然后您可以编写这个,它编译得很好,并且具有正确的语义:
breed :: MonadRandom m => [Organism] -> m [Organism]
breed old = for old $ \_ -> liftA2 crossover (uniform old) (uniform old)
很好,很简洁,我觉得甚至很可读 如果你想为每一个现存的有机体构建一个新的有机体,你应该在现存的有机体上循环。因此,在这个样板中删去了你在问题中口头删去的内容:
import Control.Applicative
import Control.Monad.Random
import Data.Traversable
data Organism
crossover :: Organism -> Organism -> Organism
crossover = undefined
Control.Monad.Random
模块由提供。然后您可以编写这个,它编译得很好,并且具有正确的语义:
breed :: MonadRandom m => [Organism] -> m [Organism]
breed old = for old $ \_ -> liftA2 crossover (uniform old) (uniform old)
很好,很简洁,我觉得甚至很可读 这个解决方案怎么样:
crossoverPop::[String]->[String]->[String]crossoverPop-newPop | length-newPop
不是一个好的解决方案。重复检查长度
是很尴尬的(如果您使用的是链表,那么实际上效率很低)。没有理由显式地使用部分构建的newPop
,只需在运行时将其作为结果进行构建即可。是的,这也可以通过递归而不是标准的循环构造来实现,但是为什么还要麻烦呢?(另外,select
作为一个纯函数是不可能的,这必须是一个单子动作——最好是在一个专用的随机单子中,但IO也可以。)或者按照Carl的压缩建议,这可能更好。这个解决方案呢:CrossOvertop::[String]->[String]->[String]->[String]CrossOvertop-pop-newPop | length-newPop
不是一个好的解决方案。重复检查长度
是很尴尬的(如果您使用的是链表,那么实际上效率很低)。没有理由显式地使用部分构建的newPop
,只需在运行时将其作为结果进行构建即可。是的,这也可以通过递归而不是标准的循环构造来实现,但是为什么还要麻烦呢?(另外,select
作为一个纯函数是不可能的,这必须是一个单子动作——最好是在一个专用的随机单子中,但IO也可以。)或者按照卡尔的压缩建议,这可能更好。正如许多人在回答中提到的,典型的方法是使用带交叉的zip
唯一不清楚的是,当使用selectFrom
函数时,您使用的是哪个选择模式。例如:selectFrom
可以在不同的迭代中重复妈妈/爸爸吗?@ismor-是的,所选元素不会从原始列表中删除(我不太担心最终算法是否完美或最优,我只是发现实现GA是一个很好的“你好世界”当学习一门涉及多种语言结构的新语言时,你最终需要对该语言进行一些深入研究)。正如许多人在回答中提到的,典型的方法是使用带交叉的zip
唯一不清楚的是,当使用selectFrom
函数时,您使用的是哪个选择模式。例如:selectFrom
可以在不同的迭代中重复妈妈/爸爸吗?@ismor-是的,所选元素不会从原始列表中删除(我不太担心最终算法是否完美或最优,我只是发现实现GA是一个很好的“你好世界”当学习一门涉及多种语言结构的新语言时,你最终需要对该语言进行一点深入研究)。有一些很好的库可以使采样相对轻松。请参阅我的答案,以获得一个特别轻量级的示例(至少,在程序员资源中是轻量级的;因为采样不太可能成为此算法中的热点,这对我来说是一件需要优化的好事情)。请参阅我的答案,以获得一个特别轻量级的示例(至少,在程序员资源中是轻量级的;因为采样不太可能成为此算法中的热点,所以对我来说,这是一件需要优化的好事情)。
do
let n = length inputPopulation
[mums,dads] <- replicateM 2 . replicateM n $ selectFrom inputPopulation
return $ zipWith crossover mums dads
import Data.Monoid ((<>))
{- you should use System.Random module in order to get random indices.
The function should look similar to this but I couldn't test it:
getRandomIndex :: RandomGen g => g -> [a] -> [Int]
getRandomIndex g l = take hi $ randomRs (0, hi) g
where hi = length l
In the main function use getStdGen to get a g to feed getRandomIndex
-}
dads = ["dad0","dad1", "dad2", "dad3", "dad4", "dad5"]
mums = ["mum0","mum1", "mum2", "mum3", "mum4", "mum5"]
dadIndex :: [Int]
dadIndex = [1,4,2,3,2,0] -- let's imagine that this is the result of getRandomIndex g dads
mumIndex :: [Int]
mumIndex = [0,2,2,3,5,2] -- let's imagine that this is the result of getRandomIndex g mums
-- crossover is simply string concatenation
crossover :: String -> String -> String
crossover a b = a <> b
newPopulation :: [String]
newPopulation = zipWith crossover randomMums randomDads
where randomMums = map (mums !!) mumIndex --
randomDads = map (dads !!) dadIndex
main = print newPopulation
import Control.Applicative
import Control.Monad.Random
import Data.Traversable
data Organism
crossover :: Organism -> Organism -> Organism
crossover = undefined
breed :: MonadRandom m => [Organism] -> m [Organism]
breed old = for old $ \_ -> liftA2 crossover (uniform old) (uniform old)