我正在尝试在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]...]
基本上每个内部列表都包含特定代理商的要约或出价,提交特定出价/要约的代理商的价格和ID
我试图遍历两个列表以模拟一个市场,这意味着我将比较某个报价和某个出价的价格,如果条件满足,我希望进行交易以减少要约列表中的要约和出价列表中的要约。 更具体地说,我尝试这样做:
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报告程序在更改列表列表的内部列表的项目时起作用,我在Stack Overflow上找到了它。 不幸的是,使用此方法会出现错误,因为我得到的是TRUE / FALSE而不是列表项的索引,这可能是因为在遍历列表项时无法或无法更改列表项。 如果满足某些条件,是否可以在修改元素的同时迭代列表?如果是这样,那是最好的方法?
答案 0 :(得分:2)
感谢注释-一种实现方法是将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