Find the 'source turtle' of an item in a list - netlogo

I would like to track the path of a wallet stolen by a thief. The model should create a network of thieves, each of them with their own bags where they put the stolen objects (I am setting this objects - wallets - as self).
Let suppose that thief1 has in his own bag [wallet1 wallet2 wallet4] and his neighbour has [wallet1 wallet3] as wallet1 was added in his own bag.
If the neighbour with bag [wallet1 wallet3] wants to pick randomly one of the two items to return to the police, for example wallet1 (and this can be done using [let picked_wallet one-of turtle-set my-bag]), how can I add a 'tag' or something that can tell me that the first thief to stole that wallet was the thief1?
globals [this-wallet]
breed[thieves thief]
thieves-own [my-bag wallet-id]
to setup
clear-all
create-thieves 5
ask thieves [ set my-bag [] create-links-to other thieves ]
ask one-of thieves [ set this-wallet self set my-bag fput self my-bag ask link-neighbors [set my-bag fput this-wallet my-bag print "Neighbours " show my-bag ]]
ask one-of thieves [ set this-wallet self set my-bag fput self my-bag ask link-neighbors [set my-bag fput this-wallet my-bag print "Neighbours " show my-bag ]]
ask thieves [show link-neighbors show my-bag]
reset-ticks
end

In response to your comment on my last answer, here's a new answer.
Well, a virus problem is different from a wallet problem and needs different data structures.
Still, viral transmission can be modeled as a series of transactions, so the idea of using a global master list of transactions to keep track of what has gone on is still a workable approach.
You COULD also keep a list on each agent of who they got a virus from and when, but it would be redundant with a single master list -- you can simply filter the master list of transactions by agent to see exactly the same information as what you are trying to keep in many lists at the agent level. I'm not sure why you do not like that approach.
Keeping one list is much cleaner than keeping many lists. Any question you could ask agents-with-lists you could also answer by searching the global list.
It would make sense to have a little redundancy for viewing what is going on and for simplifying the ASK command you will use to spread the virus -- so you could store at the agent level whether the agent is currently-infected? and color-code infected agents to tell them apart from never-infected agents and fully-recovered? agents and dead? agents.
Even that could be reduced to a single status variable with legitimate values of "healthy" "infected" and "recovered" and a single is-immune-now? flag. That would be enough to figure out who is contagious, who is infected, who could possibly become infected, who has recovered, who has died, etc.
Of course, if you are playing epidemiologist and trying to track down where the infection came from ( "patient zero") you COULD add a variable showing for each person WHO they got infected BY and when and write some long recursive code to trace back step by step where that linked-list started. OR, you could just get the same answer in a simple single filtering pass of the master list of who infected whom and when.
Maybe doing this the easy way is "cheating" and you want to play doctor instead of God and you want to show how it could possibly be tracked back one step at a time? Or you want to show how an epidemiologist might go to a lot of effort to build a "tree" diagram showing where the infection started and how it spread down different branches?
That's an INTERESTING problem but it is not the question you asked.
If you want to find the ultimate-source-turtle for an item in a list, you need to modify your data-structure. One way ( the hard way ) to do that would be to store more information in each turtle's list -- so at the time the virus is added to the list you ALSO add a timestamp and a source-turtle. Possibly you could store this information as triplets in a list such as [ source-agent-id tick-acquired virus-type ] and so each agent would have a list of such triplet-lists. That could work. That's one way to do it.
That would require that you add some complexity to the process that puts the virus on their list. It would have to build a list of the 3 items and put that list onto the target my-list of any agent it infected. ( In your case the virus seems to be 100% contagious and anyone with it gives it to everyone else! )
So your ASK-TURTLES logic would be a little bit more complicated. You could manage the complexity by having little to-report routines that packed the triplet-list or unpacked it.
OR, with fewer lists to manage, you could have your ASK-TURTLES logic store a series of transactions, that you could code as 4-item lists: [ source-id target-id virus-type tick-infected ] and store that in a master list-of-lists in a global variable. You still might want to set the target-turtle's variables of "status" and "immune-now?" at the time you are infecting the next agent to simplify identifying which turtles are contagious and which turtles are immune to simplify the next go step where you would ask turtles who are contagious to infect turtles who are not immune and are within a given radius, etc.

