Updating counter of picked objects from a list - netlogo

I would like to update the counter of an element in a list, every time it is picked from turtles.
To do that, I am setting the item I am interested in and adding 1 to it (counter).
I created a global variable called it_cnt and I set it equal to 0 in the hatch where I create the objects (in order to know which turtle owns that item initially).
This is where I initialise the counter:
ask buyers [
hatch-obj random 5 [
set it_cnt 0
]
]
Please see below the list that I am considering
let picked_obj (list item 0 obj_in_shop_bag item 1 obj_in_shop_bag item 2 obj_in_shop_bag item 3 obj_in_shop_bag)
I am updating the counter as follows
let new_id_cnt item 3 picked_obj + 1
to add 1 in case the picked_obj is chosen by a buyer. However, when I print the list to see if it works
print (word " ; " item 0 obj_in_shop_bag " ; " item 1 obj_in_shop_bag " ; " item 2 obj_in_shop_bag " ; " item 3 new_id_cnt)
if the item is picked twice from different buyers in different ticks (ticks are item 0 in the list), the only value that I get is 1, as it was reset.
I would greatly appreciate if you could tell me how to fix the counter in order to let it work correctly.
Many thanks.

This is not an answer but is too long for comments. I can't make sense of the question.
You have set it_cnt 0 in the hatch but you say it's a global variable. So if you have 10 buyers, each of them hatches 0 to 4 obj and that single copy of the global variable is set to the value 0 by every one of the potentially 40 objs. Why? Do you mean that it's a turtle variable that is owned by obj?
Where you are updating the counter, you have suddenly switched the name from it_cnt to new_id_cnt. That won't update anything, there is no connection shown between the values of these two variables.

Related

How to create a sequential counter in NetLogo 6.2?

