Netlogo:如何让一只乌龟朝着一个独特的补丁目标移动?
Netlogo: How to make a turtle move towards an unique patch target?
我有乌龟(病人),每只只能用一张床(白斑)。由于患者是在候诊室中随机生成的(绿色补丁),有时他们中的两个或更多人会到达相同的距离,因此他们会找到与目标相同的补丁。我试图向贴片添加一个属性,目的是将特定床位分配给特定患者。这个想法是这样的(请沉迷于丑陋的代码,我正在学习:P):
globals [
waitxmax
waitxmin
waitymax
waitymin
box
]
breed [ patients patient ]
patients-own [ target ]
patches-own [ assigned ]
to setup-wait-room
set waitxmax -15
set waitxmin 15
set waitymax 11
set waitymin 15
ask patches with [
pxcor >= waitxmax and
pxcor <= waitxmin and
pycor >= waitymax and
pycor <= waitymin
] [ set pcolor green ]
end
to setup-beds
let cmy 7
let cmx 15
let dst 3
let nbox 7
ask patch cmx cmy [ set pcolor white ]
let i 1
while [ i < nbox ] [
ask patch (cmx - dst) cmy [ set pcolor white ]
set i i + 1
set cmx cmx - dst
]
ask patches with [ pcolor = white ] [ set assigned false ]
set box patches with [ pcolor = white ]
end
to setup-patients
create-patients start-patients [
set shape "person"
set target nobody
move-to one-of patches with [ pcolor = green ] ]
end
to setup [
clear-all
setup-wait-room
setup-beds
reset-ticks
]
to go
ask patients [ go-to-bed ]
tick
end
to go-to-bed
let _p box with [ self != [ patch-here ] of myself ]
if target = nobody [
set target min-one-of _p [ distance myself ]
ask target [ set assigned myself ]
]
;;; FIXME
if ([ assigned ] of target) != self [ show "not true" ]
if target != nobody [
face target
fd 1
]
end
当我在 FIXME 下面打印比较的两侧时,从命令中心我实际上得到了预期的结果。例如:患者 0 和患者 1 都具有相同的 target
(补丁 -3 7),但该补丁是 assigned
到(患者 0)。我本以为比较会迫使患者 1 获得新目标,因为床上没有他的名字(我还没有编写该代码),但它总是评估为真。这更臭名昭著,因为我增加了更多可用床位的患者(如果没有可用床位,他们应该在有空位时立即等待)。
通过界面检查时,我还看到补丁 -3 7 显示(患者 0),所以我不知道发生了什么。指挥中心示例:
observer> show [ assigned ] of patch -3 7
observer: (patient 0)
observer> if ([ assigned ] of patch -3 7) = [self] of patient 0 [ show "true" ]
observer: "true"
observer> if ([ assigned ] of patch -3 7) = [self] of patient 1 [ show "true" ]
;;;; SETUP AND GO
(patient 0): (patch -3 7)
(patient 0): (patient 0)
(patient 0): "true"
(patient 2): (patch 12 7)
(patient 2): (patient 2)
(patient 2): "true"
(patient 1): (patch -3 7)
(patient 1): (patient 1)
(patient 1): "true"
也许我只是想多了,有一种更简单的方法可以为病人分配床位,反之亦然?
上面的代码中似乎缺少一两个块(我不能 copy-paste 和 运行),所以请查看下面的选项。
这个版本的工作原理是在 turtle 变量中有一个地方存储 'claimed' 个床位。由于海龟变量可以使用 of
作为列表查询,bed-less 海龟可以检查是否有任何床不在该列表中,如果有,则声明一个。
turtles-own [ owned-bed ]
to setup
ca
ask n-of 5 patches [
set pcolor green
]
crt 10 [
set owned-bed nobody
claim-unclaimed-bed
if owned-bed != nobody [
print word "I own the bed " owned-bed
]
]
reset-ticks
end
to claim-unclaimed-bed
; If I have no bed
if owned-bed = nobody [
; Pull the current owned beds for comparison
let all-owned-beds [owned-bed] of turtles
; Pull those beds that are green AND are not found in 'all-owned-beds'
let available-beds patches with [
pcolor = green and not member? self all-owned-beds
]
; If there are any beds available, claim one
ifelse any? available-beds [
set owned-bed one-of available-beds
] [
; If there are none available, print so
print "There are no available beds."
]
]
end
编辑: 忘记了实际的问题标题 - 在上面的示例中实际移动到他们的 owned-bed
(如果他们有的话),他们只是 face
它并移动你喜欢的方式-例如:
to go
ask turtles with [ owned-bed != nobody ] [
ifelse distance owned-bed > 1 [
face owned-bed
fd 1
] [
move-to owned-bed
]
]
tick
end
编辑:增加了复杂性
好的,对于 severity
的添加元素,您可能希望避免使用多个 with [ ... = x
语句,而是使用一个名为 min-one-of
的原语 returns 具有某些报告者最小值的代理。然后,你想告诉 NetLogo 继续询问下一个最严重的和下一个最严重的,等等。一种方法是使用 while
循环,它基本上说“当满足这个条件时,继续评估以下代码。” 小心 和 while
循环 - 如果您忘记编写代码,最终条件不再是 true
,while
循环将只是继续 运行ning 直到你最终将工具 > 停止你的模型(或者,就像我遇到的大型模型一样,NetLogo 崩溃)。
我修改了代码(上面的大部分内容没有改变)以包含这样一个 while
循环。还要注意的是,由于模型需要多次检查哪些床可用,我将该代码制作成 to-report
块以压缩/简化。
turtles-own [ owned-bed severity ]
to setup
ca
ask n-of 5 patches [
set pcolor green
]
crt 10 [
set owned-bed nobody
set severity random-float 10
]
let current-available-beds report-available-beds
while [any? current-available-beds] [
; From the turtles with no bed, ask the one with the lowest severity number to
; claim an unclaimed bed. Then, reset the current-available-beds
ask min-one-of ( turtles with [owned-bed = nobody] ) [ severity ] [
claim-unclaimed-bed
if owned-bed != nobody [
show ( word "I have a severity of " severity " so I am claiming the bed " owned-bed )
]
]
set current-available-beds report-available-beds
]
reset-ticks
end
to-report report-available-beds
let all-owned-beds [owned-bed] of turtles
report patches with [
pcolor = green and not member? self all-owned-beds
]
end
to claim-unclaimed-bed
; If I have no bed
if owned-bed = nobody [
let available-beds report-available-beds
; If there are any beds available, claim one
ifelse any? available-beds [
set owned-bed one-of available-beds
] [
; If there are none available, print so
print "There are no available beds."
]
]
end
我有乌龟(病人),每只只能用一张床(白斑)。由于患者是在候诊室中随机生成的(绿色补丁),有时他们中的两个或更多人会到达相同的距离,因此他们会找到与目标相同的补丁。我试图向贴片添加一个属性,目的是将特定床位分配给特定患者。这个想法是这样的(请沉迷于丑陋的代码,我正在学习:P):
globals [
waitxmax
waitxmin
waitymax
waitymin
box
]
breed [ patients patient ]
patients-own [ target ]
patches-own [ assigned ]
to setup-wait-room
set waitxmax -15
set waitxmin 15
set waitymax 11
set waitymin 15
ask patches with [
pxcor >= waitxmax and
pxcor <= waitxmin and
pycor >= waitymax and
pycor <= waitymin
] [ set pcolor green ]
end
to setup-beds
let cmy 7
let cmx 15
let dst 3
let nbox 7
ask patch cmx cmy [ set pcolor white ]
let i 1
while [ i < nbox ] [
ask patch (cmx - dst) cmy [ set pcolor white ]
set i i + 1
set cmx cmx - dst
]
ask patches with [ pcolor = white ] [ set assigned false ]
set box patches with [ pcolor = white ]
end
to setup-patients
create-patients start-patients [
set shape "person"
set target nobody
move-to one-of patches with [ pcolor = green ] ]
end
to setup [
clear-all
setup-wait-room
setup-beds
reset-ticks
]
to go
ask patients [ go-to-bed ]
tick
end
to go-to-bed
let _p box with [ self != [ patch-here ] of myself ]
if target = nobody [
set target min-one-of _p [ distance myself ]
ask target [ set assigned myself ]
]
;;; FIXME
if ([ assigned ] of target) != self [ show "not true" ]
if target != nobody [
face target
fd 1
]
end
当我在 FIXME 下面打印比较的两侧时,从命令中心我实际上得到了预期的结果。例如:患者 0 和患者 1 都具有相同的 target
(补丁 -3 7),但该补丁是 assigned
到(患者 0)。我本以为比较会迫使患者 1 获得新目标,因为床上没有他的名字(我还没有编写该代码),但它总是评估为真。这更臭名昭著,因为我增加了更多可用床位的患者(如果没有可用床位,他们应该在有空位时立即等待)。
通过界面检查时,我还看到补丁 -3 7 显示(患者 0),所以我不知道发生了什么。指挥中心示例:
observer> show [ assigned ] of patch -3 7
observer: (patient 0)
observer> if ([ assigned ] of patch -3 7) = [self] of patient 0 [ show "true" ]
observer: "true"
observer> if ([ assigned ] of patch -3 7) = [self] of patient 1 [ show "true" ]
;;;; SETUP AND GO
(patient 0): (patch -3 7)
(patient 0): (patient 0)
(patient 0): "true"
(patient 2): (patch 12 7)
(patient 2): (patient 2)
(patient 2): "true"
(patient 1): (patch -3 7)
(patient 1): (patient 1)
(patient 1): "true"
也许我只是想多了,有一种更简单的方法可以为病人分配床位,反之亦然?
上面的代码中似乎缺少一两个块(我不能 copy-paste 和 运行),所以请查看下面的选项。
这个版本的工作原理是在 turtle 变量中有一个地方存储 'claimed' 个床位。由于海龟变量可以使用 of
作为列表查询,bed-less 海龟可以检查是否有任何床不在该列表中,如果有,则声明一个。
turtles-own [ owned-bed ]
to setup
ca
ask n-of 5 patches [
set pcolor green
]
crt 10 [
set owned-bed nobody
claim-unclaimed-bed
if owned-bed != nobody [
print word "I own the bed " owned-bed
]
]
reset-ticks
end
to claim-unclaimed-bed
; If I have no bed
if owned-bed = nobody [
; Pull the current owned beds for comparison
let all-owned-beds [owned-bed] of turtles
; Pull those beds that are green AND are not found in 'all-owned-beds'
let available-beds patches with [
pcolor = green and not member? self all-owned-beds
]
; If there are any beds available, claim one
ifelse any? available-beds [
set owned-bed one-of available-beds
] [
; If there are none available, print so
print "There are no available beds."
]
]
end
编辑: 忘记了实际的问题标题 - 在上面的示例中实际移动到他们的 owned-bed
(如果他们有的话),他们只是 face
它并移动你喜欢的方式-例如:
to go
ask turtles with [ owned-bed != nobody ] [
ifelse distance owned-bed > 1 [
face owned-bed
fd 1
] [
move-to owned-bed
]
]
tick
end
编辑:增加了复杂性
好的,对于 severity
的添加元素,您可能希望避免使用多个 with [ ... = x
语句,而是使用一个名为 min-one-of
的原语 returns 具有某些报告者最小值的代理。然后,你想告诉 NetLogo 继续询问下一个最严重的和下一个最严重的,等等。一种方法是使用 while
循环,它基本上说“当满足这个条件时,继续评估以下代码。” 小心 和 while
循环 - 如果您忘记编写代码,最终条件不再是 true
,while
循环将只是继续 运行ning 直到你最终将工具 > 停止你的模型(或者,就像我遇到的大型模型一样,NetLogo 崩溃)。
我修改了代码(上面的大部分内容没有改变)以包含这样一个 while
循环。还要注意的是,由于模型需要多次检查哪些床可用,我将该代码制作成 to-report
块以压缩/简化。
turtles-own [ owned-bed severity ]
to setup
ca
ask n-of 5 patches [
set pcolor green
]
crt 10 [
set owned-bed nobody
set severity random-float 10
]
let current-available-beds report-available-beds
while [any? current-available-beds] [
; From the turtles with no bed, ask the one with the lowest severity number to
; claim an unclaimed bed. Then, reset the current-available-beds
ask min-one-of ( turtles with [owned-bed = nobody] ) [ severity ] [
claim-unclaimed-bed
if owned-bed != nobody [
show ( word "I have a severity of " severity " so I am claiming the bed " owned-bed )
]
]
set current-available-beds report-available-beds
]
reset-ticks
end
to-report report-available-beds
let all-owned-beds [owned-bed] of turtles
report patches with [
pcolor = green and not member? self all-owned-beds
]
end
to claim-unclaimed-bed
; If I have no bed
if owned-bed = nobody [
let available-beds report-available-beds
; If there are any beds available, claim one
ifelse any? available-beds [
set owned-bed one-of available-beds
] [
; If there are none available, print so
print "There are no available beds."
]
]
end