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
我正在尝试在 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