为海龟群创建梯度
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 次)。
let
与 set
+ 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
我总共使用了 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 次)。
let
与 set
+ 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