我在NetLogo中有一个模型,仅当变量(平均温度过程)达到18时,海龟才开始移动。此变量的值来自于在安装程序中读取的csv文件(请参见下面的代码) )。
按现状,该模型运行的滴答声数量与数据点相同(365 =每年#天)。我编写模型仅通过指定if file-at-end? [stop]
来运行很长时间,因为我想测试go过程是否有效(并且确实如此)。现在,我希望模型在到达文件末尾后返回到数据文件中的第一个值并继续读取它。尽管对关键字,NetLogo原语或过程进行了广泛的搜索,但有关StackOverflow或NetLogo的google组的先前问题都没有,但已经提出了令人满意的解决方案。可能我可能还不了解它们。
要实现此目标,我可以替换[stop]
些什么?还是需要其他更改?
我可以延长数据文件的长度,但是我觉得我想使用的方法可能更简单或更优雅。
我的代码:
`extensions
[array
csv]
globals[
river-patches ;;; water where the fish live
bank-patches ;;; patches were the fish cannot go
initial-temp ;;; temperature set at tick 0
temp-list ;;; variable containing temperature from .csv file
mintemp ;;; minimum temperature possible on any river-patch
maxtemp] ;;; maximum temperature possible on any river-patch
patches-own
[mean-daily-temp] ;;; variable for patch temperature
to setup
clear-all
file-close-all ;;; close any files
file-open "temperature.csv" ;;; contains the data for minimum and
maximum temperatures possible in each
tick
setup-constants ;;; set up constants
setup-river-patches ;;; set up river-patches
setup-bank-patches ;;; set up patches not in the river
setup-turtles ;;; set up turtles
reset-ticks ;;; set ticks to 0
end
to setup-constants
set initial-temp (22.06) ;;; initial temperature for each patch
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;; SETUP PATCHES ;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; creates patches that make up the river
to setup-river-patches
set river-patches patches with [pycor > -27 and pycor < 27]
ask river-patches
[set pcolor blue
set mean-daily-temp (initial-temp)]
;;; creates bank patches that are green
set bank-patches patches with [pycor <= -27 or pycor >= 27]
ask bank-patches
[set pcolor green]
end
;;; creates the 'fish' turtles
to setup-turtles
create-turtles 20
ask turtles [
set color white
set shape "fish"
set size 1
move-to one-of river-patches]
end
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;; TO GO ;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
to go
update-daily-temp ;;; this reads data from csv and creates the
'mintemp' and 'maxtemp' variables used in
'daily-river-temp'
daily-river-temp ;;; in each tick, this procedures sets the
individual patch temperature
move-turtles ;;; procedure asking turtles to move in response to
temperature
tick
end
;;;;;; HOW DO I ASK THE PROCEDURE update-daily-temp TO RETURN TO
;;;;;; START OF FILE, AFTER REACHING FINAL DATA POINT
;;;;;; SO THE MODEL CAN RUN FOR MORE TICKS THAN THERE
;;;;;; ARE DATA POINTS IN THE FILE? (i.e. UNTIL I CLICK GO AGAIN)
to update-daily-temp
if file-at-end? [stop]
set temp-list csv:from-row file-read-line
set mintemp item 0 temp-list
set maxtemp item 1 temp-list
end
to daily-river-temp ;;; in each tick, set the individual patch
;;; temperature
ask patches[
set mean-daily-temp random-float (maxtemp - mintemp) + mintemp
]
end
to move-turtles
ask turtles
[ifelse [mean-daily-temp] of patch-here > 18 and [pcolor] of patch
ahead 1 = blue
[forward 1 set heading random 360 ]
[set heading random 180]
if xcor > 119 and xcor < 119
[set heading random 360] pen-down]
end
谢谢您!
答案 0 :(得分:2)
您可以简单地关闭并重新打开文件,而不必停止:
if file-at-end? [
file-close
file-open "temperature.csv"
]
另一种方法是使用csv:from-file
将整个文件加载到内存中,然后使用模算术访问当天的温度。假设您将整个文件内容存储在temperatures
变量中,那么您的update-daily-temp
过程将变为:
to update-daily-temp
let temp-list item (ticks mod 365) temperatures
set mintemp item 0 temp-list
set maxtemp item 1 temp-list
end
请注意,我为temp-list
使用了let
而不是set
:除了update-daily-temp
之外,您似乎没有在其他任何地方使用该变量,因此应该实际上是局部变量而不是全局变量。通常,you should avoid globals if you can。
答案 1 :(得分:0)
我的直觉是您应该设置一个计数器,例如:
ifelse tick <= 365[
set InYearCounter tick
set Year 1
]
[
set InYearCounter (tick - (Year * 365))
if InYearCounter = 365[
set Year (Year + 1)
]
]
然后使用“ InYearCounter”在csv表中获取该行。
to setup
set temp-table csv:from-file "temperature.csv"
end
to update-daily-temp
set temp-list item InYearCounter temp-table
set mintemp item 0 temp-list
set maxtemp item 1 temp-list
end
这样,模拟不会在一年结束时结束,而是会持续到新的一年。