You asked
how can I add a 'tag' or something that can tell me that the first
thief to stole that wallet was the thief1?
I'm not clear about what operation corresponds to "stealing a wallet". Is the agent doing the stealing the one who puts the wallet on someone's list? Or the one whose list it gets put on?
In your example you have two different people with "wallet1" on their list, so I'm also not clear about who "has" the wallet. How can one wallet be two places at once? In fact it's more than two places, when it's put on one thieves list, it's put on every thieve's list. What is that operation supposed to represent? Is that "stealing"?
Are you trying to figure out which of the many copies of wallet1 got put on any agent's list first in time? Of course that's a little hard because agent sets are always processed in a random order, so the code you show gives no clue to who got it first.
What I'm suggesting is that the data-structure you have doesn't seem to do a good job of representing real-world operations, and if this doesn't confuse the current question of who got the wallet put on their list first, which is what I think you're asking, it will surely confuse other questions down the road. The operation you show for updating the lists makes it impossible to determine which thief got it first.
It certainly confuses me. I think your coding would be much easier if there was only ever one copy of wallet1 in existence, and it was only on one agent's list at a time, and the agent's list was only one entry long, and you had a "steal-wallet" procedure that removed a wallet from one agent's list and put it on exactly one different agent's list. Then it would be clear what time that happened.
Or are these lists supposed to represent knowledge one agent has about the existence of the wallet? Or do they represent all wallets that ever existed owned by anyone over all historical time, in which case the "same" wallet might appear many different times, each time representing a different owner, and even the same wallet and the same owner might be stolen and stolen back multiple times so even that pair of facts (wallet-id and new-owner) would not be unique.
For one thing, if everyone is going to end up with identical lists, then find some place to put the list once and be done with it -- don't give everyone a copy when one copy will do. The list doesn't even need to be owned by anyone -- it can simply be a global variable. That would simplify a lot. Then you only have one wallet, and each time it changes owner you can make an entry in the master-list.
What should the entry have in it? Certainly not the wallet itself, because that CAN be passed around. Probably you need a sublist that describes the transaction that just took place, so you would need a sublist containing [wallet-id, last-owner-id, current-owner-id, time-it-changed-hands] as the entries in the master global list.
From that you could at least conceptually be able to reconstruct who had the list first, second, third, .. or last, who has it now, anything you wanted. Or if you always did "lput" to put the latest event as the last item on the list, then you wouldn't even need the time-stamp, unless you lose information by sorting the list, because the first owner would be the first entry on the list that had that wallet-id. Problem solved, in concept. Still you might want to sort the list someday, so having the timestamp on it would allow you to recover the order later if you wanted to.
In conclusion of all that discussion, my suggestion to finding out who had wallet1 first would be this:
* get rid of the my-lists on every agent entirely.
Work with a single list defined as a global.
treat wallets as if they are real and only have one copy of a wallet at any one time.
define procedures "steal-wallet", "create-wallet" and "destroy-wallet" that move the wallet from one owner to another, and record the transaction as a sublist of 4 facts in the master list. The master list would be a list of lists then.
the master list might be named "transactions" because that's what it records.
then, conceptually, you would have all the information you need to answer any question about the life-history of a wallet or the life-history of a thief. You wouldn't have to maintain 20 different copies of the same information.
and it would be easy to look at all the thieves and see which one had the wallet, without needing to look at the transaction list. ( although, that information would correspond to the last entry in the transaction list about that wallet.)
Or -- maybe I totally misunderstand what these lists represent.
Passing the ball ( or wallet ) back to you.

Related

Modelling agent behaviour, where single agent operates under two conditions simultaneously

