首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Net徽标中使用列表中的列表值

如何在Net徽标中使用列表中的列表值
EN

Stack Overflow用户
提问于 2022-04-07 08:46:37
回答 1查看 390关注 0票数 1

当我建立我的模型时,我还上传了一个包含多个列的csv文件,经过一些研究后,我发现它被读取为一个列表列表(每一行都是一个列表)。

代码语言:javascript
复制
set yield-data sentence yield-data (list (list file-read file-read file-read file-read file-read))

当我运行模型(土地使用模型)时,对于每个补丁,必须在一个简单的算法中使用列表列表中的一个值(上面是yield-data),该算法将定义其下一个土地使用类别。我还没有到那里,我的第一个目标是找出如何在my-list中查找值。

请参阅下面的可复制代码,它使用my-list而不是yield-data,除了我为之奋斗的过程to test。我对面向对象的建模还不熟悉.

代码语言:javascript
复制
globals [
  my-list
  my-rd-list
]

patches-own [
  year
  varA
  varB
  temp-varC
]

to setup
  ;; here I just create patches with different values that also appear in the list
  ca
  resize-world 9 * 0 ( 9 * 1 )  ( 9 * -1 ) 9 * 0 
  set my-list [[2015 3 2 8] [2016 5 1 10] [2017 7 0 12]] 
  ask patches with [pxcor < 3] [set year 2015] 
  ask patches with [pxcor > 3] [ set year 2016]
  ask patches with [pxcor > 6] [ set year 2017]
  ask patches with [pycor > -3] [ set varA 3] 
  ask patches with [pycor < -3] [ set varA 5]
  ask patches with [pycor < -6] [set varA 7]
  ask patches [set varB random 3]
end

to test
;; need to add a "while n <= number of list inside the list"
let n 1
  foreach item n my-list [
    x ->
   ask patches with [year = item 0 item n my-list and varA = item 1 item n my-list and varB = item 2 item n my-list] [set pcolor orange set temp-varC item 3 item n my-list] 
    set n n + 1
  ]
end

这样做的想法是,对于每个列表(例如,2015 3 2 8,列表的最后一个值用来对补丁程序进行小的计算,该修补程序修补了具有年份= 2015、varA= 3和varB=2的标准,我认为将其作为临时变量存储在修补程序中会更容易。)由于理解了更好的列表是如何工作的,代码现在开始工作了。然而,

1)然而,我忽略了如何计算主列表中有多少个列表,或者我在开头提到的原始txt文件中有多少行。

( item 1 item n my-list**,2)我希望varA在里面,比方说,-1 /+1在的值附近,类似于这里-下面的那个不起作用**

ask patches with [year = item 0 item n my-list and varA < item 1 + 1 (item n my-list) and varA > item 1 - 1 (item n my-list) and varB = item 2 item n my-list] [set pcolor orange set temp-varC item 3 item n my-list]

那么,我有一个“基本”问题:当一个补丁将被检查时,他的temp-varC varA 会更新,varA也会根据 my-list 中的值进行更新:对于 temp-varC 的下一次更新,该修补程序在循环中还能保持良好状态吗?因为varA会改变,所以"items“的组合会发生变化,并且它可以有一个更新的(但我不想那样!)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-07 16:44:14

关于如何计算my-list中有多少列表

每个内部列表只是my-lists的一个项目,因此length my-lists会告诉您有多少内部列表。

关于varA周围的区间

这只需要你设计一个反映你想要的东西的算术条件。我想至少有几种方法可以做到。

例如,对于要应用此间隔的条件,而不是具有以下内容:

代码语言:javascript
复制
varA = item 1 some-list

你本可以:

代码语言:javascript
复制
abs (varA - item 1 some-list) <= 1

使用while的方法

让我首先给您一个使用while的解决方案,因为这是您处理问题的方式,也是因为澄清如何在此上下文中处理列表是有用的。在此之后,使用filter的方法更加简洁。

使用while方法,您不需要foreach,因为foreach 对列表中的每一项运行一个命令。。在您使用foreach的示例中,您告诉匿名过程将my-list的每一项(即每个内部列表)一次存储为x,并为每个x运行一些命令。但是,您从不在这样的命令中处理x,这证明了foreach是超级的。

这意味着,使用上面关于列表长度和条件下的间隔的两条信息,您可以通过以下操作实现您的目标:

代码语言:javascript
复制
to test
  ask patches [
    let i 0
    while [i < length my-list] [
      let current-inner-list item i my-list
      ifelse ((year = item 0 current-inner-list) AND (abs (varA - item 1 current-inner-list) <= 1) AND (varB = item 2 current-inner-list))
        [set temp-varC item 3 current-inner-list
         stop]
        [set i i + 1]
    ]
  ]
