#tree-search #multi-agent #mcts #ai #monte-carlo #simulation #game

npc-engine-core

NPC引擎的核心,提供通用的MCTS框架

1个不稳定版本

0.1.0 2022年6月15日

#1591算法


用于 npc-engine-utils

MIT/Apache

96KB
1.5K SLoC

NPC引擎

Build Status

© 2020-2022 苏黎世联邦理工学院和其他贡献者。有关更多详细信息,请参阅AUTHORS.txt

ETH游戏技术中心提供的一个可定制的蒙特卡洛树搜索(MCTS)规划器,具有针对多智能体模拟和涌现叙事的高级特性。

NPC引擎提供以下功能

  • 领域无关的MCTS规划器,
  • 可变持续时间任务,使其除了规划器外还成为调度器,
  • 异构智能体(例如,在常规智能体旁边有一个全局簿记智能体),允许进行干净的领域设计,
  • 支持动态出现和消失的智能体(甚至在一个规划树内),
  • 当任务无效时的选择行为:剪枝该子树(如棋类游戏),或重新规划(如模拟),
  • 除了标准 rollout 之外,还提供自定义状态值函数,
  • 包括跟踪和绘制搜索树为图(使用graphviz的dot格式)在内的多个调试功能,
  • 提供了一些示例,辅助库和研究论文的代码(见下文)。

获取它

要获取NPC引擎,请克隆此仓库

git clone https://github.com/ethz-gtc/npc-engine.git

确保您已安装GIT LFS,您可以在此处阅读如何安装它。如果没有,PNG文件将无法正确获取,您将看到PNG解码错误。

示例

我们提供了几个示例,说明了引擎的各种功能。

要运行示例,您需要安装Rust

确保您的控制台使用支持unicode表情符号的字体,因为我们使用表情符号进行可视化。在最新的Linux和MacOS机器上,它们默认支持。在Windows 10及更高版本上,您可以安装最近发布的Windows Terminal,并使用wt

井字棋

cargo run --release --example tic-tac-toe

这是一个传统的井字棋回合制游戏,您可以与计算机进行交互式对战。要移动,请输入X Y,其中XY是您的移动坐标(0、1或2)。

源目录:tic-tac-toe

捕获

cargo run --release --example capture

这是两个智能体之间竞争性战斗的模拟,每个智能体都试图捕获位置。

智能体可以确保位置,收集弹药和医疗包,并互相射击。他们轮流计划。每次任务完成后,模拟都会输出世界状态和智能体的状态。

  • 对于世界,它显示了医疗包(❤️)、弹药(•)和捕获位置的(⚡)状态。对于捕获位置,“__”表示它属于无人,“CX”(X = 0或1)表示一个智能体正在捕获它,“HX”(X = 0或1)表示一个智能体持有该位置。一个被持有的位置会随着时间的推移带来胜利点。
  • 对于智能体,捐赠的“AX”中X是智能体ID,以下内容显示:他们的位置(例如0)或位置(例如0-1,如果是移动的情况),他们的健康点(❤️),他们携带的弹药数量(•)以及他们的胜利点数(⚡)。
  • 显示即将完成的任务,如果由于规划时完成条件已更改而导致执行失败,也会显示出来。
  • 然后对该智能体运行计划,显示并排队执行所选任务。

此领域演示了各种持续时间的行为,世界智能体重生收集品,智能体的消失(死亡时),以及简单执行器实用程序的使用。

源目录:capture

学习

cargo run --release --example learn

这是一个1-D伐木工模拟,智能体的性能随着时间的推移而提高,因为它是通过自我学习来提高的。每次运行后都会输出收集到的木材量。

智能体必须通过在一个1-D世界中砍伐树木来收集木材,同时使用少量的MCTS访问次数。此示例中的状态值函数估计器不是一个标准的roll-out模拟,而是一个包含两个神经元的单隐藏层的前馈神经网络。模拟在多个epoch中重复进行,每次使用基于MCTS的状态值估计来训练神经网络,以使用反向传播来训练下一个epoch。这个模拟表明,在几百个epoch的过程中,智能体的性能——在特定时间段内收集的木材量——提高了50%以上。

安装了Python 3、scipymatplotlib后,可以通过以下命令查看epoch的性能,平均20次运行:

npc-engine-core/examples/learn/plot.py

曲线应该看起来像这样

Wood collected over epochs

源目录:learn

生态系统

cargo run --release --example ecosystem

这是一个二维生态系统模拟,其中食草动物(🐄)和食肉动物(🐅)会吃和死。

世界由一个瓦片地图组成,每个瓦片可以是空的(深绿色)、障碍物(灰色)或草地(绿色)。草地瓦片可以提供1-3个单位的食物,通过饱和度的增加来表示。食草动物通过吃食会减少其站立瓦片上的食物量1个单位。食草动物出生时携带5个单位的食物,并且可以储存最多5个单位的食物。肉食动物可以吃掉相邻瓦片或一个瓦片距离的食草动物。它们也可以跳到一个瓦片距离,包括越过其他实体,但不能越过障碍物,这需要额外的1个单位食物。肉食动物出生时携带10个单位的食物,并且可以储存最多10个单位的食物。当实体吃食时,其储存的食物会恢复到最大值。每10帧,所有实体都会消耗1个单位的食物。如果没有食物,它们会死亡。