I would like to know if there is any way to implement a sequential counter without using a list by intervals. I'm trying to implement the following: at the end of each tick is counting the population size (NFinal). And then, we would check the constancy of the population, through a subtraction (the logical test would be the result of this subtraction is equal to zero during 3 consecutive ticks?).
For example:
NFinal of tick 0 - NFinal of tick 1 = 0
NFinal of tick 1 - NFinal of tick 2 = 0
NFinal of tick 2 - NFinal of tick 3 = 0
If this is the scenario (with 3 sequential values ​​equal to zero), the simulation will stop.
However, if it is in the scenario:
NFinal of tick 0 - NFinal of tick 1 = 0
NFinal of tick 1 - NFinal of tick 2 = 0
NFinal of tick 2 - NFinal of tick 3 = 2
The simulation does not stop (since it did not have 3 zero values ​​in sequence) and therefore would reset the counter to continue the simulation.
However what I managed to implement was by intervals using list. I don't know if it's the best way. Well, every time I use the list my model is getting slower. Is there a simpler way to implement this?
Thanks in advance!
Attempt below:
globals [ StabilityList ConstanceInterval ]
to go
if ConstanceInterval = 0 [ stop ]
end
to StabilityCheckerProc
set StabilityList lput 1 StabilityList ;; 1 = NFinal
let i 3 ;;
if length StabilityList >= i
[
let t1 last StabilityList
let start ( length StabilityList - i )
let t0 item start StabilityList
set ConstanceInterval abs ( t1 - t0 )
]
set StabilityList get-last i StabilityList
end
to-report get-last [ num lst ]
let b length lst
let a b - num
report sublist lst ( ifelse-value ( a < 0 ) [ 0 ] [ a ] ) b
end
You could use a counter to track the number of occurrences in a row, such that if your condition is satisfied you increase the counter, and if it is not you reset the counter. For example:
globals [ zero-tracker ]
to setup
ca
reset-ticks
end
to go
let variable-placeholder random 5
ifelse variable-placeholder = 0 [
; If a zero is recorded (eg, the result of your subtraction operation,
; increase the zero-tracker by one
set zero-tracker zero-tracker + 1
] [
; If anything BUT a zero is recorded, reset the zero-tracker
set zero-tracker 0
]
tick
if zero-tracker = 3 [
stop
]
end
Luke's answer is the answer.
But, if for any reason you did have a problem that needed to look at the last X things, and a counter was not going to work, you could use a list, but keep it at length X.
;; in setup, initialize the list with 'memory-size' items
set memory map [ -> 0] range 0 memory-size
;; in go, add a new memory to the list, and drop an old memory
set memory but-first lput value memory
;; then do what you must to examine the memories
< that code here >
Still slower than using a counter, but probably faster than accumulating and taking sections from an ever-growing list of values.
If you do need to maintain an ever-growing list of values, you might still maintain this smaller list.
Finally, even when using the ever-growing list of values, it would be fewer operations to take the sublist off the front of the list:
;; add new memory to front of list
set memory fput value memory
;; get last three memories from front of list
let last-three sublist memory 0 3 ;; no math or length needed
As always, test any assertion that something might be faster.

Netlogo: How to subset with row and column indexes

Could someone help me out with the code on reading in data in Netlogo? I am trying to choose one element in multiple lists to assign it to the turtle as a variable (I have the data in a rectangular table read from a csv file).
In my current code, it reads as I want but the problem is it is reading only elements of one last row instead of iteratively reading elements (across columns) of all rows. What I need is to read one element of each row at a time.
here are some rows of my data
Here is what I have tried so far:
let residents-file "mock-data.csv"
let residents-list []
set residents-list csv:from-file residents-file
foreach residents-list [ ?1 ->
let hh-col ?1row
let residents-to-create 1
create-residents residents-to-create [ setxy random-xcor random-ycor ]
ask residents [
set shape "person"
set color 9
set ID item 0 hh-col
set occupancy item 1 hh-col]]
It looks like the issue is that you are using create-residents to create n residents, but then asking all residents to do something. In other words, no matter which row is currently being processed, all of the existing residents (whether created in this iteration or created in previous iterations) are being asked to pull the values from the row that is being processed on the current iteration.
The easiest way to fix this is probably just to have each resident pull the values as it's being created.
With this toy version of your dataset:
id occupancy
1 owner
2 renter
3 owner
4 renter
5 owner
Here is a simplified example:
breed [ residents resident ]
residents-own [ id occupancy ]
extensions [csv]
to setup
ca
let residents-file "mock-data.csv"
let residents-list but-first csv:from-file residents-file
foreach residents-list [ cur-row ->
create-residents 1 [
set id item 0 cur-row
set occupancy item 1 cur-row
]
]
ask residents [
print ( word "My who is " who ", my id is " id ", and my occupancy is " occupancy )
]
reset-ticks
end
Output should look something like:

Plotting elements of a list through time (ticks)

I would need to study the distribution through time of items that are selected from a list, based on agent source’s breed (women and men).
At each tick, a breed woman or man creates a new object that is added in other turtles’lists. This/these objects can be selected at each step (ticks) by other turtles (women and/or men), spreading within the network.
In the plot, the y-axis should have the number of occurrences (frequency) of each object in the visited turtles (i.e. turtles that have selected that item from their lists).
Example:
object 3 is created by a man, object 5 is created by a woman.
man 2: count 1 object 3 (object 3 created) at tick 1
woman 4: count 1 object 5 (object 5 created) at tick 3
...
man 2: count 1 object 3 (object 3 picked) at tick 12
man 2: count 1 object 3 (object 3 picked) at tick 12
man 2: count 1 object 3 (object 3 picked) at tick 13
...
woman 31: count 1 object 5 (object 5 picked) at tick 21
Plots:
for object 3, I would have (dots in blue as it was created by a man)
x y
1 1
2 0
3 0
...
12 2
13 1
...
and for object 5 (dots in red as it was created by a woman):
x y
1 1
2 0
3 0
...
12 0
13 0
...
21 1
...
Do you have any suggestions on how I could plot over time items that are created, then picked by turtles and see, separately, the different distributions over time?
What you could do is using length filter in order to get the count of objects created by either men or women (if I understood well, this is item 2 in your list example):
let selected (list item 0 list_1 item 1 list_1 item 2 list_1)
ifelse item 2 list_1 = women [
set list_1_w fput selected list_1_w
print (word "List objects created by women: " list_1_w)
let list_count_w (length (filter [a -> item 2 a = women] list_1_w)) /* added */
]
[ set list_1_m fput selected list_1_m
print (word "List objects created by men: " list_1_m)
let list_count_m (length (filter [a -> item 2 a = men] list_1_m)) /* added */
]
The two letvariables above return a count of objects created by women or men. This count considers only breed women and men, not distinguishing between objects created by woman x and objects created by man x. About plotting them, probably you should count all of them at each tick in order to have a chronology of the number of events (objects) selected through time by agents.
To track each object, an idea would be to create a temporary plot pen that can track all objects:
ask turtles [ /* here you should distinguish between objects created by women and objects created by men */
create-temporary-plot-pen (word who)
set-plot-pen-color color
plotxy ticks ___ /* you should add here variable that you want to consider */
]
The code above can create a multiplot to track all objects (but you will need to label them and keep track when they're selected).
It's just an idea. You (or someone else in the community) should change accordingly the code above to consider the different breeds and how to track these objects through time.
I hope this can be of some help!
Since I can't seem to get you to understand my questions, I have a different suggestion. Stop trying to do a plot. Instead, do a monitor on the screen that does the calculation (at each tick) of whatever it is you are trying to plot. You can have one monitor for each breed. Once you have the monitor working, just use the same code as the pen in a plot.

Get a count of turtles with a combination of values

I am trying to count the number of "buyer" type turtles, which have a certain surplus (turtle variable) greater than or equal to zero, and price (another turtle variable) greater than the current turtle's price (already grabbed in local variable myprice...although there may be a more direct way to put it in)
let countup count buyers with ([surplus >= 0] and [price > myprice])
NetLogo returns
Expected a TRUE/FALSE here, rather than a list or block.
let countup count buyers with (surplus >= 0 and price > myprice) returns
WITH expected this input to be a TRUE/FALSE block, but got a TRUE/FALSE instead
Close! You're looking for:
let countput count buyers with [ surplus >= 0 and price > myprice ]
with is a report that takes two arguments, like so
<turtleset> with <report block>
where the reporter block is a clump of code surrounded by [ ] that will result in either true or false. In general [ ] is netlogo's way of grouping together code so you can doing something special with it, such as having each agent in an agentset run it. Hope that helps!
Also, I assume you've got something like let myprice price on, say, the line above this one. You can combine those lines like so (not saying this code is the right way to do it, just wanted to show another option):
let countput count buyers with [ surplus >= 0 and price > [ price ] of myself ]
Checkout the docs for (the very poorly named) myself.

Subtracting element of ith position from element at (i + 1)th position of any list in netlogo

I want to create a list of count values of some variable (tot-turtles) increasing with each tick. I tried the below code but all time list is having single element of length 1. neither i is getting incremented. please correct me.
set tot-turtles count turtles
to go
let mylist [ ]
set mylist lput tot-turtles mylist ; show mylist
set i 1
foreach mylist [ ; print ? ;show i
set x ? - i ; print x
set i (i + 1) ;show i
]
end
I want to subtract elements of list in the following fashion where the length of list depends on the number of simulation run or till simulation ends, then
i need subtraction of element as element at (i + 1)th - element at ith position till the end of the list.
In the above code i is 1 then increments by 1 ie 2 and then continue to 1 2 1 2 1 2. mylsit always shows single element. Confused with "?" , it gives element of current position if i am not wrong, but how we know the current position?
Please help me out of these doubts and code. thanks a lot.
Thank you sir, yes i was doing mistake with local and global variable i checkd it later. and the thing i wanted is as below.
to setup
set mylist [ 0]
set item-difference 0
end
to go
set tot-turtles count tutles set
mylist lput tot-turtles mylist
let _n (length mylist)
set item-difference (( item ( _n - 1 ) mylist - item ( _n - 2 ) mylist )
end
I hope you got Allan sir.
It's a bit difficult to tell what you are after, but it seems you are using a local variable when you want a global variable. See if this offers some help:
globals [mylist]
to setup
ca
set mylist []
crt 10
end
to go
crt 1
set mylist lput (count turtles) mylist ; show mylist
end
to test
let _n (length mylist)
(foreach mylist n-values _n [? + 1] [
print ?1 - ?2
])
end