繁体   English   中英

理解Haskell中的基本递归

[英]Understanding basic recursion in Haskell

我正在编写一个遗传算法作为我的人工智能课程的项目。 我熟悉GA背后的概念,但我对Haskell的经验是有限的。 在程序中只剩下一件事要做,那就是创建一个循环我其他函数的函数。 我将介绍我的功能并更详细地解释问题:

这是第二代的功能。 我得到了父母,交配它们并改变基因组,然后将新的基因组传递到一个列表中:

generation1 = initialPopulation
generation2 = [(mutate (mate (fTTS generation1) (sTTS generation1))) | x <- [1..100]]

这非常有效。 我可以创建新一代并重复:

generation3 = [(mutate (mate (fTTS generation2) (sTTS generation2))) | x <- [1..100]]

所以对于每一代新人来说,我离目标基因组更近一步(在我的情况下,这是一个字符串)。 我希望生成新一代,直到达到目标String。 我认为一个基本的递归会解决这个问题,如:

g 0 = initialPopulation
g n = [(mutate (mate (fTTS (g (n - 1))) (sTTS (g (n - 1))))) | x <- [1..100]]

这适用于我的笔记本电脑,直到g(3),但计算需要很长时间。 我的问题是我不明白为什么。 我认为Haskell递归的工作方式如下:

-- g 0 = [(mutate (mate (fTTS initialPopulation) (sTTS initialPopulation))) | x <- [1..100]] = ["N4kiT","Tu1RT","Tu1R<"]
-- g 1 = [(mutate (mate (fTTS (g 0)) (sTTS (g 0)))) | x <- [1..100]]
-- g 2 = [(mutate (mate (fTTS (g 1)) (sTTS (g 1)))) | x <- [1..100]]
-- g 3 = [(mutate (mate (fTTS (g 2)) (sTTS (g 2)))) | x <- [1..100]]

在我的头脑中应该与上面的generation3功能相同。 如果有更多了解Haskell的人可以解释为什么我能够毫无困难地运行“generation15”函数但是不能超过“g(3)” - 函数之前我必须强制退出安慰。

谢谢!

问题是gn没有被记忆 - 它将在你的列表理解中重新计算2 * 1000

g 0 = initialPopulation
g n = 
    let prev = g (n-1)
    in [(mutate (mate (fTTS prev) (sTTS prev))) | x <- [1..100]]

应该改进的东西(我想要得到严格的值也是一个很好的问题 - 但这可能是另一个问题)


但我不会那样用它 - 而是写一个:

nextGen prev = [(mutate (mate (fTTS prev) (sTTS prev))) | x <- [1..100]]

功能,然后你可以做类似的事情:

find gen = if goodEnough gen then gen else find (nextGen gen)

带着希望

best = find initialPopulation

(请注意,也许你应该在很多代之后都有退出策略 - 所以你可能想要包括一代计数器或类似的东西)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM