首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >循环遍历在Net徽标中共享公共属性的修补程序

循环遍历在Net徽标中共享公共属性的修补程序
EN

Stack Overflow用户
提问于 2022-05-12 12:52:28
回答 1查看 52关注 0票数 0

我想总结一个共享相同ID的修补程序的数值属性(AT1),并存储该ID的值(下面是过程simulation )。首先,我想遍历补丁以找到共享相同ID的补丁(基于外部文件)。

见下面一个可重复的代码,它不起作用,它一个接一个地打印所有补丁的和,但不只是一个ID,我尝试了几种方法。

代码语言:javascript
复制
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是

代码语言:javascript
复制
   "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

谢谢你抽出时间!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-12 15:25:26

我的第一点意见是,在simulation中有补丁再次询问补丁程序。

您的第二个解决方案是更简单的工作方法。这里的主要内容是将其从修补程序上下文中删除并让观察者运行它。对于打印输出,我建议使用像print (word current-ID ": " current-sum)这样的格式。在运行模型之后,当您想要快速检查它时,这是非常干净的。

代码语言:javascript
复制
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。第一个变量有很多局部变量,可以清楚地显示它是如何工作的。您将挖掘出正确的子列表,然后挖掘出正确的变量,递增该变量,在子列表中替换它,并替换主列表中的子列表。第二个操作完全相同,但只在一行代码中执行。

代码语言:javascript
复制
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,但是这种结构确实使它非常紧凑、清晰,并且很好地用于后续处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72215932

复制
相关文章

相似问题

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