首页 > 解决方案 > 如何使用 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,则移动到另一半并将该特定乌龟的颜色设置为蓝色。

我希望我已经解释清楚了,谢谢大家。

标签: netlogomoveprocedure

解决方案


Jumboman 的回答解决了最实际的方面并告诉你该怎么做,但我想包括一些进一步的观点,让你了解正在发生的事情,因为它在一开始很容易解决。

问题的核心是你to go,但是,正如你所看到的,NetLogo 并没有警告你任何语法错误——因为实际上没有!这与您的问题的性质非常相关,即所有执行动作的海龟(而不仅仅是满足条件的海龟)。

为了理解原因,我们应该退后一步:您应该始终特别注意执行过程的上下文(即执行操作的代理类型)。

在 NetLogo 中,有四种类型的代理:海龟、补丁、链接和观察者。代码总是从观察者(即你)的角度编写的。这就是为什么,如果您希望其他代理做某事,您需要请这些代理做这些事情。你可以让海龟询问补丁,询问链接以要求一些海龟做事,但最终,每条链都是ask从观察者开始的。

然而,NetLogo 也会尝试猜测您希望谁来执行您的程序。在这种情况下,假设to go使用海龟自己的变量(即utility-value-free-incomecolor,后者来自内部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 goany?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:关于上下文的东西,我养成了总是写注释的习惯,在每个过程的声明旁边,指定该过程所属的上下文。这对于加快代码的可读性和某些调试特别有用,因为您的模型是由大量程序构建而成的。


推荐阅读