【问题标题】:Read csv file repeatedly during model run in netlogo在 netlogo 中模型运行期间重复读取 csv 文件
【发布时间】:2018-10-22 00:53:28
【问题描述】:

我在 NetLogo 中有一个模型,其中只有当变量(平均每日温度程序)达到 18 时,我的海龟才开始移动。这个变量的值来自在设置时读取的 csv 文件(参见下面的代码)。

就目前而言,模型运行的刻度数与数据点的数量相同(365 = # 天/年)。我通过指定 if file-at-end? [stop] 将模型编写为仅运行这么长时间,因为我想测试 go 过程是否有效(并且它们确实有效)。现在,我希望模型在到达文件末尾后返回数据文件中的第一个值并继续读取它。以前没有关于 StackOverflow 或 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

谢谢你的期待!

【问题讨论】:

    标签: csv arguments netlogo


    【解决方案1】:

    您可以简单地关闭并重新打开文件而不是停止:

    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 而不是set 代替temp-list:您似乎没有在update-daily-temp 的其他任何地方使用该变量,所以它应该是一个局部变量而不是一个全局变量。一般情况下,you should avoid globals if you can

    【讨论】:

    • 我根据您的建议使用了混合方法。由于我尚未探索的原因,if file-at-end? [file-close file-open ...] 命令本身不起作用。此外,由于我尚未探索的原因,我也无法弄清楚如何添加另一个变量而不会出错以将文件加载到内存中。因此,我按照您的建议尝试了使用 if 和模算术的混合方法:if ticks mod 365 = 0 [file-close file-open "temperature.csv"] 后跟 set temp-list csv:from-row file-read-line,它运行顺利!
    【解决方案2】:

    我的直觉是你应该设置一个计数器,例如:

    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
    

    这样模拟不会在年底结束,而是会持续到新的一年。

    【讨论】:

    • 您能否说明如何设置计数器?根据您的回答,我不确定如何实现这一点。换句话说,我应该将上面的ifelse 语句放在我的代码中的什么位置?我喜欢这个想法,只是不知道如何实现它。一个通用的方法会很有帮助,因为我以后可能需要一个用于这个模型的方法。
    • 我想我会将一年中的某一天 (InYearCounter) 和 Year counter 语句放在 go 函数的末尾。我编写的计数器不需要设置初始值。它们确实需要添加到全局变量列表中,因为它们需要保留在 go 函数之外,并且您不能在 NetLogo 中修改 let 变量(局部变量)。基本计数器只是将自身加 1(在本例中为年份计数器)。 ...
    • ... InYearCounter(我可能应该称之为 Day)正在通过减去当前年份之前的所有天数来修改刻度(它本身就是一个计数器),以便您从 1 中获得天数- 365。你可能需要稍微摆弄一下,我可能把 if 语句弄得有点不对劲(可能需要是 366 而不是 365)。
    • tick 应该是记号(可能会导致模拟向前移动一个时间步长(通常在 go 语句的末尾)。如果有疑问,您可以使用值 0 制作自己的 MyTicks 变量或 1 在 setup 然后在 go 语句的末尾更新它。“set MyTicks (MyTicks + 1)”。
    猜你喜欢
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    相关资源
    最近更新 更多