所有实体在各自的局部世界视图上以多线程方式并行规划。规划持续3帧,其他动作是瞬时的。实体可以看到8个瓦片距离的地图,并且考虑3个距离内的其他实体,对于食草动物是6个瓦片,对于肉食动物是3个瓦片。在规划时,实体只考虑3个最近的其他实体,如果有超过3个。它们的规划目标是每轮1000次访问,但如果计算能力不足,规划可能会提前结束。在这种情况下,计划质量会下降。模拟以每秒25帧的速度运行。

世界中的实体只有一个“步进”动作,它负责每10帧管理每个实体食物量的减少;以及每30帧为具有1或2个单位食物的瓦片恢复草地。

源目录: ecosystem

伐木工

目录 scenario-lumberjacks

用于2020年Raymond等人论文《利用高效的规划和轻量级实体定义:一种实现涌现叙事的新途径》中的研究代码。该领域有两个伐木工,其价值函数是收集到的总木材数量。这两个实体之间没有明确的沟通,但因为他们为对方规划,因此产生了心智理论。您可以在这个视频中了解这项工作的概述。

要查看该场景的基本运行,请使用以下命令

cargo run --release --bin lumberjacks scenario-lumberjacks/experiments/base.json

您可以通过按“空格”键来逐步进行模拟。有两个实体,红色和黄色,它们轮流执行动作。在这个基本场景中,红色实体将通过考虑黄色实体的可能动作,以最优顺序收集所有树木。

可以通过使用-s标志设置配置参数来非交互式地运行场景

cargo run --release --bin lumberjacks -- -s display.interactive=false scenario-lumberjacks/experiments/base.json

以下是论文中的一些有趣实验

基本竞争

红色实体按照顺序收集木材,以阻止黄色实体收集任何,将所有留给自身。

cargo run --release --bin lumberjacks scenario-lumberjacks/experiments/competition-basic/base.json

高级竞争

红色实体通常会将其收集的第一批木材用于建立一个障碍物,以阻止黄色实体收集更多木材,为自己留下更多。这展示了推理他人并为了更大的长期利益而接受短期损失的能力。

cargo run --release --bin lumberjacks scenario-lumberjacks/experiments/barrier/base.json

合作

现在,所有与正在砍伐的树木相邻的实体也会收到一个木材。因此,通过规划和隐含的规划,这两个实体同步地砍伐同一棵树。

cargo run --release --bin lumberjacks scenario-lumberjacks/experiments/teamwork-basic/base.json

可持续性

有一个水井可供实体浇水,让树木重新长到完整大小。实体不会完全砍伐树木,而是在树木几乎死亡时去水井取水。

cargo run --release --bin lumberjacks scenario-lumberjacks/experiments/optimization/base.json

如果我们还允许智能体种植一棵新树(使用一块木头),智能体会砍倒这棵树,然后在离井更近的地方重新种植

cargo run --release --bin lumberjacks -- -s features.planting=true scenario-lumberjacks/experiments/optimization/base.json

文档

NPC 引擎由两个包组成: npc-engine-corenpc-engine-utils。可以通过以下命令生成和交互式浏览文档

cargo doc --open -p npc-engine-core -p npc-engine-utils

关于性能的说明

Rust 强烈依赖于编译器优化。确保你在 cargo 调用时包含 --release 标志以实现高效执行。

生成搜索树图的 PDF

一些示例(生态系统、捕获、井字棋)使用辅助函数 plot_tree_in_tmp_with_task_nameplot_tree_in_tmp 来生成搜索树在临时目录中的 Graphviz 的 dot 格式 图。使用生成的 .dot 文件,你可以使用以下命令创建 PDF 树

for file in $(ls *.dot); do dot -Tpdf $file -o `basename -s .dot $file`.pdf; done

请引用我们

如果你在学术环境中使用此软件,请引用我们的论文

@inproceedings{raymond2020leveraging,
	title={Leveraging efficient planning and lightweight agent definition: a novel path towards emergent narrative},
	author={Raymond, Henry and Knobloch, Sven and Z{\"u}nd, Fabio and Sumner, Robert W and Magnenat, St{\'e}phane},
	booktitle={12th Intelligent Narrative Technolgies Workshop, held with the AIIDE Conference (INT10 2020)},
	doi={10.3929/ethz-b-000439084},
	year={2020},
}

感谢及替代方案

我们想感谢 Patrick Eppensteiner、Nora Tommila 和 Heinrich Grattenthaler 对这个研究项目的贡献。

对此工作的某些替代方案,也在 Rust 中,包括 mctsarborboard-game 框架。

许可

NPC 引擎是免费和开源的!本存储库中的所有代码都根据你的选择,在以下两种许可下双许可

任选其一。

贡献

除非你明确表示,否则,根据 Apache-2.0 许可证定义,你故意提交的任何旨在包含在作品中的贡献,都应如上所述双许可,不附加任何额外条款或条件。

依赖

~1–2.1MB
~45K SLoC