NETLOGO:迭代两个列表列表并动态更改项目

NETLOGO: iterating over two lists of lists and dynamically changing items

我正在尝试在 Netlogo 中构建一个模型,其中我有两个列表列表,我称之为报价列表和投标列表,这两个列表的结构如下:

let offerlist [[offer_1 price_1 id_of_agent] [offer_2 price_2 id_of agent]...]
let bidlist [[bid_1 price_1 id_of_agent] [bid_2 price_2 id_of agent]...]

基本上每一个内表都包含了某个代理的offer或者bid,价格和提交某个offer/bid

的代理id

我正在尝试遍历这两个列表来模拟一个市场,这意味着我比较某个出价和某个出价的价格,如果满足条件,我想进行交易减少offerlist中的offer和bidlist中的bid。 更具体地说,我试着这样做:

to-report replace-subitem [index1 index2 lists value]
  let old-sublist item index1 lists 
  report replace-item index1 lists (replace-item index2 old-sublist value)
end

foreach offerlist[[x]->
   foreach bidlist[[y]->
     if item 1 x < item 1 y[
       set bidlist replace-subitem (position y bidlist) 0 bidlist 0
       set offerlist replace-subitem (position x offerlist) 0 offerlist 0
]
]
]

replace-subitem reporter 在涉及更改列表列表的内部列表项时起作用,我在 Stack Overflow 上找到了它。 不幸的是,使用这个我得到一个错误,因为我得到的不是列表项目的索引,而是 TRUE/FALSE 可能是因为在我遍历列表项目时不可能或不能更改列表项目。 如果满足某些条件,是否可以在修改元素的同时遍历列表?如果是这样,最好的方法是什么?

感谢您的评论 - 一种方法是将 foreach 与索引一起使用,而不是直接与列表项一起使用,这样您就可以使用一个列表中的索引来引用另一个列表。使用此设置:

globals [ offerlist bidlist ]

to setup
  ca
  set offerlist [ [ 25 15 1 ] [ 75 25 2 ] [ 23 35 3 ] ]
  set bidlist   [ [ 15 20 1 ] [ 90 30 2 ] [ 20 40 3 ] ] 
  reset-ticks
end

然后(假设列表的长度始终相同)您可以使用任何列表的长度来构建索引并遍历每个列表。评论中的更多详细信息:

to update-lists
  foreach range ( length offerlist ) [
    ind ->
    ; Get the first items from each current sublist
    let offer-item item ind offerlist
    let bid-item item ind bidlist

    ; If the offer is greater than the bid, get the
    ; difference between those values
    if first offer-item > first bid-item [
      let dif first offer-item - first bid-item

      ; Update the offer item with the difference value
      set offer-item replace-item 0 offer-item dif

      ; Update the bid-item with 0  
      set bid-item replace-item 0 bid-item 0

      ; Go back to the index value to update both the
      ; offerlist and the bidlist
      set offerlist replace-item ind offerlist offer-item
      set bidlist replace-item ind bidlist bid-item
    ]
  ]

  print offerlist
  print bidlist
end

从如下所示的输入列表中获取:

[[25 15 1] [75 25 2] [23 35 3]]
[[15 20 1] [90 30 2] [20 40 3]]

到输出:

[[10 15 1] [75 25 2] [3 35 3]]
[[0 20 1] [90 30 2] [0 40 3]]

如果您更喜欢 map 版本,我 认为 您必须分两步完成:

to update-lists-map 
  ; Make a temporary offerlist by mapping over
  ; the current offerlist and bidlist, and replacing
  ; the first item as appropriate
  let newoffers ( map [ 
    [ o_ b_ ] -> 
    ifelse-value ( first o_ > first b_) 
    [ replace-item 0 o_ ( first o_ - first b_ )]
    [ o_ ]
  ] offerlist bidlist )

  ; Make a temporary bidlist by mapping over
  ; the current offerlist and bidlist, and zeroing
  ; the first item as appropriate
  let newbids ( map [ 
    [ o_ b_ ] -> 
    ifelse-value ( first o_ > first b_) 
    [ replace-item 0 b_ 0 ]
    [ b_ ]
  ] offerlist bidlist )

  ; overwrite the original offer and bid lists
  set offerlist newoffers
  set bidlist newbids

  print offerlist
  print bidlist
end