Any tips on how to model agent behaviour in an environment where two sets of rules apply simultaneously.
Specifically, what I am looking to simulate is a situation where an Agent operates under a specific set of rules, such as an employee-employer relationship, but at the same time, operates on perhaps different "informal" rules, such as an employee-employee relationship. Effectively there are two network structures in place, but the agent operates in both structures.
Any example models out there that I could take a look at?
(This is a model design question, not programming, so it probably belongs on the NetLogo user group instead of here.)
My colleague and I wrote a book on modeling decisions that are tradeoffs between competing objectives, in ABMs. It's focus is on ecology but the concepts could be useful for you.
The basic idea is to come up with an objective function that includes both "sets of rules" as you call them. Perhaps something like maximizing your relations with fellow employees without getting fired by the employer. Then build very simple models of how decisions affect the mechanisms that drive co-worker relations, probability of getting fired, etc. It's not simple, but it's very powerful and flexible. You won't find a simple approach that's very general.
The fun part is trying different variations and comparing how they work.
https://press.princeton.edu/books/paperback/9780691195285/modeling-populations-of-adaptive-individuals
Maybe I’m under-thinking this, but..I would encode both (all) sets of rules, and have the agent execute those rules as appropriate.
So, how to choose and execute rules?
Per social interaction:
Execute one behavior randomly based on which relationships are present
Choose one or more behaviors, as #1 and execute all of them in a specific order
As above, but execute behaviors in random order
For all possible behaviors, assign a probability based on whatever factors (number of role-members present, utility, consequence, etc l) Choose and execute one behavior randomly based on that probability (roulettes-wheel selection)
Choose more than one… execute in fixed or random order
Proportionate to the value of a “social-competence” property, Select a number of possible behaviors as #4. Then randomly select one of those to execute.
Here’s a code-segment example of #6
;; list of possible reactions
;; these are variables or reporters that report
;; an anonymous command that executes the behavior
Let action-list (list
boss-action
employee-action
coworker-action
peer-action
)
;; measure social situation
;; list of values from reporters
;; these are reporters that return a value
;; based on, for example, how many of that type of
;; relationship are present.
Let choice-list ( list
( probability-of-doing-boss-behavior )
( probability-of-employee-behavior )
( probability-of-coworker-behavior )
( probability-of-peers-behavior )
)
;; think about situation, choose possible actions,
;; as many times as social-competence allows.
;; roulette-wheel should return the index of the selected action
Let reaction-list (n-values social-competence
[ -> roulette-wheel choice-list ] )
;; choose an action from those options
Let action-index one-of reaction-list
;; execute that action
Run item action-index action-list
The same result as a single combined objective function might be a physics type model where the result of any single set of rules is a vector of some strength pushing ("nudging"?) the agent in some direction. Then you could have as many sets of rules as you want, each contributing it's own vector of force, and the final result would be a resultant combined net force and subsequent Newtonian F=m*a or rearranging acceleration = ( vector sum of forces )/mass.
I'm trying to imagine how I respond when the expectations of different groups I belong to clash, and whether a linear sum vector model describes it. I recall in college when I couldn't resolve Catholic support for the Vietnam War and "Kill for Christ" was a tongue-in-cheek slogan. I think in that case the "forces" didn't cancel out -- they resulted in ABANDONING membership in one of the groups to reduce cognitive dissonance. So, not a linear sum of zero in that case.
Another unstable human approach might be to keep going back and forth when two forces attempting to dominate behavior conflict -- first going with one a few steps then feeling guilty and going the other way a few steps. So which one dominates at any given step might depend on one's recent path and history and which one you "owed" something to. Or imagine being married to two people and trying to keep both of them happy. Maybe you partition space and Monday-Tuesday-Wednesday you keep one happy and Thursday-Friday-Saturday you keep the other happy and Sunday you go fishing.

Moving agents with other agents using Pickup/Dropoff from PML in Anylogic without duplicate code

Info: The question was updated with more explanation
I want to transport a agent (e.g. bananas) with a moving agent (e.g. truck) from place A to place B, where, for example, place A is where the bananas where plucked and place B is some storage for the bananas. So the bananas are simply being transported by the truck. Especially, the agent to be moved (the bananas) are not a resource (in the sense of Anylogic PLM) and have no upper amount limit.
There are various ways to solve this problem, but most of them either require some element in the model that I don't need or want (for example, a rack/pallet system in the case of the block 'Rack Store') or require the agents to be Anylogic resources.
As described in this answer, it kinda makes sense to use pickup and dropoff for this task. The problem is that the agent to be moved is not being transported, so that answer does not solve my question. To explain further, when the agent to be moved (the bananas) are being dropped off at the target location (place B), they simply re-appear at their original location (place A), even though the truck which picked them up via the pickup block has moved to place B.
I made a minimal example of this here.
As I described, the 'transportation' only works if I add the separate 'moveTo1' block for the dropped off agents.
Is there any simple and obvious way to handle this rather simple task of transportation in Anylogic without having multiple move blocks or other workarounds? I know there is 'ResourceAttach', but that requires the agent to be moved to be resources, and there is 'RackStore', which requires a rack/pallet system, which I don't need or want in my model.
What I want to know is what the 'standard' Anylogic way would be to do this.
Thanks a lot in advance!
Now I understand what your problem is...
When you use dropoff, the block that comes after it needs to define the new location of the agents, otherwise they stay in the same place.. You can use the moveTo block with a jump so the agents are teleported to the location you want them to be:
In almost all the blocks of the PML you can define the agent location in the properties, and this is a case where using that property is necessary.
You can set the position of the bananas to the position of the truck.
e.g. using agent.setXY(container.getX(), container.getY()) in the "On dropoff" field.
It seems to work for a simple test model.

