6

我正在考虑如何将“蚂蚁农场模拟器”从 Erlang 移植到 Erlang。这是基本的纲要:

1) 定义一个 100x100 的“插槽”世界

2)蚂蚁占用一个槽

3) 蚁群占据位置 50,50

4)食物在地图周围随机放置

5)蚂蚁一次移动一个空间寻找食物并将其带回殖民地

6) 一次只能在一个槽中放置一个对象。

这个问题的目标是尽可能保持系统并发。在 Clojure 中,上述问题通过拥有一个代理线程池来解决,每个代理为单个蚂蚁运行 AI。然后这些蚂蚁通过事务更新全局状态。

这是我一直在思考的全球状态。我们如何去构建“游戏世界”?

我的第一个想法是为每个蚂蚁创建一个 Erlang 进程,然后为地图中的每个插槽创建一个进程。要移动,蚂蚁会执行以下操作:

1)蚂蚁告诉它当前的位置“我想向北移动”

2) 插槽向北调用插槽并说“请更新您的内容以现在包含蚂蚁“pid””

3)如果北槽已经有一只蚂蚁,它会发送一个“拒绝”响应,该响应会向下渗透到包含蚂蚁的槽(然后是蚂蚁)。如果更新有效,那么“授权”会沿着链向下发送,并且蚂蚁会更新其内部状态。

我唯一不喜欢这种方法的是,在移动过程中,蚂蚁、它的槽和目标槽都被“锁定”,直到整个事务完成。然后,这会为死锁打开自己的大门。也就是说,两只蚂蚁可能同时试图交换位置,每个位置都在等待另一个位置。

任何人都可以提出更好的解决方案吗?

- -编辑 - -

让我逐步解决死锁问题:

1) Ant 1 请求 slot A “向北传输”到 slot 2 2) Ant 2 请求 slot B “向南传输”到 slot 1 3) Slot 1 向 slot 2 发送传输请求并等待回复 4) Slot 2向 slot 1 发送传输请求并等待回复

从代码的角度来看,这将很容易实现,但也会出现死锁,因为每个插槽只监听来自另一个插槽的回复。我想“正确的方法”可能是在转移过程中自动拒绝所有转移请求。

4

2 回答 2

1

让你的蚂蚁向它要移动的位置投掷,请求允许移动。蚂蚁然后等待一个演员响应,告诉它移动是否成功。如果移动成功,蚂蚁会更新自己的状态以指示他在新槽中。如果失败,他将再次执行他的搜索逻辑。如果你最终让 A 和 B 试图交换插槽,你不会陷入僵局,但他们都会认为他们必须寻找其他选择。

如果您的网格被大量占用,您可能希望插槽执行轮询逻辑,将权限分发给相邻的蚂蚁,告诉他们如果他们的逻辑将他们引导到那里,他们可能会进入。(想象一个上面有 50x50-2 蚂蚁的网格,你就会明白为什么这是一个很好的逻辑改变。)

永远不要使用电话,除非你绝对、肯定、毫无疑问地没有电话就无法生存。然后,如果同一类型的进程有机会相互调用,或者可以相互调用的类型,则非常努力地摆脱它们。

于 2012-04-23T23:24:43.667 回答
0

我假设当它无法向北移动时,它会尝试不同的方向?那么僵局在哪里呢?

如果该领域非常拥挤,我可以想象饥饿,但不是僵局。

于 2012-04-23T18:55:29.300 回答