Reputation: 241
I have a model in which turtles navigate a graph of nodes (also stored as turtles) and links in discrete increments (using the move-to
procedure). I would like to create a turtle based variable that allows turtles to remember the number of times they have visited particular nodes in the graph.
e.g.
move-to
a node set #visits #visits + 1
associated with that nodeset #visits 1
I imagine my options are related to lists or tables - however I am not sure which of these will be most efficient. With regards to tables I don't think the key can be a turtle - perhaps a string derived from its who - but this feels like it may be inefficient.
Two points that are likely pertinent:
some of the graphs will have a large number of nodes (~5000) , and often some of the turtles will never visit all of them, so it may be sensible to grow the structure on-the-fly to save memory.
there can also be a relatively large number of agents (~2500)
Any advice, as ever, much appreciated.
Upvotes: 2
Views: 300
Reputation: 14972
I realize I am late to the party, and Bryan's answer is perfectly fine, but an alternative solution would be to use a separate breed of links to record the number of visits to a node:
breed [ nodes node ]
undirected-link-breed [ edges edge ] ; node <---> node
breed [ agents an-agent ]
directed-link-breed [ visits visit ] ; agent ----> node
visits-own [ num-visits ]
to setup
clear-all
create-nodes 10 [ create-edges-with n-of (1 + random 2) other nodes ]
create-agents 10 [ move-to one-of nodes ]
end
to go
ask agents [
let destination one-of [ edge-neighbors ] of one-of nodes-here
move-to destination
if out-visit-to destination = nobody [ create-visit-to destination ]
ask out-visit-to destination [ set num-visits num-visits + 1 ]
]
end
It might not be quite as fast as using the table extension, but it would have the advantage of allowing queries from both sides: you ask an agent how many times it visited which nodes, but you can also ask a node how many times it has been visited by which agents.
Upvotes: 1
Reputation: 12580
Tables are the more efficient way to go as well as easier codewise, though using agents as keys does not work (much to my surprise). That said, you can just use who
numbers as keys.
It would look something like:
extensions [ table ]
turtles-own [ node-visits ]
...
to move-to-node [ node ]
move-to node
let key [ who ] of node
let visits ifelse-value (table:has-key? node-visits key) [ table:get node-visits key ] [ 0 ]
table:put node-visits key (visits + 1)
end
tables are efficient in both memory use and lookup speed. You could do this with lists and be efficient in memory use (if you use key value pairs) or lookup speed (if you use who
numbers as indices or something) but not both, unless you basically write your own hash table implementation with lists.
Now, all that aside, you generally should worry about performance problems like these until you are:
profiler
extension)The real reason I suggest the table extension is because it's the simplest to implement.
Upvotes: 3