当我建立我的模型时,我还上传了一个包含多个列的csv文件,经过一些研究后,我发现它被读取为一个列表列表(每一行都是一个列表)。
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。我对面向对象的建模还不熟悉.
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“的组合会发生变化,并且它可以有一个更新的(但我不想那样!)。
发布于 2022-04-07 16:44:14
关于如何计算my-list中有多少列表
每个内部列表只是my-lists的一个项目,因此length my-lists会告诉您有多少内部列表。
关于varA周围的区间
这只需要你设计一个反映你想要的东西的算术条件。我想至少有几种方法可以做到。
例如,对于要应用此间隔的条件,而不是具有以下内容:
varA = item 1 some-list你本可以:
abs (varA - item 1 some-list) <= 1使用while的方法
让我首先给您一个使用while的解决方案,因为这是您处理问题的方式,也是因为澄清如何在此上下文中处理列表是有用的。在此之后,使用filter的方法更加简洁。
使用while方法,您不需要foreach,因为foreach 对列表中的每一项运行一个命令。。在您使用foreach的示例中,您告诉匿名过程将my-list的每一项(即每个内部列表)一次存储为x,并为每个x运行一些命令。但是,您从不在这样的命令中处理x,这证明了foreach是超级的。
这意味着,使用上面关于列表长度和条件下的间隔的两条信息,您可以通过以下操作实现您的目标:
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。
就您的情况而言,这意味着您可以:
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,因此它只报告所有这些条件都计算为TRUE的my-list项。
例如:对于具有year = 2017、varA = 7和varB = 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感兴趣,还需要两个步骤:
first、last或item 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];last或item 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将包含修补程序可能具有的year、varA和varB的任何组合,那么就没有问题了。否则,您可能需要预见到这种可能性,并使用ifelse或ifelse-value为temp-varC分配默认值,以防在my-list中找不到匹配列表。类似于:
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中的工作方式是,它首先收集属于被调用代理集的所有代理,然后要求每个代理在命令块中执行操作。就是这样,不需要动态更新代理集。
此代码验证它:
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这显示了指挥中心中的下列情况:
observer> test-ask-command
(turtle 1): "Hi!"
(turtle 0): "Hi!"这意味着第二只海龟说“嗨”,即使当它开始行动的时候,它的颜色已经改变到35了。
旁注
year = 0和varA = 0中留下一些补丁?因为,在您的setup中,您只使用严格的更大和更少的符号,这样所有带有pxcor = 3的补丁都不会设置year,而使用pyxcor = -6的所有补丁都不会设置varA。varA只是NetLogo的vara。https://stackoverflow.com/questions/71779011
复制相似问题