end

这样,循环将检查内部列表,直到找到正确的列表,然后设置temp-varC,然后执行stop,以便循环结束而不必遍历所有my-list

注意,单个布尔值周围的括号是可选的,我使用它们是为了提高可读性。

使用filter的方法

一种更简洁的方法使用filter这个原始以一个记者和一个列表作为参数,并返回( NetLogo jargoon中的reports)一个列表,该列表只包含来自最初列表中的项目,而记者对原始列表的计算结果为TRUE

就您的情况而言,这意味着您可以:

代码语言:javascript
复制
to test
  ask patches [
    set temp-varC last (first (filter [current-inner-list -> (item 0 current-inner-list = year) AND (abs (varA - item 1 current-inner-list) <= 1) AND (item 2 current-inner-list = varB)] my-list))
  ]
end

让我们把这段代码分解。

filter命令被传递给一个匿名报告程序(通常是条件的连接)和my-list,因此它只报告所有这些条件都计算为TRUEmy-list项。

例如:对于具有year = 2017varA = 7varB = 0的修补程序,filter [current-inner-list -> (item 0 current-inner-list = year) AND (abs (varA - item 1 current-inner-list) <= 1) AND (item 2 current-inner-list = varB)] my-list语句将报告[[2017 7 0 12]],这是my-list,但只包含这一项。

考虑到您只对提取12感兴趣,还需要两个步骤:

  1. 使用firstlastitem 0提取唯一的内部列表。因此,first (filter [current-inner-list -> (item 0 current-inner-list = year) AND (abs (varA - item 1 current-inner-list) <= 1) AND (item 2 current-inner-list = varB)] my-list)报告[2017 7 0 12]
  2. 使用lastitem 3提取此内部列表的最后一项。因此,last (first (filter [current-inner-list -> (item 0 current-inner-list = year) AND (abs (varA - item 1 current-inner-list) <= 1) AND (item 2 current-inner-list = varB)] my-list))报告12

这就是为什么做set temp-varC <all of the above>的工作。

A注意:使用filter代码目前不适用于您的示例,因为my-list当前不包含足够的值组合,无法覆盖所有修补程序。这意味着,对于某些修补程序,filter [current-inner-list -> (item 0 current-inner-list = year) AND (abs (varA - item 1 current-inner-list) <= 1) AND (item 2 current-inner-list = varB)] my-list将报告一个空列表[],因此运行first (filter [current-inner-list -> (item 0 current-inner-list = year) AND (abs (varA - item 1 current-inner-list) <= 1) AND (item 2 current-inner-list = varB)] my-list)会给出一个错误。如果在实际模型中,my-list将包含修补程序可能具有的yearvarAvarB的任何组合,那么就没有问题了。否则,您可能需要预见到这种可能性,并使用ifelseifelse-valuetemp-varC分配默认值,以防在my-list中找不到匹配列表。类似于:

代码语言:javascript
复制
to test
  ask patches [
    let my-list-filtered filter [current-inner-list -> (item 0 current-inner-list = year) AND (abs (varA - item 1 current-inner-list) <= 1) AND (item 2 current-inner-list = varB)] my-list
    set temp-varC ifelse-value (empty? my-list-filtered) [0.5] [last first my-list-filtered]
  ]
end

关于temp-varC的多个更新

否:ask在NetLogo中的工作方式是,它首先收集属于被调用代理集的所有代理,然后要求每个代理在命令块中执行操作。就是这样,不需要动态更新代理集。

此代码验证它:

代码语言:javascript
复制
to test-ask-command
  clear-all
  
  create-turtles 2 [
    set color 25
  ]
  
  ask turtles with [color = 25] [
    show "Hi!"
    ask other turtles [
      set color 35
    ]
  ]
end

这显示了指挥中心中的下列情况:

代码语言:javascript
复制
observer> test-ask-command
(turtle 1): "Hi!"
(turtle 0): "Hi!"

这意味着第二只海龟说“嗨”,即使当它开始行动的时候,它的颜色已经改变到35了。

旁注

  1. 您是否有意在year = 0varA = 0中留下一些补丁?因为,在您的setup中,您只使用严格的更大和更少的符号,这样所有带有pxcor = 3的补丁都不会设置year,而使用pyxcor = -6的所有补丁都不会设置varA
  2. 准确地说,在样式方面,我建议选择不需要大写字母的重要变量名称:如果检查任何修补程序,您就会发现,例如,varA只是NetLogo的vara
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71779011

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档