【问题标题】:Clojure agents interaction failureClojure 代理交互失败
【发布时间】:2011-08-23 22:06:54
【问题描述】:

想象一下:平面世界 n*n 个单元格。有移动的物体。它们可能会发生碰撞,根据流程,它们中的一个应该被销毁。

我使用来自 Rich Hickey 蚁群的想法将对象表示为代理。因此,在碰撞后,其中一个代理必须在收到其他代理的消息后停止工作。

有一个代码 sn-p 来说明我的问题:第二个代理意外停止。

;agents
(def f_guy (agent nil))

(def s_guy (agent nil))

;functions for agents
(defn f_do [x]
  (do
    (Thread/sleep 20)
    (println "f")
    (send-off *agent* f_do)))

(defn s_do [x]
  (do
    (Thread/sleep 40)
    (println "s")
    (send-off f_guy nil)
    (send-off *agent* s_do)))

;the process
(defn start []
  (do
    (send-off f_guy f_do)
    (send-off s_guy s_do)))

;go
(start)

谢谢!

【问题讨论】:

    标签: clojure agent


    【解决方案1】:

    您向f_guy 发送了调用nil 作为函数的请求。他做到了,这让他通过抛出异常进入了一个破碎的状态。然后,您让他再次致电nil。但他甚至不能同意这样做,因为他已经崩溃了,等待着有人来修复他。所以s_guy 一直在等待f_guy 确认(还不一定执行)请求,而f_guy 已经下班了。

    【讨论】:

    • 谢谢!我曾尝试(发送 f_guy nil)两次,它向我展示了 java.lang.RuntimeException
    【解决方案2】:

    请问你想在这里完成什么?

    第一个和第二个代理在我的实验中都失败了,这是因为你基本上是把代理放在代理里面……

    例子:

    (def a (agent 0))
    (send-off a inc) ; -> #<Agent@29de03: 1>
    

    所以通过这样做:

    (defn f_do [x]
      (do
        ...
        (send-off *agent* f_do)))
    

    您在代理中递归地返回代理。

    【讨论】:

    • 我会尽力解释。就像在 Rich Hickey 的蚁群中一样,我有一个 2d 世界和其中的移动物体。我想评估碰撞,一旦对象被表示为代理 - 为了 kill 对象,我必须停止代理,我通过向他发送 nil 消息来做到这一点。
    • 蚁群演示非常老了(比如三年)。让代理向自己发送动作来模拟重复动作并不是最好的解决方案。实际上,您不应该将对象表示为“代理”,而是使用代理(或其他东西)来管理对象的不断变化的状态。与其发送代理 nil(这确实让他崩溃和燃烧,而且对他来说非常“粗鲁”),您需要一个更好的模型来协调各种对象之间的状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2021-12-20
    • 2023-03-16
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多