Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 陷入极大极小算法-下一步是什么?哈斯克尔_Haskell_Tree_Artificial Intelligence_Minimax - Fatal编程技术网

Haskell 陷入极大极小算法-下一步是什么?哈斯克尔

Haskell 陷入极大极小算法-下一步是什么?哈斯克尔,haskell,tree,artificial-intelligence,minimax,Haskell,Tree,Artificial Intelligence,Minimax,我正在为一个2人棋盘游戏编写一个基本的极大极小算法。到目前为止,我有一个函数,它对一块板求值并返回一个分数。我有一个函数,返回所有可能的移动(以及这些移动的移动)等玫瑰树。。。达到一定的深度。我可以找到那棵树的叶子,然后根据我的启发给它们一个值,我的问题是在那之后我该怎么做 我是否以某种方式编辑叶子的父节点,并根据子节点的值为父节点分配一个新值,然后继续操作,直到到达根节点 我是不是要从叶子上创建一棵新树,在到达根节点之前拾取最小/最大值?如果是这样的话,这棵新树是如何记住到达叶子所需的所有动作

我正在为一个2人棋盘游戏编写一个基本的极大极小算法。到目前为止,我有一个函数,它对一块板求值并返回一个分数。我有一个函数,返回所有可能的移动(以及这些移动的移动)等玫瑰树。。。达到一定的深度。我可以找到那棵树的叶子,然后根据我的启发给它们一个值,我的问题是在那之后我该怎么做

我是否以某种方式编辑叶子的父节点,并根据子节点的值为父节点分配一个新值,然后继续操作,直到到达根节点

我是不是要从叶子上创建一棵新树,在到达根节点之前拾取最小/最大值?如果是这样的话,这棵新树是如何记住到达叶子所需的所有动作的

我只想使用标准库的导入(我不想下载软件包)。任何建议都很好,我已经为此挣扎了几天。 谢谢


我试着从我的代码中挑选一些部分来举例,但是有很多函数纠结在一起。如果有帮助的话,以下是主要函数的类型签名及其功能说明:

此函数获取一个
Int
(表示树的
Depth
)、一个
游戏
(棋盘的当前状态)、即时可能移动的列表,并返回一个包含每个可能移动(以及移动到这些移动)的玫瑰树以及与该移动相关的分数。如果玩家是黑暗的,它的分数是正的,如果玩家是黑暗的,它的分数是负的——玫瑰树中的每一个深度都是玩家的下一个移动

roseTreeAtDepthN :: Int-> Game -> [Position] -> [Rose (Position,score)]
例如:
treeatdepthn2初始游戏[(2,3)、(3,2)、(4,5)、(5,4)]
返回:

[Rose ((2,3),4) [Rose ((2,2),-3) [],Rose ((2,4),-3) [],Rose ((4,2),-3) []],
 Rose ((3,2),4) [Rose ((2,2),-3) [],Rose ((2,4),-3) [],Rose ((4,2),-3) []],
 Rose ((4,5),4) [Rose ((3,5),-3) [],Rose ((5,3),-3) [],Rose ((5,5),-3) []],
 Rose ((5,4),4) [Rose ((3,5),-3) [],Rose ((5,3),-3) [],Rose ((5,5),-3) []]]
我有另一个功能,可以让我得到一棵树的叶子。我在
treeAtDepthN
中为每个移动使用评估游戏状态的函数,但我意识到这可能不是必需的,应该只在树的叶子上使用。我不确定这是否有帮助


稍后编辑:

不确定下一步我的minimax算法要做什么。我有一个函数,可以将所有可能的移动打印到某个深度,我有一个启发式算法来计算每个移动,我只是不知道如何将它转换成一个函数,返回最佳移动。我只想使用Haskell库中给出的函数(不想下载任何包)

我想如果我画一幅图来解释我的功能,我可能会更容易理解。我有两种解决方案,我可以想到,这两种方案如图所示,我不确定我应该采用哪种方法,如果有的话:

我想我需要一个函数,将图片顶部的[Rose a]转换为图片底部的Rose a


谢谢。

好吧,你实际上不需要用更新的分数建立一棵树。您只需计算最佳移动(即最大化最小最坏情况分数的移动)

因此,从一些预备工作开始:

import Data.List
import Data.Ord

type Position = (Int,Int)
type Score = Int
data Rose a = Rose a [Rose a]
我们可以编写一个函数,获取移动树列表并选择移动(aka
Position
),从而获得最低分数的最大值:

maximin :: [Rose (Position, Score)] -> (Position, Score)
maximin = maximumBy (comparing snd) . map minscore
助手
minscore
计算移动树的最低分数,假设最佳对位

