0

我听说 Haskell 中存在树实现的策略,但我还没有找到任何关于良好行为树替代方案的信息。

我的目标:给定一个表示状态的元组,将该元组提供给行为节点树的最佳模式是什么,每个行为节点都根据元组返回忙/错误/已完成/正在运行。该行为也可能改变元组(导致状态改变)。

嵌套节点可以根据其父节点的策略执行。例如,如果子节点返回“错误”,则不会评估更多子节点。另一种策略是即使返回错误状态也执行所有子节点。

我希望这是有道理的!

4

4 回答 4

4

不幸的是,您似乎是一个很少有 Haskell 用户了解的领域的专家。关于这些技术,我所知道的只是我从非技术人员那里听到的关于不同业务规则引擎的讨论,所以我可能不太了解,但我认为值得一试,因为其他人都被难住了。

就前向链接推理系统,尤其是 Rete 算法而言,它们基本上已经可以正常工作了。他们在进行过程中迭代并向数据库添加更多知识,直到没有事情可做。如果您不允许任意效果,那将是一个简单的Control.Monad.State端口;如果你需要任意效果,你可以使用状态单子变换器,而不是中级/高级 Haskellers 会被吓倒的东西。您可能会在 Haskell 网站上找到可以使用的东西,但如果您最终自己这样做,那么Real World Haskell的 Monad Transformers章节是必不可少的。

我对行为树一无所知,但在维基百科上一目了然,它们在我看来就像 Rete 算法加上后台的并发进程。如果这甚至接近正确,那么您必须决定是否需要并发性或并行性。如果您满足于“神奇地”更快地计算纯值(并且,通过扩展,所有内容都是用 Haskell 编写的),那么您可以Control.Parallel不费力气地使用这些东西,但您将无法(比如说) 查询哪些进程正在运行,哪些没有。如果您真的需要不同的可观察行为,那么您将需要Control.Concurrent它并且它不那么神奇,所以更多的簿记。Simon Marlow 写了一个很好的教程关于你在那里的选择。你所描述的对我来说听起来比 Haskell 可以为你做的大多数很酷的东西都低级。如果您决定接受更高级别的接口,您可能会发现它更容易实现。我也不是这个主题的专家。

于 2012-05-10T04:24:17.677 回答
3

我最近发布了关于 hackage 的 smarties 行为树库

https://hackage.haskell.org/package/smarties

我确信还有其他在 haskell 中实现 BT 的好方法,但我对这个设计非常满意。注意 smarties 仅支持 2 个节点状态 SUCCESS 和 FAIL。

针对您的问题:

将该元组提供给行为节点树的最佳模式是什么,每个行为节点都根据元组返回忙/错误/已完成/正在运行。该行为也可能改变元组(导致状态改变)。

smarties 的主要类型是一个 monad,它表示具有内部感知(状态)的节点序列。从这个意义上说,它与 State monad 非常相似。还有一些接口可以强制执行不可变的感知。

嵌套节点可以根据其父节点的策略执行。例如,如果子节点返回“错误”,则不会评估更多子节点。另一种策略是即使返回错误状态也执行所有子节点。

每当它遇到 FAIL 节点时,它都会将状态和最终输出短路。然而,它仍然运行剩余的节点来获取它的一元返回值,这对于在 BT 中组合逻辑非常有用。

因此,选择器(代表分支逻辑)是通过传入节点单子列表并采用第一个具有成功状态的单子来实现的。

Monadic 语法在行为树中非常强大。您在树中的某个点读取状态,然后在树中使用它的值。这使得节点更容易组合!

于 2020-03-28T00:49:50.397 回答
2

您的问题我们都有些困惑,当您说“元组”时,我可能不明白您的意思,而是在黑暗中拍摄:

我编写了一个名为 simple-actors 的小型库,用于Actor Model concurrency。如果您可以想象通过“演员”在并发“频道”上侦听并相互交流需要完成什么,那么您可能有兴趣看一下。

此处文档的顶部是一种演员二叉搜索树的示例(您的问题让我想到了这一点,抱歉,如果这一切都离题了)。

编辑:我应该提到我发现行为树上的维基百科页面完全难以理解;也许熟悉企业术语的人可以提供帮助。

于 2012-05-10T00:37:32.103 回答
1

由于没有找到 BT 实现,我自己在 Haskell 中开始了某种 BT 实现,如下所述:

http://www.brainific.com/blog/2015/09/twisting-your-trees/

并存储在这里:

https://bitbucket.org/brainific/action-fw/src

这里有具体的测试:

https://bitbucket.org/brainific/action-fw/src/a6081b740dc4b8258f67f49df473458737fc4240/test/BehaviourTrees21Test.hs?at=master&fileviewer=file-view-default

请注意标准行业 BT 的一些不同功能:

  • 这些树是事件驱动的,在某种程度上更像是一棵事件处理过程树,而不是更常见的轮询树;
  • 事件类型是通用的:成功/失败/运行状态只是另一种事件类型,由转换函数处理,因此您实际上可以轻松混合和匹配 BT 节点和 FSM 节点;
  • 事件节点不是静态的,而是在运行时从某些 Env 数据类型生成的(我没有进行深入的性能检查,但希望 Haskell RTS 在这里应该有所帮助);
  • 节点是通过代码指定的,因此它们可以比平时更奇特(其中一个可以产生计划过程并等待“继续”开始,在执行计划时中断默认的 BT 运行);
  • 尚未实现黑板或代理间消息(尽管添加地图和频道应该相当简单)。

使用 Haskell 有一些问题(例如,我仍然不能弯曲类型系统来表示处理事件类型 T1 的树只能包含触发事件类型 T1 的子树),但可以提供一些具有很强表达能力的功能(例如循环作为无限懒惰列表)。

请注意,它仍然是相当 alpha 甚至是 pre-alpha!我开始将它与 The Dark Mod ( http://thedarkmod.com ) 集成,我希望在其中验证我的假设。如果您最终感兴趣,请随时发送邮件。

于 2017-12-11T08:59:43.973 回答