我在 CodeReview 上发布了这个问题,但我意识到这与其说是 Haskell 问题,不如说是算法问题。
Haskell 代码可以在我的 github 存储库中找到,但我认为代码不如一般概念重要。
基本上,该程序会计算出卡拉哈游戏(瑞典变体)中的最佳第一组动作。只考虑第一个“回合”,因此我们假设您开始,并且从对手开始移动的点开始的任何事情都不会被计算。
卡拉哈板 http://www.graf-web.at/mwm/kalaha.jpg
棋盘一开始是空的商店和每个罐子里等量的弹珠。
你开始你的回合,选择你身边的一个非空罐子,从那个罐子里捡起所有的弹珠,然后在经过一个罐子时通过丢下一颗弹珠在棋盘上移动。如果您的最后一块大理石落在商店中,您将获得另一个回合。如果你降落在一个非空的、非商店的罐子里,你拿起罐子里的所有东西并继续。最后,如果你落入一个空底池,转牌就会传给对手。
到目前为止,我已经通过选择所有可能的路径然后根据商店中弹珠的数量对它们进行排序来解决这个问题。一条路径意味着从你的一个罐子开始,做所有必要的拾取和移动,看看你是落在商店还是空罐子里。如果你登陆商店,你可以继续,现在你身边的非空罐子一样多的新分店。
问题在于,如果你从花盆里的五颗弹珠开始,那已经是相当多的路径了。跳转到 6 并且 ghci 内存不足。
我无法弄清楚如何降低成本的原因是因为我认为在计算过程中每条路径都是必要的。虽然我最多只需要生成的数千个(或数百万个)路径中的三个路径(最好的路径),但其余的需要运行以查看它们是否实际上比以前的路径更好。
如果一个更长(通常更好),那么这很好但成本很高。如果它比以前的任何路径都短,那么程序仍然必须计算该路径才能找到它。
有什么办法可以解决这个问题,还是根据定义计算所有必要的路径?