我想总结一个共享相同ID的修补程序的数值属性(AT1),并存储该ID的值(下面是过程simulation )。首先,我想遍历补丁以找到共享相同ID的补丁(基于外部文件)。
见下面一个可重复的代码,它不起作用,它一个接一个地打印所有补丁的和,但不只是一个ID,我尝试了几种方法。
globals [
AT-data
ABC
area
]
patches-own [
ID
AT1
AT2
seed
sum_AT1
]
to setup
;; here I just create patches with different values that also appear in the list
ca
set ABC [ "A" "B" "C" "D" "E" "F" "G" "H" "I" ]
ask patches [ set seed random 10 set ID one-of ABC
ifelse (seed = 4)
[ set pcolor orange] [set pcolor white]
]
end
to load
reset-timer
; first, we load the database file
; We check to make sure the file exists first
ifelse ( file-exists? "AT_data.txt" )
[
; We are saving the data into a list, so it only needs to be loaded once.
set AT-data []
file-open "AT_data.txt"
while [ not file-at-end? ]
[
; file-read gives variables stored in a double list
; Each iteration we append the next three-tuple to the current list: ID AT1 AT2
set AT-data sentence AT-data (list (list file-read file-read file-read))
]
user-message "File loading complete!"
file-close
assign-data
stop
]
[ user-message "There is no AT_data.txt file in current directory!" ]
file-close-all
print timer
end
to assign-data
reset-timer
ask patches with [seed = 4] [
let i 1
while [i < length AT-data] [
let current-inner-list item i AT-data
ifelse (ID = item 0 current-inner-list)
[ set AT1 item 1 current-inner-list set AT2 item 2 current-inner-list
stop]
[ set i i + 1 ]
]
]
print timer
end
to simulation
reset-timer
ask patches [
let i 1
while [i < length AT-data] [
let current-inner-list item i AT-data
ifelse (ID = item 0 current-inner-list)
;; I tried with and without this following line
;[ask patches with [ID = item 0 current-inner-list] [
[ set area area + AT1
print area
print ID
stop
]
;]
;; this one is an alternative
;[ print sum [AT1] of patches with [ID = item 0 current-inner-list]
;print ID
;]
[ set i i + 1 ]
]
]
print timer
endAT_data.txt是
"A" 65 81
"B" 21 71
"C" 54 18
"D" 23 41
"E" 85 27
"F" 35 88
"G" 29 4
"H" 78 2
"I" 99 60谢谢你抽出时间!
发布于 2022-05-12 15:25:26
我的第一点意见是,在simulation中有补丁再次询问补丁程序。
您的第二个解决方案是更简单的工作方法。这里的主要内容是将其从修补程序上下文中删除并让观察者运行它。对于打印输出,我建议使用像print (word current-ID ": " current-sum)这样的格式。在运行模型之后,当您想要快速检查它时,这是非常干净的。
to simulation-2
reset-timer
let i 0
while [i < length AT-data] [
let current-inner-list item i AT-data
let current-ID item 0 current-inner-list
let current-sum sum [AT1] of patches with [ID = current-ID]
print (word current-ID ": " current-sum)
set i i + 1
]
print timer
end对于您的第一个解决方案,您的问题是,您只有一个区域变量,您的增量。在下面的示例中,我将区域设置为包含列表的列表,其长度与AT-data相同。每个内部列表由一个ID和一个设置为0 [["A" 0] ["B" 0] ... ["I" 0]]的计数器组成。为此,我使用map过程。map获取列表中的每个单独元素,对其执行特定操作,并将它们全部作为新列表返回。一般来说,这是一个非常有用的程序,以了解什么时候您将使用列表。
接下来,我像您一样迭代所有补丁,并增加区域列表的计数器以获得正确的ID。第一个变量有很多局部变量,可以清楚地显示它是如何工作的。您将挖掘出正确的子列表,然后挖掘出正确的变量,递增该变量,在子列表中替换它,并替换主列表中的子列表。第二个操作完全相同,但只在一行代码中执行。
to simulation-1
reset-timer
set area map [inner-list -> list item 0 inner-list 0] AT-data ;creates a new list of lists of the form [["A" 0] ["B" 0] ... ].
ask patches [
let i 0
while [i < length AT-data] [
let current-inner-list item i AT-data
ifelse (ID = item 0 current-inner-list)
[ let inner-area-list item i area ;grab the correct innerlist
let increased-count item 1 inner-area-list + AT1 ;increment the second part of this inner list
set inner-area-list replace-item 1 inner-area-list increased-count ;put the incremented count back into the inner list
set area replace-item i area inner-area-list ;put the inner list back into the complete list
;; all these can be combined into a single line of code but that is more prone to errors
;set area replace-item i area (replace-item 1 item i area (item 1 item i area + AT1))
stop
]
[ set i i + 1 ]
]
]
print area
print timer
end只有在构建了这个完整的嵌套列表结构之后,我才想到这样一个事实:您可以使用一个正常的列表,其中只有不同的计数器,而没有ID,但是这种结构确实使它非常紧凑、清晰,并且很好地用于后续处理。
https://stackoverflow.com/questions/72215932
复制相似问题