Luca G.
Luca G.

Reputation: 29

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

I am trying to build a model in Netlogo in which I have two lists of lists which I call offerlist and bidlist, the two list are structured as follows:

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]...]

Basically every inner list contains the offer or bid of a certain agent, the price and the id of the agent submitting a certain offer/bid

I am trying to iterate over the two lists to simulate a market place, which means that I compare the prices of a certain offer and of a certain bid and if the conditions are met I would like to make a transaction happen reducing the offer in the offerlist and the bid in the bidlist. To be more specific I tried to do it like this:

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
]
]
]

The replace-subitem reporter works when it comes to change items of inner lists of a list of lists and I found it on Stack Overflow. Unfortunately using this I get an error since instead of the index of the items of the list I get a TRUE/FALSE probably because it is not possible or not functional to change items of the lists while I iterate through them. Is there a way to iterate through the lists while modifying the elements if certain conditions are met? If so which is the best way to do it?

Upvotes: 0

Views: 457

Answers (1)

Luke C
Luke C

Reputation: 10291

Thanks for the comment- One way to do this would be to use foreach with indices rather than with the list items directly, so you can use the index from one list to refer to another. With this setup:

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

Then (assuming the lists are always the same length) you can use the length of whichever list to build indices and iterate over every one. More detail in comments:

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

Which takes you from the input lists that look like:

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

to the output of:

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

If you'd prefer a map version, I think you have to do it in two steps:

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

Upvotes: 2

Related Questions