I am fairly new to Netlogo and have been working through Railsback & Grimms excellent book while trying my own stuff on the side
Currently, I am trying to code a kind of money transfer whereby two turtles meet (e.g. Turtle 1 and Turtle 2), and the two turtles then share money (e.g. T1 has $4 and T2 has $6, they both leave with $5)
The code I have tried using is as below
to currency-share
let neighbor one-of bystanders-here ; identify neighbor around
if neighbor != nobody ;; is there a neighbor? if there is
[ set currency round ((currency + neighbor currency) / 2)] ; share money
end
Unfortunately the code isn't working and I can't find any examples through the forums which use a similar idea. Perhaps I'm searching incorrectly (using key words like turtle exchange, share etc. normally comes up with patch sharing). If anyone has any models they could recommend where such exchanges happen, or if anyone knows how I may improve my code, please let me know. Thank you.
At first glance, this seems like a simple syntax problem. To get the currency of the neighbor, you should be using of:
set currency round ((currency + [ currency ] of neighbor) / 2)
But since you also said that you want both turtles to get the new amount, you also need to add:
ask neighbor [ set currency [ currency ] of myself ]
Or, perhaps less confusingly you could do something like:
set new-amount round ((currency + [ currency ] of neighbor) / 2)
set currency new-amount
ask neighbor [ set currency new-amount ]
One last variant, slightly better in my opinion because more general (and perhaps even clearer) is:
let sharers (turtle-set self one-of bystanders-here)
let new-amount mean [ currency ] of sharers
ask sharers [ set currency new-amount ]
In this last one, you don't even need the if neighbor != nobody check because if there are no bystanders, turtle-set will build an agentset containing only self and the mean currency of that set will just be the present currency value.
Related
With the use of the myself primitive, I want a patch with a certain land use to make buildings of that type in a specific radius, but it's not working. Here is the code:
patches-own [land-use] ;land-use can take many types: "residential", "industrial", "commercial"
...
to grow
ask patches with [land-use = "residential"]
[ask other patches in-radius 10 [
if [land-use = "residential"] of myself [build-house]]]
end
How can this be fixed?
The problem there is not myself but the use of of. Two things to fix:
of requires the reporter to be in square brackets. Only the reporter that of refers to, not the whole condition being tested (as in your case where you are testing a condition).
You should not specify the value of the variable but just its name. Just as in normal language: you wouldn't say "If your hair colour equals my blonde", but you would say "If your hair colour equals my hair colour".
The resulting syntax is:
if (land-use = [land-use] of myself) [
build-house
]
Parentheses surrounding the condition are optional, I use them as a stylistic choice.
PS Regarding point 2 above... of course you could keep the value of the variable (i.e. "residential") instead of the name of the variable (i.e. land-use), and in that case drop of myself.
You would have:
if (land-use = "residential") [
build-house
]
And as of now it would work because the patches starting this process are just those with land-use = "residential"... but this doesn't look like great code, as it is not extendable to other variable's values and it contains more hard-coding than necessary.
I have two breeds, let's say sellersA and sellersB, and an item that I want to create for one seller chosen either from a sellersA or sellersB.
Right now, therefore, I have
globals[
chosen?
]
breed [sellersA sellerA]
breed [sellersB sellerB]
sellersA[
catalogue
]
sellersB[
catalogue
]
and the item which has two attributes, attr1 and attr2. I initialised the catalogue in the setup: set catalogue [].
The following part of code should check if the catalogue is empty or not: if it is empty, a selected seller create a new item with some specific attributes (1 and 2):
let selected_one nobody
let customers nobody
set selected_one one-of turtles with [breed = sellersA or breed = sellersB]
ifelse empty? [catalogue] of selected_one [
create-items 1[ hide-turtle set new_item self set chosen? false]
ifelse [breed = sellersA] of selected_one
[ ask selected_one [
set attr1 random-float 1
set attr2 random-float
set function1 (1 + attr2)
]
]
[ ask selected_one [
set attr1 random-float 1
set attr2 random-float
set function2 (1 - attr2)
]
]
Then the seller add the item to its catalogue and to the catalogue of the customers connected with.
ask selected_one [
set customers (turtle-set self in-link-neighbors with [breed = sellersA])
ask customers [set catalogue fput new_item catalogue]
]
]
]
If the catalogue of a selected seller is not empty (i.e. the seller has items to sell), I would like to select one of the previous items created and track it (for example if one of sellers A created this new item and this item was added to its list and to its customers' list (neighbours), I would like to know how many customers from its neighbourhood selected its item).
For your previous answers to my questions, I know that I should use the extension rnd:weighted-one-of and, in order to select the item with highest value of one of the two attributes, I should create a new list with only indices that point to the attributes of the object created. This should require to use who. However, as result, I am getting only empty lists when I run show catalogue in the observer.
I think the problem might be in the definition of the item and of its attribute. I tried to define it as a breed with attr1 and attr2, but it did not work when I put the function as sellersA-own.
I would like to keep the code simple, but I do not know how.
I hope you can help me.
You don't show it, so I will assume you have a breed of items which have attributes:
breed [ items item]
items-own [
attr1
attr2
]
So sellers have catalogs, the catalogs list items, and the items have attributes.
It's not clear to me who "customers" are, or what attributes they have. They seem to be simply other sellers who have links to a given seller. Is that right?
Anyway, you asked
I would like to know how many customers from its neighbourhood
selected its item).
The phrase "its item" implies to me that items must have some additional attribute such as "creator". In any case, you don't describe what it means for a customer to have "selected" an item, or where you store such information, or where you store a history of who ever selected an item in the past -- so it's impossible to give advice on this question.
You also ask why this happens:
I am getting only empty lists when I run show catalogue in the
observer.
Well, "catalog" is not a global variable, it is an attribute of the sellers. You need to inspect the sellers to see if they have catalogs with the correct item or items in them, or ask something like
ask sellersA [ show catalog ]
but more probably, you want to open an inspector window and leave it open so you can watch what's going on.
inspect one-of sellersA
But, however you do it, you may still find that no sellers have catalogs with any items in them. You should look to see if any items have been created, as they are global and you should be able to see them in the observer, or inspect them, or simply count them.
Actually I don't understand how the code you listed above could possibly work. Your code has
[ ask selected_one [
set attr1 random-float 1
set attr2 random-float
set function1 (1 + attr2)
]
where selected_one is a seller, who does not own attributes or functions. You're not in the context of an item so I would expect the command "set attr" to fail. Maybe that code is failing silently which is why you have no items.
After you run your code, are there any items that have been created?
I got 2 large sets of agentbreeds1 (villagers) and an equal amount of agentbreeds2 (houses). I am attempting to link these two together on a one-to-one ratio. So far I tried to do this by the following line, but I am not sure whether it does so correctly:
ask villagers [
create-link-with one-of other houses
]
Just for clarity, if I have villager1 it may only connect to one house that does not have any link to another villager already.
Hopefully one of the bright folks here can help me further!
Thanks in advance.
That's pretty close, but since you have no constraint saying something like "you may only create a link with a house that has no villager already" you will end up with some houses that have multiple villagers linked and some houses that have no villagers linked. All you have to do to correct that is to include that constraint, such that villagers may only link to a house that is not already linked:
ask villagers [
create-link-with one-of houses with [ not any? link-neighbors ]
]
To check that it worked, you can either visually inspect the links or run some variation of the lines below:
ask turtles [
if count link-neighbors != 1 [
show ("I am not linked to just one turtle.")
]
]
If any turtle is not linked to another, or is linked to more than one, it will print the line in quotes.
In my study, I'm trying to build a simulation representing of a real work setting, with the aim of creating knowledge on how make people feel better at work.
In particular, I'm modelling a scenario where people work for more than one team (do you work on only one project at a time? Many don't...). To do this, I'm working with NetLogo.
I'm having a problem with an ASK to a specific agent of a custom link-turtle-set. The point is that sometimes it reports an error, saying that "ASK expected input to be an agent or agentset but got NOBODY instead", but it should not arrive to that "ASK" without the agent to exist! What am I doing wrong?
The function is the following:
to TeamRecruiting
;; I ask non-complete teams to...
ask teams with [ teamsize != (count membership-neighbors) ]
[
;; ... count how many individuals they have...
let actualteammembers count membership-neighbors
;; ... to save locally how many individuals they can share...
let teamoverlap overlap
;; ... their target size...
let neededsize teamsize
;; ... and their identity.
let teamwho who
;; then I ask those individuals that have not yet more things than they can handle...
ask individuals with [ indMTM != (count membership-neighbors) ]
[
;; ... to save locally who they are...
let indwho who
let createdalink 0
;; ... then if some conditions have been met ...
if(some conditions)
[
;; I create a link (of my specific type) with the team...
create-membership-with team teamwho
;; I do the following because more than one individual could join the team teamwho in the same run of the function
ask team teamwho [ set actualteammembers (actualteammembers + 1) ]
set createdalink 1
]
;; if the association occurred, ...
if(createdalink = 1)
[
;; we ask all other teams to evaluate if the new connection violates their maximum overlap constraint between the team I am considering from the beginning of the function, and all other teams, in other words...
ask teams with [ who != teamwho ]
[
let numpaths 0
let team2who who
;; I count how many individuals say that they are shared by the two teams
ask individuals
[
if((membership-neighbor? team teamwho) and (membership-neighbor? team team2who)) [ set numpaths (numpaths + 1) ]
]
;; ... and if the number of paths is more than the maximum allowed overlap...
if(numpaths > teamoverlap)
[
;; I take the connection away...
ask membership teamwho indwho [ die ]
;; and I reduce the actual number of team members
set actualteammembers (actualteammembers - 1)
]
]
]
]
]
end
Thank you for your precious help!
I think that the problem is likely to be in the way you refer to the link you are asking to die. membership is an undirected link and so which agent is end1 and which is end2 depends upon the order in which the agents were created. The one with the lower who number is end1 and the other is end2. So, if the team agent was created after the individual agent, that particular link would be membership indwho teamwho. In general, using who numbers at all is bad practice, but the same problem would arise if you used the team and individual agents themselves rather than their who numbers.
Someone with more experience in the use of undirected links than I might have better advice on how to easily refer to an undirected link when you don't know offhand which agent is the older, but something like
ifelse (indwho < teamwho) [
ask membership indwho teamwho [ die ]
]
[
ask membership teamwho indwho [ die ]
]
should work. Using directed links obviates this problem as the creator agent is always end1 and the target agent end2. So, if membership links always are created by the individual, you'll always know that the individual is at end1.
Hope this helps.
Charles
I'm doing an ABM model on couple bargaining. On it, some turtles calculate their utility by taking account of common resources (which are possessed by the undirected link between a turtle and his couple). The link was created with
create-link-with turtle (who - 25)
and the utility is being calculated with
to W-Ut-compute
set utility ( Wworkprod * ([work] of my-links ^ (workneed / (workneed + houseneed))) * Mhouseprod * ([house] of my-links ^ (houseneed / (workneed + houseneed))))
end
The code checking worked, but the go button doesn't.
^ expected input to be a number but got the list [-2.1300000000000017] instead.
error while women 100 running ^
called by procedure W-UT-COMPUTE
called by procedure GO
called by Botón 'go'
How can I use the link values on its variables to do the turtles calculations?
Regards, thanks for your attention.
Since my-links is the agentset of all the turtle's links, [work] of my-links returns a list (albeit a list of only one item, since there is only one link).
If you want to extract the one link you're interested in from the my-links agentset, you can use one-of:
[ work ] of one-of my-links
As the name implies, this will randomly select one of the turtle's links. But since there should be only one anyway, it will always be the same.