Which agent executes a command given to an agentset first?

If I switch to turtle/patch context and do something like "set pcolor green", in what order do they execute the commands? I tested it out with a wait in there to see if there was an obvious pattern, but couldn't notice any. Is there any difference between that and ask?
I doubt it's completely random, though. How's it actually being handled behind the stage?
It's random--about as random as things get in computer programming, I believe. The NetLogo User Manual says:
An agentset is not in any particular order. In fact, it's always in a random order. And every time you use it, the agentset is in a different random order. This helps you keep your model from treating any particular turtles, patches or links differently from any others (unless you want them to be). Since the order is random every time, no one agent always gets to go first.
I just looked quickly at AgentSet.java in the source code for a recent version of NetLogo (5.0.2), it and looks to me like the order is randomized using a Mersenne Twister algorithm, which is usually considered to be quite good for randomization.
If you want the turtles/patches/links in a particular order, you can use sort, or select elements using e.g. with, or convert the agentset into a list using [self] of <agentset>, for example.

Sub-breeds in NetLogo

I am new to NetLogo and I have some questions about the following piece of code:
people-own [
walker-type ;; can be "cautious", "adaptive" or "reckless"
walked-through-red?
own-profit
adaptive-threshold-time-gained
adaptive-threshold-time-gained-people-crossing
adaptive-gone-reckless
cooldown
]
With an OO background, I see this as some kind of enumeration of the properties of an object (the people breed). You can clearly see that there are three types of people: cautious walkers, adaptive walkers and reckless walkers. Also, the properties beginning with adaptive (adaptive-threshold-time-gained and such) have only meaning when the current person is adaptive.
I would expect that there is some way to express this more elegantly. In an OO programming language you would use inheritance to create three subclasses (one for each walker-type), but for so far I know that doesn't exist in NetLogo.
What is the recommended way of expressing this?
Lack of inheritance (perhaps as sub-breeds) is a serious limitation of NetLogo, although in the end it has only occasionally mattered to me. There are a couple possible work-arounds, depending on the application.
If you just want some different data attributes, and the related types are the only turtles in the simulation, you can have turtles-own the common characteristics and have breeds-own only the type specific characteristics.
If the data attributes are all shared but the behavior differs, you can create your own agentsets (in your case, subsets of people) and call different procedures on each agent set (or write procedures that branch on a member? test). Unfortunately, these agentsets will have to be explicitly augmented if any new members are created, so you lose that nice "special agentset" feature of breeds.
hth.

Evolution of Setup Procedure

My question was, is there anyway through Netlogo to be able to include the Setup Procedure WITHIN the go procedure so that each iteration or TICK within the go procedure has a slightly different setup because of agent-evolution?
In my case in particular, i am modeling a flight leg where I have three airlines competing to find the best schedule for the flight during the day based on a utility model, and then a number of passengers that choose which flight is more appropriate for them with another utility model. My aim was to be able to vary the demand of passengers in each iteration through the go procedure even though this is dependant of the setup procedure and have the airline continuously vary their fees in order to attract more passengers and I feel I cannot do this because the Setup procedure limits me into only being to create one possible situation and doesnt allow for the evolution of my agents.
Thank you for your help, I really appreciate it.
The use of procedures named setup and go in NetLogo, and the pattern in which you typically attach them to buttons, is purely a convention. You can make as many procedures as you want, call them whatever you want, and have those procedures call each other in any way you want.
So for example, if you want to call setup from within your go procedure, go right ahead.
If your setup procedure calls clear-all, though, that might not be a smart thing to do. In that case you'd want to split the setup procedure into two separate procedures, where one of the procedures contains only the part you want to reuse. Something like:
to setup
clear-all
...
setup-environment
...
end
to setup-environment
...
end
to go
...
setup-environment
...
end