圆形竞技场中的运动模拟
Movement Simulation in a Circular Arena
我希望通过 NetLogo 模拟完成以下任务:
创建一个半径为10厘米的三个区域的有界圆形世界
- 外区:定义距离世界边界 1.5 厘米的环形空间(红色)
- 内区:半径为 8 厘米的圆(灰色)
- 禁区:所有海龟(黑色)的禁区
运动行为
- 乌龟在下面的代码中给出了预定义的转动角度和移动长度
- 但是,我想包括乌龟暂停 n 滴答
的一些正态分布持续时间的概率
边缘跟随行为 - Thigmotaxis
乌龟可以随意进入外区,但以下规则会控制它在那里的行为:
- 一只海龟如果进入内部区域,可能会逃离外部区域。
- 但是,海龟留在内部区域内的概率等于每个 tick [一些正态分布的概率]。
在每个刻度的基础上为每只海龟生成位置报告(二维坐标)
将此报告导出为 CSV 或 TXT 文件
我的代码基于 NetLogo 库中的“Random Walk Example”,包括“per tick”规则,例如转角、移动长度。我试图实现海龟每刻暂停的概率,但我不知道如何合并 n 刻的持续时间。内部和外部区域是不同颜色的补丁。然后,我们可以将乌龟的行为建立在 if pcolor = red [commands go here]
的基础上。此外,当乌龟撞到世界边界时,它往往会被卡住,因为它会蠕动以寻找逃生角度。相反,是否有可能让乌龟在避开禁区(黑色补丁颜色)的同时“变成”世界的弯曲墙?最后,对于数据导出,保存 Commmand Center
输出很容易,但它的格式不便于分析,即 x、y 单独列中的坐标等
to setup
clear-all
resize-world -100 100 -100 100 ; 1 unit = 1 mm
set-patch-size 2
ask patches [set pcolor black] ; outside arena | how to designate this patch color as "forbidden"?
ask patch 0 0 [ask patches in-radius 100 [set pcolor red]] ; outer zone
ask patch 0 0 [ask patches in-radius 85 [set pcolor gray]] ; inner zone
create-turtles 10 [set size 15]
ask turtles [
set color one-of base-colors ; assign color to each turtle without repeats?
pen-down
]
reset-ticks
end
to go
if ticks = 1200 [stop] ; each tick = 1 second
move-turtles
tick
end
to move-turtles
ask turtles [
if random-float 1 > 0.05 ; 5% probability of pause per tick
[;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
forward random-normal 10 4
show list xcor ycor
]
end
从技术上讲,这是一堆(公认的相关)问题,而不是单个问题(在 Whosebug 上更受欢迎)。但我会看看我是否能做出连贯的答案。
这里是 a runnable version of the final code,其中包含所有感兴趣的人的所有更改。
首先,控制乌龟移动的最简单方法是使用 patch-ahead
原语来检查它们将移动到哪里,然后在必要时更改它们的目的地。当使用 forward 1
而不是随机数时,这是最简单的,所以我从它开始。然后我使用 face one-of neighbors with [pcolor = red]
让乌龟面对一个“好”的补丁。同样,这仅适用于 forward 1
.
我还添加了 __change-topology false false
以防止乌龟环绕世界,因为一些补丁确实在边缘处接触。
to setup
clear-all
resize-world -100 100 -100 100 ; 1 unit = 1 mm
; make sure the turtles can't wrap at the patches at the edges that touch
__change-topology false false
set-patch-size 2
ask patches [set pcolor black] ; outside arena | how to designate this patch color as "forbidden"?
ask patch 0 0 [ask patches in-radius 100 [set pcolor red]] ; outer zone
ask patch 0 0 [ask patches in-radius 85 [set pcolor gray]] ; inner zone
create-turtles 10 [set size 15]
ask turtles [
set color one-of base-colors ; assign color to each turtle without repeats?
pen-down
]
reset-ticks
end
to go
if ticks = 1200 [stop] ; each tick = 1 second
move-turtles
tick
end
to move-turtles
ask turtles [
if random-float 1 > 0.05 ; 5% probability of pause per tick
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; Item #1 - outer zone blocked
; if turtles only move `1` at time, they cannot "skip" past a patch
; so to prevent moving into the black, all we have to do is point them somewhere else
if [pcolor] of patch-ahead 1 = black [
face one-of neighbors with [pcolor = red]
]
forward 1
]
end
第二项是从外部观察到的粘性内部区域。我们使用与上述相同的技术并进行一些小调整。我没有对 setup
或 go
进行更多更改,因此从这里开始只显示 move-turtles
:
to move-turtles
ask turtles [
if random-float 1 > 0.05 ; 5% probability of pause per tick
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; to control turtle movement, we're going to use `patch-ahead` to check the patch color
; before moving. if turtles only move `1` at time, they cannot "skip" past a patch, which
; is necessary to use this technique.
; Item #1 - outer zone blocked
; so to prevent moving into the black, all we have to do is point them somewhere else
if [pcolor] of patch-ahead 1 = black [
face one-of neighbors with [pcolor = red]
]
; Item #2 - inner zone stickiness
; if we're in the outer zone and our target patch is inner zone, don't keep moving that way
; if we fail our check
if
pcolor = red ; we're in the outer zone
and [pcolor] of patch-ahead 1 = gray ; our target patch is grey
and random-float 1 < 0.8 ; our random probability to bounce off
[
; then we bounce off
face one-of neighbors with [pcolor = red]
]
forward 1
]
end
第三项是你想让海龟做的“暂停”。我不清楚这应该如何工作。首先,最简单的是,这只是乌龟不为蜱行动的机会。在这里,我将机会存储在一个 paused
变量中,该变量用于转弯和 forward
。很难看到结果,因为滴答 运行 如此之快,但它们确实会暂停片刻。
to move-turtles
ask turtles [
; Item 3a - single tick pause - 5% chance to pause and not move forward
let paused (random-float 1) <= 0.05
if not paused
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; to control turtle movement, we're going to use `patch-ahead` to check the patch color
; before moving. if turtles only move `1` at time, they cannot "skip" past a patch, which
; is necessary to use this technique.
; Item #1
; so to prevent moving into the black, all we have to do is point them somewhere else
if [pcolor] of patch-ahead 1 = black [
face one-of neighbors with [pcolor = red]
]
; Item #2
; if we're in the outer zone and our target patch is inner zone, don't keep moving that way
; if we fail our check
if
pcolor = red ; we're in the outer zone
and [pcolor] of patch-ahead 1 = gray ; our target patch is grey
and random-float 1 < 0.8 ; our random probability to bounce off
[
; then we bounch off
face one-of neighbors with [pcolor = red]
]
if not paused [
forward 1
]
]
end
由于很难看到这种效果,并且因为您提到要暂停 n
个刻度,所以我还做了一个版本,其中每只海龟都跟踪应该暂停多长时间。为此,我们需要在文件顶部添加一个 turtles-own [ pause ]
变量来计算它静止不动的滴答声。如果乌龟碰上了随机机会,它不会移动,而是设置暂停变量,并且在未来的滴答声中,它将倒计时到 0
,然后再次开始移动。
to move-turtles
ask turtles [
; `pause = 0` to keep them from spinning in place when paused
if pause = 0 and random-float 1 > 0.05 ; 5% probability of pause per tick
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; to control turtle movement, we're going to use `patch-ahead` to check the patch color
; before moving. if turtles only move `1` at time, they cannot "skip" past a patch, which
; is necessary to use this technique.
; Item #1 - outer zone barrier
; so to prevent moving into the black, all we have to do is point them somewhere else
if [pcolor] of patch-ahead 1 = black [
face one-of neighbors with [pcolor = red]
]
; Item #2 - inner zone stickiness
; if we're in the outer zone and our target patch is inner zone, don't keep moving that way
; if we fail our check
if
pcolor = red ; we're in the outer zone
and [pcolor] of patch-ahead 1 = gray ; our target patch is grey
and random-float 1 < 0.8 ; our random probability to bounce off
[
; then we bounch off
face one-of neighbors with [pcolor = red]
]
; Item #3b - counting pause
; if we are paused, just decrement the pause and take no action
ifelse pause > 0 [
set pause (pause - 1)
] [
ifelse random-float 1 > 0.05 [
; 95% chance to move forward
forward 1
] [
; 5% chance to pause 5 ticks
set pause 5
]
]
]
end
您的最后一项是将海龟数据导出为 CSV 或文本。你有两个选择。您可以使用 the CSV extension or you can use BehaviorSpace 到 运行 您的模型作为“实验”。两者都会起作用。您已经在 move-turtles
过程中使用 show list xcor ycor
语句有了正确的想法,您只需要获取所有海龟的数据以输出到 CSV 或使用 BehaviorSpace 报告器:[(list who xcor ycor)] of turtles
。我包括 who
数字,这样数据更容易被 turtle track/sort。
编辑:
如评论中所述,先前版本可能会引发 运行时间错误。这个 NOBODY
错误是因为我禁用了环绕,这意味着海龟可能会面对世界边缘并执行 patch-ahead 1
which returns NOBODY
而我忘记检查它了。我会为此添加一个检查,但由于您想要可变步长版本,让我们同时添加它。
我们在使用 random-normal 10 4
时遇到的一个问题是它可以生成任意大的数字。 (顺便说一句,在我看来,每只海龟都有一个暂停也让它们每次移动了一个随机的距离,我不相信随机距离会增加太多。)如果我们想让海龟移动得更多一次多于 1 space,但我们想要保持只检查前面的补丁的相对简单的逻辑,我们可以将 forward 1
移动到一个循环中,随着我们的进行减少距离。然后,我们还必须将 bounce/sticky 检查移动到该循环中,因为我们可以从黑色的边缘向后穿过内部边界。
我还制定了一个更强大的 face-red-patch
程序来确保我们永远不会陷入困境。
你可以run the model online to test it out.
to move-turtles
ask turtles [
; `pause = 0` to keep them from spinning in place when paused
if pause = 0 and random-float 1 > 0.05 ; 5% probability of pause per tick
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; to control turtle movement, we're going to use `patch-ahead` to check the patch color
; before moving. if turtles only move `1` at time, they cannot "skip" past a patch, which
; is necessary to use this technique.
; Item #1 - outer zone barrier
; so to prevent moving into the black, all we have to do is point them somewhere else
if patch-ahead 1 = nobody or [pcolor] of patch-ahead 1 = black [
face-red-patch
]
; Item #3 - pause
; if we are paused, just decrement the pause and take no action
ifelse pause > 0 [
set pause (pause - 1)
] [
ifelse random-float 1 > 0.05 [
; 95% chance to move forward
; Item #5 - variable length moves
let forward-amount random-normal 10 4
while [patch-ahead 1 != nobody and [pcolor] of patch-ahead 1 != black and forward-amount > 0] [
; Item #2 - inner zone stickiness
; if we're in the outer zone and our target patch is inner zone, don't keep moving that way
; if we fail our check
if
pcolor = red ; we're in the outer zone
and [pcolor] of patch-ahead 1 = gray ; our target patch is grey
and random-float 1 < 0.8 ; our random probability to bounce off
[
; then we bounce off
face-red-patch
]
forward 1
set forward-amount (forward-amount - 1)
]
] [
; 5% chance to pause 5 ticks
set pause 5
]
]
]
end
to face-red-patch
; this kind of looping code can be dangerous, but if we're careful to use it only when we know it
; will terminate it should be okay. Use Tools > Halt if you think it hit a bad state and is in an
; infinite loop
while [patch-ahead 1 = nobody or [pcolor] of patch-ahead 1 != red] [
set heading random 360
]
end
我希望通过 NetLogo 模拟完成以下任务:
创建一个半径为10厘米的三个区域的有界圆形世界
- 外区:定义距离世界边界 1.5 厘米的环形空间(红色)
- 内区:半径为 8 厘米的圆(灰色)
- 禁区:所有海龟(黑色)的禁区
运动行为
- 乌龟在下面的代码中给出了预定义的转动角度和移动长度
- 但是,我想包括乌龟暂停 n 滴答 的一些正态分布持续时间的概率
边缘跟随行为 - Thigmotaxis
乌龟可以随意进入外区,但以下规则会控制它在那里的行为:
- 一只海龟如果进入内部区域,可能会逃离外部区域。
- 但是,海龟留在内部区域内的概率等于每个 tick [一些正态分布的概率]。
在每个刻度的基础上为每只海龟生成位置报告(二维坐标)
将此报告导出为 CSV 或 TXT 文件
我的代码基于 NetLogo 库中的“Random Walk Example”,包括“per tick”规则,例如转角、移动长度。我试图实现海龟每刻暂停的概率,但我不知道如何合并 n 刻的持续时间。内部和外部区域是不同颜色的补丁。然后,我们可以将乌龟的行为建立在 if pcolor = red [commands go here]
的基础上。此外,当乌龟撞到世界边界时,它往往会被卡住,因为它会蠕动以寻找逃生角度。相反,是否有可能让乌龟在避开禁区(黑色补丁颜色)的同时“变成”世界的弯曲墙?最后,对于数据导出,保存 Commmand Center
输出很容易,但它的格式不便于分析,即 x、y 单独列中的坐标等
to setup
clear-all
resize-world -100 100 -100 100 ; 1 unit = 1 mm
set-patch-size 2
ask patches [set pcolor black] ; outside arena | how to designate this patch color as "forbidden"?
ask patch 0 0 [ask patches in-radius 100 [set pcolor red]] ; outer zone
ask patch 0 0 [ask patches in-radius 85 [set pcolor gray]] ; inner zone
create-turtles 10 [set size 15]
ask turtles [
set color one-of base-colors ; assign color to each turtle without repeats?
pen-down
]
reset-ticks
end
to go
if ticks = 1200 [stop] ; each tick = 1 second
move-turtles
tick
end
to move-turtles
ask turtles [
if random-float 1 > 0.05 ; 5% probability of pause per tick
[;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
forward random-normal 10 4
show list xcor ycor
]
end
从技术上讲,这是一堆(公认的相关)问题,而不是单个问题(在 Whosebug 上更受欢迎)。但我会看看我是否能做出连贯的答案。
这里是 a runnable version of the final code,其中包含所有感兴趣的人的所有更改。
首先,控制乌龟移动的最简单方法是使用 patch-ahead
原语来检查它们将移动到哪里,然后在必要时更改它们的目的地。当使用 forward 1
而不是随机数时,这是最简单的,所以我从它开始。然后我使用 face one-of neighbors with [pcolor = red]
让乌龟面对一个“好”的补丁。同样,这仅适用于 forward 1
.
我还添加了 __change-topology false false
以防止乌龟环绕世界,因为一些补丁确实在边缘处接触。
to setup
clear-all
resize-world -100 100 -100 100 ; 1 unit = 1 mm
; make sure the turtles can't wrap at the patches at the edges that touch
__change-topology false false
set-patch-size 2
ask patches [set pcolor black] ; outside arena | how to designate this patch color as "forbidden"?
ask patch 0 0 [ask patches in-radius 100 [set pcolor red]] ; outer zone
ask patch 0 0 [ask patches in-radius 85 [set pcolor gray]] ; inner zone
create-turtles 10 [set size 15]
ask turtles [
set color one-of base-colors ; assign color to each turtle without repeats?
pen-down
]
reset-ticks
end
to go
if ticks = 1200 [stop] ; each tick = 1 second
move-turtles
tick
end
to move-turtles
ask turtles [
if random-float 1 > 0.05 ; 5% probability of pause per tick
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; Item #1 - outer zone blocked
; if turtles only move `1` at time, they cannot "skip" past a patch
; so to prevent moving into the black, all we have to do is point them somewhere else
if [pcolor] of patch-ahead 1 = black [
face one-of neighbors with [pcolor = red]
]
forward 1
]
end
第二项是从外部观察到的粘性内部区域。我们使用与上述相同的技术并进行一些小调整。我没有对 setup
或 go
进行更多更改,因此从这里开始只显示 move-turtles
:
to move-turtles
ask turtles [
if random-float 1 > 0.05 ; 5% probability of pause per tick
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; to control turtle movement, we're going to use `patch-ahead` to check the patch color
; before moving. if turtles only move `1` at time, they cannot "skip" past a patch, which
; is necessary to use this technique.
; Item #1 - outer zone blocked
; so to prevent moving into the black, all we have to do is point them somewhere else
if [pcolor] of patch-ahead 1 = black [
face one-of neighbors with [pcolor = red]
]
; Item #2 - inner zone stickiness
; if we're in the outer zone and our target patch is inner zone, don't keep moving that way
; if we fail our check
if
pcolor = red ; we're in the outer zone
and [pcolor] of patch-ahead 1 = gray ; our target patch is grey
and random-float 1 < 0.8 ; our random probability to bounce off
[
; then we bounce off
face one-of neighbors with [pcolor = red]
]
forward 1
]
end
第三项是你想让海龟做的“暂停”。我不清楚这应该如何工作。首先,最简单的是,这只是乌龟不为蜱行动的机会。在这里,我将机会存储在一个 paused
变量中,该变量用于转弯和 forward
。很难看到结果,因为滴答 运行 如此之快,但它们确实会暂停片刻。
to move-turtles
ask turtles [
; Item 3a - single tick pause - 5% chance to pause and not move forward
let paused (random-float 1) <= 0.05
if not paused
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; to control turtle movement, we're going to use `patch-ahead` to check the patch color
; before moving. if turtles only move `1` at time, they cannot "skip" past a patch, which
; is necessary to use this technique.
; Item #1
; so to prevent moving into the black, all we have to do is point them somewhere else
if [pcolor] of patch-ahead 1 = black [
face one-of neighbors with [pcolor = red]
]
; Item #2
; if we're in the outer zone and our target patch is inner zone, don't keep moving that way
; if we fail our check
if
pcolor = red ; we're in the outer zone
and [pcolor] of patch-ahead 1 = gray ; our target patch is grey
and random-float 1 < 0.8 ; our random probability to bounce off
[
; then we bounch off
face one-of neighbors with [pcolor = red]
]
if not paused [
forward 1
]
]
end
由于很难看到这种效果,并且因为您提到要暂停 n
个刻度,所以我还做了一个版本,其中每只海龟都跟踪应该暂停多长时间。为此,我们需要在文件顶部添加一个 turtles-own [ pause ]
变量来计算它静止不动的滴答声。如果乌龟碰上了随机机会,它不会移动,而是设置暂停变量,并且在未来的滴答声中,它将倒计时到 0
,然后再次开始移动。
to move-turtles
ask turtles [
; `pause = 0` to keep them from spinning in place when paused
if pause = 0 and random-float 1 > 0.05 ; 5% probability of pause per tick
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; to control turtle movement, we're going to use `patch-ahead` to check the patch color
; before moving. if turtles only move `1` at time, they cannot "skip" past a patch, which
; is necessary to use this technique.
; Item #1 - outer zone barrier
; so to prevent moving into the black, all we have to do is point them somewhere else
if [pcolor] of patch-ahead 1 = black [
face one-of neighbors with [pcolor = red]
]
; Item #2 - inner zone stickiness
; if we're in the outer zone and our target patch is inner zone, don't keep moving that way
; if we fail our check
if
pcolor = red ; we're in the outer zone
and [pcolor] of patch-ahead 1 = gray ; our target patch is grey
and random-float 1 < 0.8 ; our random probability to bounce off
[
; then we bounch off
face one-of neighbors with [pcolor = red]
]
; Item #3b - counting pause
; if we are paused, just decrement the pause and take no action
ifelse pause > 0 [
set pause (pause - 1)
] [
ifelse random-float 1 > 0.05 [
; 95% chance to move forward
forward 1
] [
; 5% chance to pause 5 ticks
set pause 5
]
]
]
end
您的最后一项是将海龟数据导出为 CSV 或文本。你有两个选择。您可以使用 the CSV extension or you can use BehaviorSpace 到 运行 您的模型作为“实验”。两者都会起作用。您已经在 move-turtles
过程中使用 show list xcor ycor
语句有了正确的想法,您只需要获取所有海龟的数据以输出到 CSV 或使用 BehaviorSpace 报告器:[(list who xcor ycor)] of turtles
。我包括 who
数字,这样数据更容易被 turtle track/sort。
编辑:
如评论中所述,先前版本可能会引发 运行时间错误。这个 NOBODY
错误是因为我禁用了环绕,这意味着海龟可能会面对世界边缘并执行 patch-ahead 1
which returns NOBODY
而我忘记检查它了。我会为此添加一个检查,但由于您想要可变步长版本,让我们同时添加它。
我们在使用 random-normal 10 4
时遇到的一个问题是它可以生成任意大的数字。 (顺便说一句,在我看来,每只海龟都有一个暂停也让它们每次移动了一个随机的距离,我不相信随机距离会增加太多。)如果我们想让海龟移动得更多一次多于 1 space,但我们想要保持只检查前面的补丁的相对简单的逻辑,我们可以将 forward 1
移动到一个循环中,随着我们的进行减少距离。然后,我们还必须将 bounce/sticky 检查移动到该循环中,因为我们可以从黑色的边缘向后穿过内部边界。
我还制定了一个更强大的 face-red-patch
程序来确保我们永远不会陷入困境。
你可以run the model online to test it out.
to move-turtles
ask turtles [
; `pause = 0` to keep them from spinning in place when paused
if pause = 0 and random-float 1 > 0.05 ; 5% probability of pause per tick
[
;equal chance of right or left turn
if random-float 1 > 0.50 [right random-normal 30 10]
if random-float 1 < 0.50 [left random-normal 30 10]
]
; to control turtle movement, we're going to use `patch-ahead` to check the patch color
; before moving. if turtles only move `1` at time, they cannot "skip" past a patch, which
; is necessary to use this technique.
; Item #1 - outer zone barrier
; so to prevent moving into the black, all we have to do is point them somewhere else
if patch-ahead 1 = nobody or [pcolor] of patch-ahead 1 = black [
face-red-patch
]
; Item #3 - pause
; if we are paused, just decrement the pause and take no action
ifelse pause > 0 [
set pause (pause - 1)
] [
ifelse random-float 1 > 0.05 [
; 95% chance to move forward
; Item #5 - variable length moves
let forward-amount random-normal 10 4
while [patch-ahead 1 != nobody and [pcolor] of patch-ahead 1 != black and forward-amount > 0] [
; Item #2 - inner zone stickiness
; if we're in the outer zone and our target patch is inner zone, don't keep moving that way
; if we fail our check
if
pcolor = red ; we're in the outer zone
and [pcolor] of patch-ahead 1 = gray ; our target patch is grey
and random-float 1 < 0.8 ; our random probability to bounce off
[
; then we bounce off
face-red-patch
]
forward 1
set forward-amount (forward-amount - 1)
]
] [
; 5% chance to pause 5 ticks
set pause 5
]
]
]
end
to face-red-patch
; this kind of looping code can be dangerous, but if we're careful to use it only when we know it
; will terminate it should be okay. Use Tools > Halt if you think it hit a bad state and is in an
; infinite loop
while [patch-ahead 1 = nobody or [pcolor] of patch-ahead 1 != red] [
set heading random 360
]
end