我想總結一個共享相同 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
end
AT_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
謝謝你的時間 !
uj5u.com熱心網友回復:
我的第一句話是你有補丁在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
對于您的第一個解決方案,您的問題是您只有一個增加的區域變數。在下面的例子中,我將 area 做成一個串列,長度與 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://www.uj5u.com/yidong/473788.html
上一篇:兩個檔案的第二列的數學
