netlogo - 如何使用 NetLogo 使满足条件的海龟移动
问题描述
我目前正在使用 NetLogo 进行一个项目。长话短说:我有一定数量的海龟分布在我世界的前半部分。目标是让海龟在满足特定条件(数学条件)的情况下移动到世界的另一半。我遇到的问题是我只希望满足条件的海龟移动到另一半(所以我假设这将是海龟的一个子组,其维度将取决于我选择的“自由收入”的哪个值滑块),但实际上发生的是,如果其中至少一个满足条件,那么所有海龟都会移动。那不是我想要的。我正在考虑使用“品种”功能,但我不知道如何实现它。这是代码:
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,则移动到另一半并将该特定乌龟的颜色设置为蓝色。
我希望我已经解释清楚了,谢谢大家。
解决方案
Jumboman 的回答解决了最实际的方面并告诉你该怎么做,但我想包括一些进一步的观点,让你了解正在发生的事情,因为它在一开始很容易解决。
问题的核心是你to go
,但是,正如你所看到的,NetLogo 并没有警告你任何语法错误——因为实际上没有!这与您的问题的性质非常相关,即所有执行动作的海龟(而不仅仅是满足条件的海龟)。
为了理解原因,我们应该退后一步:您应该始终特别注意执行过程的上下文(即执行操作的代理类型)。
在 NetLogo 中,有四种类型的代理:海龟、补丁、链接和观察者。代码总是从观察者(即你)的角度编写的。这就是为什么,如果您希望其他代理做某事,您需要请这些代理做这些事情。你可以让海龟询问补丁,询问链接以要求一些海龟做事,但最终,每条链都是ask
从观察者开始的。
然而,NetLogo 也会尝试猜测您希望谁来执行您的程序。在这种情况下,假设to go
使用海龟自己的变量(即utility-value-free-income
和color
,后者来自内部move-target
)并调用只能由海龟使用的原语(即setxy
来自内部move-target
),NetLogo 假设to go
属于海龟上下文。
这意味着,在表演时to go
,每只乌龟都会按照自己to go
说的去做。更具体地说,这意味着每只乌龟都会评估let target
语句,然后每只乌龟都会执行to move-target
。
然而,这也意味着,虽然to go
没有给出任何语法错误,但您可能首先应该注意到其他一些奇怪的事情。到目前为止,作为to go
一个仅限海龟的程序,您应该看到,如果您go
在界面中添加一个按钮(这是标准做法),您将收到一个错误。实际上,界面是仅观察者上下文(因此按钮默认为观察者上下文,即除非您不手动更改它们的上下文)。您也会在命令中心输入错误(默认情况下也只有观察者上下文)go
以及尝试插入go
.setup
这将通过制作to go
观察者上下文来解决,即通过从观察者上下文的任何地方调用它 + 使用ask turtles
如 Jumboman 所示。
Jumboman 的答案中隐含但您需要明确理解的另一件事是内部的实际代码行有什么问题to go
。any?
JenB 暗示了这个问题:
您显然有意创建一个名为target
; 但是,有吗?只报告真/假。这意味着,正如 JenB 所说,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:关于上下文的东西,我养成了总是写注释的习惯,在每个过程的声明旁边,指定该过程所属的上下文。这对于加快代码的可读性和某些调试特别有用,因为您的模型是由大量程序构建而成的。
推荐阅读
- javascript - 弧线笔划线弹出后的画布
- css - 覆盖 CSS 规则类:悬停以使用类中的原始规则值
- pandasql - 当我添加分析函数时,Pandasql 不起作用
- docker - 损坏的 DAG:[/usr/local/airflow/dags/test.py] 没有名为“boto3”的模块。如何将 pip 安装到气流容器中?
- puppet - 如何在木偶清单中懒惰地定义一个类
- c++ - 尝试释放内存时 gSOAP 多线程服务器崩溃
- codeigniter - Codeigniter 从数据库数组中一张一张地分页图像
- azure - 通过 Azure Pipeline 从 GitHub 将 python 脚本部署到虚拟机
- javascript - 如何根据Vue中的条件正确禁用按钮
- qt - 如何在 QML 中使用 MenuBar.insertMenu 方法?