为海龟群创建梯度

Create a gradient for a turtle swarm

我总共使用了 1000 只海龟创建了一个矩形海龟网格。

let in-shape patches with [ pxcor >= -50 and pxcor <= 50 and pycor >= -5 and pycor <= 5 ]
ask in-shape [ sprout 1 ]

现在我需要创建一种 梯度 ,它会给我的海龟群带来一种距离感。给定一个值为 0 的“seed”,它会在 某些 talk_radius 中发出值为 0 的消息。
talk_radius 中的海龟计算它们到种子的距离。如果距离小于固定值(称为gradient_distance),乌龟将假设1为gradient_value,发出一条消息及其值。
其他海龟也这样做。所以大家会取值x+1,其中x是gradient_distance内龟的最低值,如图picture

这是伪代码中的相关算法:

loop
      if gradient seed = TRUE then // check if robot is designated as gradient source
     gradient value(self) = 0
  else
     gradient value(self) = GRADIENT MAX
     for all neighbors n do
        if measured distance(n) < G then // G represents the gradient-distance and GRADIENT MAX is infinity
           if gradient value(n) < gradient value(self) then
              gradient value(self) = gradient value(n)
     gradient value(self) = gradient value(self) + 1
  transmit gradient value(self)

这就是我在 netlogo 中的实现:

globals [talk_radius gradient_max gradient_distance]
turtles-own [gradient_seed gradient_value]

to setup
  ca
  resize-world -60 60 -20 20
  crt 1000
  let in-shape patches with [ pxcor >= -50 and pxcor <= 50 and pycor >= -5 and pycor <= 5 ]
  ask in-shape [ sprout 1 ]
  set talk_radius 4
  set gradient_max 100000
  set gradient_distance 1
  ask turtles
  [set shape "circle"]

  ask turtles-on patch -50 5
  [set gradient_seed true]
end

to gradient-formation
while [true]
[
  ask turtles
  [
    ifelse (gradient_seed = true)
    [
      set gradient_value 0
    ]
    [
      set gradient_value gradient_max
      set color scale-color green gradient_value 0 120
      ask (other turtles) in-radius talk_radius with [distance myself <= gradient_distance] ;; i consider all the turtle in talk_radius having the right gradient_distance
      [
        let a ([gradient_value] of self) ;; "of self" is not necessary but helped me for a better comprehension
        if (a < ([gradient_value] of myself))
        [
          ask myself [set gradient_value a]
        ]
      ]
      set gradient_value (gradient_value + 1)
    ]
    set color scale-color green gradient_value 0 120

  ]

]
end

我使用了比例色来获得对我所做工作的反馈,如您在 image 中所见。
现在的问题是:我尝试 set a ([gradient_value] of self) 添加 a[=46 而不是 let a ([gradient_value] of self) =] 到 turtle 变量(我在顶部的 turtle-own 列表中添加了一个)。
我以为结果会是一样的,但是我得到了一个 不断增加的 gradient_value 对于每只乌龟,正如你在 image 中看到的那样(颜色为白色表示非常高 gradient_value)。 为什么会有这种差异?
提前谢谢你,很抱歉问了这么长的问题。

针对改进问题的讨论进行了广泛编辑

首先,我想从一个更简单的代码版本开始。我相信这与没有 while[true] 的你的完全一样。为了清楚起见,我删除了您正在创建的额外 1000 只海龟,并将关于是否为种子的 ifelse 分成两个单独的 ask 语句。我也移动了颜色,直到值计算完成后。

globals [talk_radius gradient_max gradient_distance]
turtles-own [gradient_seed? gradient_value]

to setup
  clear-all
  resize-world -60 60 -20 20
  let in-shape patches with [ pxcor >= -50 and pxcor <= 50 and pycor >= -5 and pycor <= 5 ]
  ask in-shape
  [ sprout 1
    [ set shape "circle"
      set gradient_seed? false
    ]
  ]
  set talk_radius 4
  set gradient_max 100000
  set gradient_distance 1

  repeat 10 [ gradient-formation ]
end

to gradient-formation
  ask turtles-on patch -50 5
  [ set gradient_seed? true
    set gradient_value 0
  ]
  ask turtles with [not gradient_seed?]
  [ set gradient_value gradient_max
    ask (other turtles) in-radius talk_radius with [distance myself <= gradient_distance]
    [ let my-gradval ([gradient_value] of self)
      if my-gradval < [gradient_value] of myself
      [ ask myself [set gradient_value my-gradval]
      ]
    ]
    set gradient_value (gradient_value + 1)
  ]

  ask turtles [set color scale-color green gradient_value 0 120 ]
end

这里有一个概念问题。直到一只海龟计算出它的gradient_value,它是0。这意味着大量海龟附近会有一只0海龟,然后它们自己的gradient_value为1。它不会产生颜色渐变。要解决此问题,您需要 运行 多次 gradient-formation。 while [true] 代码中的方法引入了无限循环。相反,您可以 repeat 任意次数(上面代码中的 10 次)。

letset + turtles-won 的问题在于 set 和 turtles-own 创建了 1000 个副本 gradient_value - 一个对于每只乌龟。 let 版本创建了一个所有海龟都可以访问的(临时)全局变量。所以当你使用 set 时,你是为那只乌龟设置它,而不是作为一个通用的访问号码。我认为正在发生的事情是行 set gradient_value my-gradval 正在访问错误的乌龟副本 my-gradval。

但是,根据讨论,导致问题的代码的目的是找到局部最小值。有一种更直接的方法。

to gradient-formation
  ask turtles-on patch -50 5
  [ set gradient_seed? true
    set gradient_value 0
  ]
  ask turtles with [not gradient_seed?]
  [ set gradient_value 1 + min [gradient_value] of 
      other turtles in-radius min (list talk_radius gradient_distance)
  ]

  ask turtles [set color scale-color green gradient_value 0 120 ]
end

添加了一个最小工作示例以显示差异。

这是let(全局变量)版本

turtles-own [testval]

to testme
  clear-all
  create-turtles 500
  [ setxy random-xcor random-ycor
    set color blue
    set testval 1 + random 10
  ]
  ask one-of turtles
  [ set color red
    inspect self
    type "testval of asking turtle is " print testval
    ask turtles-on neighbors
    [ set color yellow
      let my-testval [testval] of self   ;; creates a temp global variable
      type "my-testval is " print my-testval
      if my-testval < [testval] of myself
      [ ask myself
        [ set testval my-testval        ;; copies the global variable value
        ]
      ]
    ]
  ]
end  

这是set(海龟属性)版本

turtles-own [testval my-testval]

to testme
  clear-all
  create-turtles 500
  [ setxy random-xcor random-ycor
    set color blue
    set testval 1 + random 10
  ]
  ask one-of turtles
  [ set color red
    inspect self
    type "testval of asking turtle is " print testval
    ask turtles-on neighbors
    [ set color yellow
      set my-testval [testval] of self
      type "my-testval is " print my-testval
      if my-testval < [testval] of myself
      [ ask myself
        [ set testval my-testval    ;; copies value from one attribute to other
        ]
      ]
    ]
  ]
end