如何使用 NetLogo 让满足条件的海龟移动
how to make turtles who satisfy a condition move with NetLogo
我目前正在使用 NetLogo 进行一个项目。
长话短说:我有一定数量的海龟分布在我的世界的前半部分。 objective 是让海龟在满足一定条件(数学条件)的情况下移动到世界的另一半。
我遇到的问题是我只希望满足条件的海龟移动到另一半(所以我假设这将是海龟的一个子组,其尺寸将取决于“自由收入”的哪个值 I select 通过滑块),但实际上发生的情况是,如果其中至少一只满足条件,那么所有海龟都会移动。那不是我想要的。
我正在考虑使用“品种”功能,但我不确定如何实施它。
这是代码:
globals
[
lazyness-coefficient
fatigue-of-work ; cost associated with looking for work and the activity of working
free-income
working-income
]
turtles-own
[
condition ; condition = 1 if the subject works, 0 if the subject is unemployed
utility-value-working-income ; utility associated with working or being unemployed while receiving a subsidy
utility-value-free-income
]
;;;
;;;
;;;
to setup
clear-all
set free-income free-income-slider ; mettere slider
set working-income working-income-slider ; mettere slider
setup-turtles
setup-patches
reset-ticks
end
to setup-patches
ask patches [ set pcolor black]
end
to setup-turtles
create-turtles 500
[
set shape "person"
set color green
set size 1.5
set condition 0
setxy random 64 random 32
set utility-value-free-income free-income ^ 2 + free-income + random-float 1000
set utility-value-working-income 0
]
end
to go
let target any? turtles with [utility-value-free-income > 14000]
if utility-value-free-income > 14000
[move-target]
end
to move-target
setxy random 64 random 64
set color blue
end
本例中的条件如下:
如果乌龟的效用值(类型为:x^2 + x + r,其中 r 是随机因子)高于 14000,则设置颜色为蓝色并移动到另一半。
这个条件只是一个尝试,在最终的项目中条件将是:
如果自由收入效用和工作收入效用的比率高于 1,则移动到另一半并将该特定乌龟的颜色设置为蓝色。
希望我解释清楚了,谢谢大家
这是关键程序:
to go
let target any? turtles with [utility-value-free-income > 14000]
if utility-value-free-income > 14000
[move-target]
end
遍历每一行:
- 创建一个名为 'target' 的变量,并根据是否有足够高收入的海龟
为其赋值 true
或 false`
- 这应该会产生一个语法错误——假设 'utility-value-free-income' 是一个海龟属性(这是必须的,否则第 1 行没有意义),那么这一行是一个错误,因为你没有告诉 NetLogo 要查看哪只乌龟以进行 运行 测试。
- 运行如果第 2 行条件为真
,则为 'move-target' 处的代码
我通常建议新手 NetLogo 建模者避免在太多过程中破坏事物。从概念上考虑一下,您想要的是移动满足某些条件的海龟。这是一个概念,使它成为一个程序。像这样:
to go
move-rich-turtles
end
to move-rich-turtles
let movers turtles with [utility-value-free-income > 14000]
ask movers
[ setxy random 64 random 64
set color blue
]
end
你把事情搞得太复杂了。 Ask 关键字允许您指定过滤器。
to go
ask turtles with [utility-value-free-income > 14000]
[
setxy random 64 random 64
set color blue
]
end
应该可以解决问题。
Jumboman 的回答解决了最实际的方面并告诉你该怎么做,但我想包括一些更进一步的观点,让你了解正在发生的事情,因为这是很容易在 at开始。
问题的核心是您的to go
,但是,如您所见,NetLogo 没有警告您任何语法错误——因为实际上存在none!这与您的问题的性质密切相关,即所有执行该操作的海龟(而不仅仅是满足条件的海龟)。
要理解原因,我们应该退后一步:您应该始终特别注意执行过程的 上下文(即执行操作的代理类型).
In NetLogo, there are four types of agents: turtles, patches, links, and the observer. 代码总是从观察者(即你)的角度来写的。这就是为什么,如果你想让其他代理人做事情,你就需要让那些代理人做那些事情。你可以要求海龟要求补丁要求链接要求一些乌龟做事,但最终,ask
的每个链都从观察者开始。
但是,NetLogo 也会尝试猜测您希望谁执行您的程序。在这种情况下,假定 to go
使用 turtles-own 变量(即 utility-value-free-income
和 color
,后者来自 move-target
)并调用一个只能由海龟(即 move-target
中的 setxy
),NetLogo 假设 to go
属于海龟上下文。
这意味着,当执行 to go
时,每只乌龟 都会按照 to go
的指示执行。更具体地说,这意味着每只海龟都会评估 let target
语句,然后每只海龟都会执行 to move-target
.
然而,这也意味着,虽然 to go
没有给出任何语法错误,但您应该首先注意到其他奇怪的事情。作为目前 to go
仅 turtle 的过程,您应该看到,如果您在界面中添加 go
按钮(这是标准做法),您将收到错误消息。实际上,界面是仅限观察者的上下文(因此默认情况下按钮是观察者上下文,即除非您不手动更改它们的上下文)。您也会在命令中心中输入 go
时出错(默认情况下也是仅观察者上下文)以及尝试在 setup
.
中插入 go
这将通过创建 to go
观察者上下文来解决,即从观察者上下文的任何地方调用它 + 使用 ask turtles
,如 Jumboman 所示。
Jumboman 的回答中隐含但您需要明确理解的另一件事是 to go
中的实际代码行有什么问题。
JenB 暗示了 any?
的问题:
您显然打算创建一个名为 target
的代理集;然而,any? 只报告过 true/false。这意味着,正如 JenB 所说,target
不会存储任何代理集,而只会存储一个 true/false 值。
然而,无论如何,您的代码创建了这个 target
变量但从未真正使用过它,这仍然是一个事实。事实上,您在过程名称中包含“target”一词 (move-target
) 并不会使该过程自动使用名为 target
的变量。因此,即使 target
是一个代理集,move-target
也不会自动引用 target
(就此而言,您可以给这两个元素完全随机的名称并且它本来是相同的).
要这样做,您必须
to move-target
ask target ...
end
但是,正如您已经被建议的那样,with
是完成这项工作的最简洁方法。
总的来说,以上所有这些事情的总和就是你应该这样做的原因:
to go
ask turtles with [utility-value-free-income > 14000] [
setxy random 64 random 64
set color blue
]
end
PS:至于上下文的东西,我养成了一个习惯,总是在每个过程的声明旁边写一个注释,指定这个过程所属的上下文。这对于加快代码的可读性和一些调试特别有用,因为您的模型建立了很多过程。
我目前正在使用 NetLogo 进行一个项目。 长话短说:我有一定数量的海龟分布在我的世界的前半部分。 objective 是让海龟在满足一定条件(数学条件)的情况下移动到世界的另一半。 我遇到的问题是我只希望满足条件的海龟移动到另一半(所以我假设这将是海龟的一个子组,其尺寸将取决于“自由收入”的哪个值 I select 通过滑块),但实际上发生的情况是,如果其中至少一只满足条件,那么所有海龟都会移动。那不是我想要的。 我正在考虑使用“品种”功能,但我不确定如何实施它。 这是代码:
globals
[
lazyness-coefficient
fatigue-of-work ; cost associated with looking for work and the activity of working
free-income
working-income
]
turtles-own
[
condition ; condition = 1 if the subject works, 0 if the subject is unemployed
utility-value-working-income ; utility associated with working or being unemployed while receiving a subsidy
utility-value-free-income
]
;;;
;;;
;;;
to setup
clear-all
set free-income free-income-slider ; mettere slider
set working-income working-income-slider ; mettere slider
setup-turtles
setup-patches
reset-ticks
end
to setup-patches
ask patches [ set pcolor black]
end
to setup-turtles
create-turtles 500
[
set shape "person"
set color green
set size 1.5
set condition 0
setxy random 64 random 32
set utility-value-free-income free-income ^ 2 + free-income + random-float 1000
set utility-value-working-income 0
]
end
to go
let target any? turtles with [utility-value-free-income > 14000]
if utility-value-free-income > 14000
[move-target]
end
to move-target
setxy random 64 random 64
set color blue
end
本例中的条件如下: 如果乌龟的效用值(类型为:x^2 + x + r,其中 r 是随机因子)高于 14000,则设置颜色为蓝色并移动到另一半。 这个条件只是一个尝试,在最终的项目中条件将是: 如果自由收入效用和工作收入效用的比率高于 1,则移动到另一半并将该特定乌龟的颜色设置为蓝色。
希望我解释清楚了,谢谢大家
这是关键程序:
to go
let target any? turtles with [utility-value-free-income > 14000]
if utility-value-free-income > 14000
[move-target]
end
遍历每一行:
- 创建一个名为 'target' 的变量,并根据是否有足够高收入的海龟 为其赋值
- 这应该会产生一个语法错误——假设 'utility-value-free-income' 是一个海龟属性(这是必须的,否则第 1 行没有意义),那么这一行是一个错误,因为你没有告诉 NetLogo 要查看哪只乌龟以进行 运行 测试。
- 运行如果第 2 行条件为真 ,则为 'move-target' 处的代码
true
或 false`
我通常建议新手 NetLogo 建模者避免在太多过程中破坏事物。从概念上考虑一下,您想要的是移动满足某些条件的海龟。这是一个概念,使它成为一个程序。像这样:
to go
move-rich-turtles
end
to move-rich-turtles
let movers turtles with [utility-value-free-income > 14000]
ask movers
[ setxy random 64 random 64
set color blue
]
end
你把事情搞得太复杂了。 Ask 关键字允许您指定过滤器。
to go
ask turtles with [utility-value-free-income > 14000]
[
setxy random 64 random 64
set color blue
]
end
应该可以解决问题。
Jumboman 的回答解决了最实际的方面并告诉你该怎么做,但我想包括一些更进一步的观点,让你了解正在发生的事情,因为这是很容易在 at开始。
问题的核心是您的to go
,但是,如您所见,NetLogo 没有警告您任何语法错误——因为实际上存在none!这与您的问题的性质密切相关,即所有执行该操作的海龟(而不仅仅是满足条件的海龟)。
要理解原因,我们应该退后一步:您应该始终特别注意执行过程的 上下文(即执行操作的代理类型).
In NetLogo, there are four types of agents: turtles, patches, links, and the observer. 代码总是从观察者(即你)的角度来写的。这就是为什么,如果你想让其他代理人做事情,你就需要让那些代理人做那些事情。你可以要求海龟要求补丁要求链接要求一些乌龟做事,但最终,ask
的每个链都从观察者开始。
但是,NetLogo 也会尝试猜测您希望谁执行您的程序。在这种情况下,假定 to go
使用 turtles-own 变量(即 utility-value-free-income
和 color
,后者来自 move-target
)并调用一个只能由海龟(即 move-target
中的 setxy
),NetLogo 假设 to go
属于海龟上下文。
这意味着,当执行 to go
时,每只乌龟 都会按照 to go
的指示执行。更具体地说,这意味着每只海龟都会评估 let target
语句,然后每只海龟都会执行 to move-target
.
然而,这也意味着,虽然 to go
没有给出任何语法错误,但您应该首先注意到其他奇怪的事情。作为目前 to go
仅 turtle 的过程,您应该看到,如果您在界面中添加 go
按钮(这是标准做法),您将收到错误消息。实际上,界面是仅限观察者的上下文(因此默认情况下按钮是观察者上下文,即除非您不手动更改它们的上下文)。您也会在命令中心中输入 go
时出错(默认情况下也是仅观察者上下文)以及尝试在 setup
.
go
这将通过创建 to go
观察者上下文来解决,即从观察者上下文的任何地方调用它 + 使用 ask turtles
,如 Jumboman 所示。
Jumboman 的回答中隐含但您需要明确理解的另一件事是 to go
中的实际代码行有什么问题。
JenB 暗示了 any?
的问题:
您显然打算创建一个名为 target
的代理集;然而,any? 只报告过 true/false。这意味着,正如 JenB 所说,target
不会存储任何代理集,而只会存储一个 true/false 值。
然而,无论如何,您的代码创建了这个 target
变量但从未真正使用过它,这仍然是一个事实。事实上,您在过程名称中包含“target”一词 (move-target
) 并不会使该过程自动使用名为 target
的变量。因此,即使 target
是一个代理集,move-target
也不会自动引用 target
(就此而言,您可以给这两个元素完全随机的名称并且它本来是相同的).
要这样做,您必须
to move-target
ask target ...
end
但是,正如您已经被建议的那样,with
是完成这项工作的最简洁方法。
总的来说,以上所有这些事情的总和就是你应该这样做的原因:
to go
ask turtles with [utility-value-free-income > 14000] [
setxy random 64 random 64
set color blue
]
end
PS:至于上下文的东西,我养成了一个习惯,总是在每个过程的声明旁边写一个注释,指定这个过程所属的上下文。这对于加快代码的可读性和一些调试特别有用,因为您的模型建立了很多过程。