Netlogo working with specific items using nested lists - list

All
I'm trying to simulate a 100 users (breed) each of them having users-own attributes which are tracked over various two runs of ticks say 0 & 1. I store these values as a list within a list and sorted them. They appear like this [[tick 0, user 2, attrib 1 ... attrib 9] [tick 1, user 2, attrib 1 ... attrib 9] [tick 0, user 3, attrib 1 ... attrib 9] [tick 1, user 3, attrib 1 ... attrib 9] ... [tick 0, user 99, attrib 1 ... attrib 9] [tick 1, user 99, attrib 1 ... attrib 9] ]
As I randomly 'ask users' to reassign certain attributes, how do I get the subset of matching values that matches the current user referred by 'who'? for example if the current user in context is 'user 3', how do I get the sublist of the matching entries from the list of lists?
Once I obtain the sublist matching 'user 3'[tick 0, user 3, attrib 1 ... attrib 9] [tick 1, user 3, attrib 1 ... attrib 9], how do I get the index of each line & the items within that list? for example if I need to access the last item on the sublist (corresponding to tick 1) so that I can obtain the value of attrib 9 to process it further?
Thanks in advance for your help!

if your list is structured: [ [ TICK# TURTLE# ATT1 ... ATT9 ] ... ]
[
[ 0 0 1 .. 9 ]
[ 0 1 1 .. 9 ]
[ 0 2 1 .. 9 ]
...
[ 0 99 1 .. 9 ]
[ 1 0 1 .. 9 ]
[ 1 1 1 .. 0 ]
... and so on ...
And the number of turtles is always CONSTANT
Then you can calculate the index of the item you need.
;; attribute data is in list "data"
LET total-turtles COUNT TURTLES
LET desired-tick 1 ;; number of the tick
LET desired-turtle 7 ;; WHO of turtle
LET desired-attribute 4
;; calculate the sublist index
LET sublist-index desired-tick * total-turtles + desired-turtle
;; get the sublist
LET attribute-sublist ITEM sublist-index data
;; get the value from the sublist
LET attribute-value ITEM (desired-attribute + 2) attribute-sublist
If you set desired-turtle to [WHO] OF ONE-OF TURTLES you are working with a random turtle. Or you can ASK a random turtle to do the above, and it can just use its own WHO.
If you add the info to the list strictly in order, then you don't need to store the tick# or who#, and you don't need to sort it.
If you let the turtle store its own list of prior attributes, it might be even easier to store and access, depending on your application.
Now you have the pieces needed for a random turtle to access the history list and grab the values from its own history, or some other turtle's history.

Related

Netlogo: replacing matrix elements by conditioning on other rows/columns

I am working in Netlogo on a series of models making heavy use matrices. Briefly, the models include a number of state-variables for different breeds, where the state-variables are often stock-like items. As a simple example, consider the model:
extensions [ matrix ]
globals
[
]
turtles-own
[
n-items
stock-list
]
to setup
clear-all
reset-ticks
create-turtles 2
ask turtles
[
setxy random-xcor random-ycor
set n-items 10
let n-vars 3
set stock-list matrix:make-constant n-items n-vars [0] ; empty matrix
let stock-item n-values n-items [i -> i]
let stock-cost n-values n-items [ random-normal 10 2 ]
let stock-age n-values n-items [ random 50 ]
matrix:set-column stock-list 0 stock-item
matrix:set-column stock-list 1 stock-cost
matrix:set-column stock-list 2 stock-age
]
end
Here, each turtle's matrix stock-list is initialised as an empty matrix and then its columns filled in depending on the variables stock-item (id for stock), stock-cost and stock-age.
Imagine a go procedure that increments the stock age by one each time-step:
to go
ask turtles
[
let current-age matrix:get-column stock-list 1
let new-age map [x -> x + 1] current-age
matrix:set-column stock-list 2 new-age
]
tick
end
What I would like to do is an operation on stock-cost only if the age is greater than some value, e.g. 10
;; pseudo-code
for( i = 1 to I = number of items )
{
if ( stock-age[i] > 10 )
{
stock-cost[i] - 1
}
}
I know how to change the list of stock-cost conditional on its own values, using the map primitive, e.g.:
to decrease-stock-value
ask turtles
[
let current-cost matrix:get-column stock-list 1
set current-cost map [[?] -> ifelse-value (? > 10) [? - 1][?]] current-cost
matrix:set-column stock-list 1 current-cost
]
But my efforts to generalise this to using values in a different list to condition upon have failed.
Thanks for your help! Also, any insight onto whether this is a good approach to modelling state variables such as stocks would be useful.
I think I sorted it out using:
to decrease-stock-value
ask turtles
[
let current-cost matrix:get-column stock-list 1
let current-age matrix:get-column stock-list 2
let new-cost ( map [ [ a b ] ->
ifelse-value ( a > 10 ) [ b - 1 ] [ b ] ]
current-age current-cost
)
matrix:set-column stock-list 1 new-cost
]
end

NetLogo: How to compare two sublists

I am not from a computer science background and I am also new to NetLogo, so I would really appreciate your help. My question is as follows:
Let assume that I have a list of three lists
Let mylist [ [ 1 2 3 4 5 ] [ 2 2 2 2 2 ] [ 3 3 3 3 3 ] ]
I would like to check each item within item 2 mylist (i.e. [ 3 3 3 3 3 ]) and see if it is not equal to the corresponding item in item 0 mylist (i.e. [ 1 2 3 4 5 ]). If that the case, I would like to subtract a constant value which is 5 from that item in item 2 mylist.
In other words, I would like mylist to be changed to the following:
[ [ 1 2 3 4 5 ] [ 2 2 2 2 2 ] [ -2 -2 3 -2 -2 ] ]
Thanks in advance,
Your own answer is fine, but here is what I consider to be a somewhat more elegant way to do it:
print lput (map [ [ a b ] ->
ifelse-value (a = b) [ b ] [ b - 5 ]
] (item 0 mylist) (item 2 mylist)) but-last mylist
The key primitive here is map, which is to foreach what of is to ask: instead of running a command on each element, it runs a reporter and builds a new list out of the results. In this particular case, it saves you from having to mess with indices and replace-item inside.
The combination of lput and but-last makes it easy to replace the last sublist in your main list, but you could also use replace-item for that. Or, depending on what you need it for, you could just use the result of map directly instead of putting it back in your main list.
I managed to solve the problem by separating the sublists:
to go
Let mylist [ [ 1 2 3 4 5 ] [ 2 2 2 2 2 ] [ 3 3 3 3 3 ] ]
let auxiliar-list1 item 0 mylist
let auxiliar-list2 item 2 mylist
foreach ( range 0 ( length auxiliar-list1 ) ) [ num-item ->
if item num-item auxiliar-list1 != item num-item auxiliar-list2 [
set auxiliar-list2 replace-item num-item auxiliar-list2 (item num-item auxiliar-list2 - 5)
show mylist
show auxiliar-list1
show auxiliar-list2
]
]
end

Netlogo list updated in time

I'm writing up a code in Netlogo that basically should do the following:
Amongst directed links, interact and seek out their cooperative behavior (coop_b).
Store coop_b in a list variable together with the time of the interaction (reputation_now)
Every interaction, add the reputation_now to a bigger list, reputation_h (reputation history)
Now, add a time-weight to the reputation, so that the more recently had interactions weigh more in the total reputation. I do this by dividing the encounter time of an interaction by the current time tick, then multiplying that with the coop_b to retrieve a weighted reputation for each interaction. This is stored in the list reputation_h_w (historic reputations weighted). The thing is, this list should be updated every time the members interact, so that earlier additions to the list are now updated to the new time tick. My hunch is this is where my code goes in the mist (problems depicted below the code section).
My code:
to horizontal_interact
ask members [
;set random example variable for coop_b
set coop_b random-float 5 ; coop-b stands for cooperation behavior
if ticks > 0 [
ask my-out-links [ ;there are directed links between all members
set reputation_now (list [coop_b] of end2 ticks) ;list of coop_b and encounter time
set reputation_h lput reputation_now reputation_h ; history of reputations, a list of all reputation_now recorded
foreach reputation_h [ x ->
let cooperative_behavior item 0 x
let encounter_time item 1 x
let reputation_now_w (list cooperative_behavior encounter_time (encounter_time / ticks ))
]
]
]
]
end
If I test the content of reputation_h and reputation_h_w with 2 members, I get:
reputation_h is the coop_b variable of the member and the tick of encounter
links> show reputation_h
(link 1 0):
[[4.0900840358972825 1]
[0.8885953841506328 2]
[0.47017368072392984 3]]
(link 0 1): [[3.6805257472366164 1]
[3.6805257472366164 2]
[3.4201458793705326 3]]
reputation_h_w (containing the member's coop_b variable, the encounter time and the encounter time divided by the ticks):
links> show reputation_h_w
(link 0 1): [[3.6805257472366164 1 1]
[3.6805257472366164 1 0.5]
[3.6805257472366164 2 1]
[3.6805257472366164 1 0.3333333333333333]
[3.6805257472366164 2 0.6666666666666666]
[3.4201458793705326 3 1]]
(link 1 0): [[4.0900840358972825 1 1]
[4.0900840358972825 1 0.5]
[0.8885953841506328 2 1]
[4.0900840358972825 1 0.3333333333333333]
[0.8885953841506328 2 0.6666666666666666]
[0.47017368072392984 3 1]]
The problem is that reputation_h_w doesn't make sense to me - firstly there's six inputs instead of three, and secondly, the encounter time (item 1) and the encounter time/ticks (item 2) is off.
What am I doing wrong here?
Not sure where you update reputation_h_w in your code, but I'm guessing that you are not resetting it to a blank list before running your foreach loop again. So, it's lput-ing the values at the end of the list, which is not blank anymore.
Example setup:
breed [ as a ]
as-own [ coop_b ]
links-own [ reputation_now reputation_history reputation_history_w]
to setup
ca
create-as 2 [
set coop_b who + 1
setxy random-pxcor random-pycor
]
while [ any? as with [ not any? my-in-links ] ] [
ask one-of as with [ not any? my-out-links ] [
create-link-to one-of other as with [ not any? my-in-links ] [
set reputation_now []
set reputation_history []
]
]
]
reset-ticks
end
Note that here I will set reputation_history [] right before the foreach chunk runs:
to interact
if ticks > 0 [
ask links [
set reputation_now ( list [coop_b] of end2 ticks )
set reputation_history lput reputation_now reputation_history
; reset reputation history to a blank list, as you are
; recalculating the weighted value at each tick
set reputation_history_w []
foreach reputation_history [ x ->
let behavior item 0 x
let encounter_time item 1 x
let fraction encounter_time / ticks
set reputation_history_w lput (
list behavior encounter_time fraction ) reputation_history_w
]
show ( word "Current reputation: " reputation_now )
show ( word "Reputation history: " reputation_history )
show ( word "Weighted history rep list: " reputation_history_w )
]
]
tick
end
As far as why your ticks are off, I'd guess it's because you are calling tick after you run your horizontal_interact procedure. With the example above, my output looks like:
(link 0 1): "Current reputation: [2 2]"
(link 0 1): "Reputation history: [[2 1] [2 2]]"
(link 0 1): "Weighted history rep list: [[2 1 0.5] [2 2 1]]"
(link 1 0): "Current reputation: [1 2]"
(link 1 0): "Reputation history: [[1 1] [1 2]]"
(link 1 0): "Weighted history rep list: [[1 1 0.5] [1 2 1]]"
even though the ticks read 3. If you run it with tick at the start of the procedure, that might sort out your expected output.

Netlogo list in list iterations with counter

I have read from csv a list of lists named fileList [[id, id2, id3],[10,10,11]]
But i have problem that I want to iterate trough the list and in every iteration create a turtle that contain id1, id3 (not Id2) as variables. My idea in python syntax (I need help to transpose it to NetLogo):
for x, list in enumerate(fileList):
if x==0: #first list is names so I transpose the names to places in
index_id=list.index(id)
index_id3=list.index(id3)
else:
create-turtle_nr1 #not in python syntax but the idea is to create turte to assign variables from list below
ask turtle_nr1 [set id1 item (item as list[index_id])]
Overall output is three turtles with variables id and id3.
In this case, you should just be able use item to index your lists iteratively. Essentially, for each turtle you want it to index the appropriate list-of-variables from the list of lists and then index the appropriate variable from that list. You could start with something like:
turtles-own [
id
id2
id3
]
to list-of-lists
;;; these lists are just placeholders, of course, use your real list of lists
;;; as the "ids_list" variable in this case
let id1list [ 1 2 3]
let id2list [ 44 55 66 ]
let id3list [ "a" "b" "c" ]
let ids_list ( list id1list id2list id3list )
let n 0
while [ n < 3 ] [ ;;; or however many turtles you end up wanting,
;;; as long as you have list variables for them
create-turtles 1 [
set id item n (item 0 ids_list)
set id3 item n (item 2 ids_list)
]
set n n + 1
]
end
This procedure creates three turtles with ids of 1, 2, and 3, id2s of 0, and id3s of a, b, and c.

How to make turtles move along a list of locations in order

My objective is to have an agentset (named ships) hatch at another agentset (named ports and listed in index) containing 2 locations representing the start and end of a pathway. To go- start moving ships/ heading towards a third agentset (called waypoints and listed in index1) in their given order.
However, if a port is closer to the current waypoint than another waypoint- move to port instead. Once the ships have reached the other port, I would also like them to stop.
Currently I have the model working with only two agentsets (ships and ports) however I would like to include a third set(called waypoints) to prevent ships from hatching at all locations(ports and waypoints) and to have the ships move in a sequential order by traveling along the waypoints (like stepping stones) before reaching the beginning or the end (ports).
Here is an example of my code:
breed [ships ship]
breed [ports port]
breed [waypoints waypoint]
ships-own [target-port
current-port]
to setup
ca
let index 0
create-ports 2
[ let loc item index [ [0 -32] [32 0] ]
setxy (item 0 loc) (item 1 loc)
set index index + 1
set shape "circle"
set size 2
set color red - 1]
let index1 0
create-waypoints 2
[let loc item index1 [[12 -3] [14 -26]]
setxy (item 0 loc) (item 1 loc)
set index1 index1 + 1
set shape "circle"
set size 1
set color red - 1]
ask ports
[ let s who
hatch-ships 1
[ set current-port s
set size 1
set color red
pen-down
set pen-size 1
set target-port min-one-of ports with [ who != s] [distance myself]
set heading towards target-port
]
]
reset-ticks
end
to go
;(obey-elevation)
ask ships
[ if (distance target-port = 0)
[ let other_ports no-turtles
ask target-port [set other_ports (other ports)]
set target-port min-one-of other_ports [distance myself]
face target-port
]
ifelse (distance target-port < 1)
[ move-to target-port
]
[fd 1
]
]
tick
end
Any help would be greatly appreciated.