minscore :: Rose (Position, Score) -> (Position, Score)
如果我们在一片叶子上,我们对分数的最佳估计是对当前板的直接启发式评估,因此我们只返回该位置和分数:

minscore (Rose x []) = x
否则,我们使用与
maximin
相反的
minimax
,即
minimax>计算最佳对策得分:

minscore (Rose (pos,_) moves)
  = let (_,score) = minimax moves in (pos,score)
请注意,
minscore
始终从树的根返回下一个移动(
pos
),但分数将从根(对于叶子)或通过进一步的递归计算(对于节点)获取

maximin
及其镜像
minimax
的完整定义如下:

maximin :: [Rose (Position, Score)] -> (Position, Score)
maximin = maximumBy (comparing snd) . map minscore
  where minscore (Rose x []) = x
        minscore (Rose (pos,_) moves)
          = let (_,score) = minimax moves in (pos,score)

minimax :: [Rose (Position, Score)] -> (Position, Score)
minimax = minimumBy (comparing snd) . map maxscore
  where maxscore (Rose x []) = x
        maxscore (Rose (pos,_) moves)
          = let (_,score) = maximin moves in (pos,score)
适用于您的图片示例:

example = maximin
  [Rose ((1,1),2) [Rose ((1,2),3) [], Rose ((1,3),-2) [], Rose ((1,4),4) []],
   Rose ((2,2),3) [Rose ((2,3),-7) [], Rose ((2,4),-1) []],
   Rose ((3,3),1) [Rose ((3,4),2) []]]
你会得到:

> example
((3,3),2)
看起来像是你想要的

关于性能的几点注意事项:

  • minimax算法实际上不使用内部节点的启发式分数,只在叶子上使用,因此您最好处理
    [Rose Position]
    ,只在需要的地方计算启发式分数(当您在
    minscore
    maxscore
    中检测到叶子时)
  • 是一个众所周知的极大极小优化算法,应该用于任何严肃的实现
无论如何,完整代码是:

import Data.List
import Data.Ord

type Position = (Int,Int)
type Score = Int
data Rose a = Rose a [Rose a]

maximin :: [Rose (Position, Score)] -> (Position, Score)
maximin = maximumBy (comparing snd) . map minscore
  where minscore (Rose x []) = x
        minscore (Rose (pos,_) moves)
          = let (_,score) = minimax moves in (pos,score)

minimax :: [Rose (Position, Score)] -> (Position, Score)
minimax = minimumBy (comparing snd) . map maxscore
  where maxscore (Rose x []) = x
        maxscore (Rose (pos,_) moves)
          = let (_,score) = maximin moves in (pos,score)

example = maximin
  [Rose ((1,1),2) [Rose ((1,2),3) [], Rose ((1,3),-2) [], Rose ((1,4),4) []],
   Rose ((2,2),3) [Rose ((2,3),-7) [], Rose ((2,4),-1) []],
   Rose ((3,3),1) [Rose ((3,4),2) []]]

在没有看到任何代码的情况下,很难提供很多指导。但是从逻辑上讲,如果你已经完成了所描述的一切设置,那么你已经完成了所有的艰苦工作——剩下的就是编写一个递归函数,给定一棵树,它根据你的启发计算出最佳移动。请将你的尝试与示例数据和预期输出一起分享。@RobinZigmond我编辑了这篇文章,其中包括一张照片。我希望它更容易理解。基本上需要一个将照片顶部的[Rose a]转换为底部的Rose a的功能。谢谢。我最终找到了答案,但这个实现更干净、更高效。
import Data.List
import Data.Ord

type Position = (Int,Int)
type Score = Int
data Rose a = Rose a [Rose a]

maximin :: [Rose (Position, Score)] -> (Position, Score)
maximin = maximumBy (comparing snd) . map minscore
  where minscore (Rose x []) = x
        minscore (Rose (pos,_) moves)
          = let (_,score) = minimax moves in (pos,score)

minimax :: [Rose (Position, Score)] -> (Position, Score)
minimax = minimumBy (comparing snd) . map maxscore
  where maxscore (Rose x []) = x
        maxscore (Rose (pos,_) moves)
          = let (_,score) = maximin moves in (pos,score)

example = maximin
  [Rose ((1,1),2) [Rose ((1,2),3) [], Rose ((1,3),-2) [], Rose ((1,4),4) []],
   Rose ((2,2),3) [Rose ((2,3),-7) [], Rose ((2,4),-1) []],
   Rose ((3,3),1) [Rose ((3,4),2) []]]