在 netlogo 模型 运行 期间重复读取 csv 文件
Read csv file repeatedly during model run in netlogo
我在 NetLogo 中有一个模型,其中我的海龟仅在变量(平均每日温度程序)达到 18 时才开始移动。此变量的值来自在设置时读入的 csv 文件(请参阅下面的代码)。
就目前而言,模型 运行 的刻度数与数据点数相同(365 = 每年 # 天)。我通过指定 if file-at-end? [stop]
将模型写到 运行 这么长,因为我想测试 go 过程是否有效(它们确实有效)。现在,我希望模型 return 到数据文件中的第一个值,并在到达文件末尾后继续读取它。以前没有关于 Whosebug 或 NetLogo 的 google 组的问题,尽管对关键字进行了广泛的谷歌搜索,但 NetLogo 原语或过程已经产生了令人满意的解决方案。可能我没看懂。
我可以用什么替换 [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
谢谢期待!
您可以简单地关闭并重新打开您的文件而不是停止:
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
注意我用了let
instead of set
for temp-list
: you don't seem to be using that variable anywhere else then in update-daily-temp
, so it should really be a local variable instead of a global variable. In general, you should avoid globals if you can.
我的直觉是你应该设置一个计数器,例如:
ifelse tick <= 365[
set InYearCounter tick
set Year 1
]
[
set InYearCounter (tick - (Year * 365))
if InYearCounter = 365[
set Year (Year + 1)
]
]
然后使用 "InYearCounter".
在 csv table 中获取行
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
这样模拟不会在年底结束,而是会延续到新的一年。
我在 NetLogo 中有一个模型,其中我的海龟仅在变量(平均每日温度程序)达到 18 时才开始移动。此变量的值来自在设置时读入的 csv 文件(请参阅下面的代码)。
就目前而言,模型 运行 的刻度数与数据点数相同(365 = 每年 # 天)。我通过指定 if file-at-end? [stop]
将模型写到 运行 这么长,因为我想测试 go 过程是否有效(它们确实有效)。现在,我希望模型 return 到数据文件中的第一个值,并在到达文件末尾后继续读取它。以前没有关于 Whosebug 或 NetLogo 的 google 组的问题,尽管对关键字进行了广泛的谷歌搜索,但 NetLogo 原语或过程已经产生了令人满意的解决方案。可能我没看懂。
我可以用什么替换 [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
谢谢期待!
您可以简单地关闭并重新打开您的文件而不是停止:
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
注意我用了let
instead of set
for temp-list
: you don't seem to be using that variable anywhere else then in update-daily-temp
, so it should really be a local variable instead of a global variable. In general, you should avoid globals if you can.
我的直觉是你应该设置一个计数器,例如:
ifelse tick <= 365[
set InYearCounter tick
set Year 1
]
[
set InYearCounter (tick - (Year * 365))
if InYearCounter = 365[
set Year (Year + 1)
]
]
然后使用 "InYearCounter".
在 csv table 中获取行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
这样模拟不会在年底结束,而是会延续到新的一年。