I have a model with banks. Each bank is linked to all other banks by a special breed of undirected link called "riskshares". Each bank also has links to other types of agents.
Each bank has a list of countries where it operates. The list is called "op-countries-list", which does not have a fixed length, and both its length and countries are randomly picked. For example, one bank might have "op-countries-list" of length 5 = "Australia, Italy, Spain, Canada, Brazil", and another bank might have "op-countries-list" of length 2= "Italy, France".
Now: I need to change to "TRUE" one boolean attribute of the "riskshare" link, depending on whether there is one common country in the "op-countries-list" of the two banks linked by the "riskshare".
I have (among other things):
banks-own
[op-country-list]
riskshares-own
[same-country-op?]
And I am trying this approach:
ask banks
[
foreach op-country-list
ifelse member? op-country-list of other-end
[set same-country-op? of my-out-riskshare true]
]
With this, I get an "OF expected input to be a reporter" error. I think I should come up with a to-report procedure and then use it, but I am not sure how to do it in this case. In addition, I am not sure how to specify that I want other-end to look into the "riskshare" kind of link, and not all other links that the bank has.
Do you have any suggestions?
There is definitely a way to do it with foreach as you're getting at, but you might find map a little more appropriate in this case. map will iterate over items in a list and do "something"- in this case, you could check for membership in the list of interest. More detail in comments below:
breed [ banks bank ]
undirected-link-breed [ riskshares riskshare ]
banks-own [ op-country-list ]
riskshares-own [ same-country-op? ]
to setup
ca
random-seed 1
let possible-countries [ "CANADA" "USA" "FRANCE" "JAPAN" "AUSTRALIA" "SPAIN" "RUSSIA" ]
create-banks 5 [
; Pick some random countries
let n-countries random 3 + 1
set op-country-list n-of n-countries possible-countries
]
layout-circle turtles 8
ask banks [
set label op-country-list
; Build the links
create-riskshares-with other banks [
; Determine if the banks share an operating country
; Pull the country lists from each bank associated with the link
let bank-1-countries [op-country-list] of end1
let bank-2-countries [op-country-list] of end2
; Use map to iterate over each country of one bank and check its
; membership in the op-country-list of the other bank. Check if 'true'
; is found in the list
let any-true? member? true map [ cur_bank -> member? cur_bank bank-2-countries ] bank-1-countries
print member? true map [ cur_bank -> member? cur_bank bank-2-countries ] bank-1-countries
; Set same-country-op? according to the any-true condition
ifelse any-true? [
set same-country-op? true
set color blue
] [
set same-country-op? false
set color red
]
]
]
reset-ticks
end
This toy model (with the random-seed as is) gives an output like:
Which I think meets the conditions you outline. Hopefully that gets you pointed in the right direction!
Related
I try to move each agents to its related agents (defined by high trust connection and in my view) if there are any such agents, and else move the agent to one of its neighbours. However, I get the error "FACE expected input to be an agent but got NOBODY instead." and I don't know how to solve it. I think the use != nobody might cause the error. Any suggestions on how to solve this?
This is my code:
breed [ persons a-person ]
undirected-link-breed [ connections connection ]
connections-own [ trust ]
persons-own [ neighbours ]
to setup
clear-all
create-persons 10
[ setxy random-xcor random-ycor ]
setup-connections
reset-ticks
end
to setup-connections
ask persons
[
create-connections-with other persons
[ set trust 0.6 ]
]
end
to go
setNeighbours
movePersons
tick
end
to setNeighbours
ask persons [ set neighbours other persons in-cone 4 360 ]
end
to movePersons
ask persons
[
let highlyRelatedPersons (turtle-set [other-end] of my-out-connections with [trust = 0.6]) in-cone 4 360
let relatedPersons (turtle-set [other-end] of my-out-connections with [trust = 0.6])
ifelse any? highlyRelatedPersons
[
face one-of highlyRelatedPersons
]
[
let weaklyRelatedNeighbour one-of neighbours with [not member? self highlyRelatedPersons] ;select one of my neighbours that is not a highlyRelatedPerson
ifelse weaklyRelatedNeighbour != nobody
[
face weaklyRelatedNeighbour
]
[
face one-of relatedPersons
]
]
]
end
You are correct in what is causing the error
highlyRelatedPersons is an agentset and while an agentset can be empty, an agentset can never be nobody. one-of highlyRelatedPersons however, will be nobody if the agentset is empty, so you could use ifelse (one-of highlyRelatedPersons != nobody).
That said, is easier to just check if the agentset is empty by using any?:
ifelse any? highlyRelatedPersons
Your code also never actually creates any links for highlyRelatedPersons and relatedPersons is always empty. This means that the code will always return false on the first ifelse and move on to the second. Generally most turtles will have neighbours they can face, but sometimes there are none so they try to face one-of relatedPersons, which again causes a crash since relatedPersons is an empty agentset.
I would like to count the number of turtles stopped on the road, and I want to take that X coordinate information and let it be the queue length. The following is the sample program.
ask turtles with [ not right-end ] ;a flag "right-end" to the red turtle for differentiation to the other blue turtles
[
ask turtles with [ speed = 0 ] ;the speed is 0 means stopped
[
set top max-one-of turtles [who] ;get a turtle with biggest id
set topx [xcor] of top
set L count turtles with [xcor > topx] ; L is the queue length of Little's Law
]
]
I am having trouble understanding exactly what you want to do, but I think it is something like this:
to-report countRightmost ;global context
let ts (turtles with [speed = 0 and not right-end] )
let top max-one-of turtles [who]
let topx [xcor] of top
report count ts with [xcor > topx]
end
I have two agents, customers and manufacturers. Each of these turtles have a number of variables which some of them are defined global to be able to be assigned to agents of another type. I have defined this : If at the end of the year, the purchases of product 1 is higher than both products 2 and 3, that product is distributed in 3 more stores. The problem is that the loop does not work logically. What are defined in the commands are happening while reporter is not true!!
ask manufacturers [
if (product1purchases > product2purchases) and (product1purchases > product3purchases) [
set storesavailability storesavailability + 3
set Brandd 1
set color red
]
Why when the condition defined in for if is not true, the commands are executed?
Thanks
They aren't. You can prove that to yourself by adding print statements, like this:
ask manufacturers [
let _cond ((product1purchases > product2purchases) and (product1purchases > product3purchases))
print (word "_cond is " _cond)
if (_cond) [
print (word "within branch, _cond is " _cond)
set storesavailability storesavailability + 3
set Brandd 1
set color red
]
]
I am new to NetLogo and I am working on a deforestation model, where farmers are my agents. They have a ID variable (lotid-farmer) that matches a ID in the patches (lotid-patch) that they own. Basically, farmers check how much money and labor they have to deforest some forest patches or abandon some of their agricultural patches (pcolor = red) in their farms. By the end of the latter procedure, farmers have a "n-aband" value calculated, which is the number of patched they will abandon (randomly) within their farms (pcolor = yellow). This is the piece of code that was supposed to do that:
ask farmers [
...
if pcolor = red and lotid-patch = [ lotid-farmer ] of self [ ; Asks the farmer to randomly convert a # of the agricultural patches without maintenance to regrowth...
ask n-of n-aband patches [ set pcolor yellow ] ; ... among all agricultural patches own by the farmer
]
...
However, when I run the code, farmers start "abandoning" patches that they do not own. I think that is because I am not setting up a proper "restriction" when I use "ask n-of n-aband patches" but I thought that that should be implicit in the "if" statement I have in the line above, no? I have also tried:
ask n-of n-aband patches with [ pcolor = red and lotid-patch = [ lotid-farmer ] of self ] [ set pcolor yellow ]
But I run into a error:
A patch can't access a turtle variable without specifying which turtle.
error while patch 390 414 running OF
called by procedure CALCULATE-DEFORESTATION
called by procedure GO
called by Button 'Go'
Any suggestions on how to get this piece working? Thank you in advance.
To do this, you need to consider only patches owned by the farmer.
ask farmers [
let _id lotid-farmer
let _candidates (patches with [lotid-patch = _id and pcolor = red])
let _n-aband min (list n-aband count _candidates)
ask n-of _n-aband _candidates [set pcolor yellow]
]
But ... don't work with ids. Work with agents. Let each patch have an owner,
which is a farmer or nobody. Let each farmer maintain a list (or agentset)
of patches that it owns.
It supposes to be a simple code, but I don't know why it doesn't work properly.
I want to change a color of non-white turtle back into white if a condition is fulfilled. I put inequality as the condition.
for example, if the amount of red turtle > = 5, then [ do something ].
No error message for the code, but I found that [ do something ] codes are executed before the condition is fulfilled. For example, it is executed when the amount of turtle is 1 or 4. And I also found that there are moments when it reach > = 5, [ do something] code is not executed.
Below is the code
to seize-value
ask consumers [set type-of-value ( list blue red green) ]
foreach type-of-value [
if count consumers with [color = ?] > = 5 [
let z consumers with [color = ?]
ask z [ set color white ]
ask consumers with [color = white] [set value? false]
ask one-of cocreation-patches [ sprout 1 [gen-prevalue]]
]]
end
I've tried using a single color, instead of a list of color (without - foreach) it doesn't work either.
Can anyone help with this?
Thank you
You have something like the following at the top of your code to set up type-of-value as an agent variable:
breed [ consumers consumer ]
consumers-own [ type-of-value ]
However, you are treating it as a global variable in your code. First you say ask consumers [set type-of-value ( list blue red green) ] to set the AGENT variable called type-of-value to the list of colours. But you end that ask [] statement before starting the foreach.
Unless the consumers have different lists of colours, what you really want is something more like this (untested). Note that I have also removed your multiple creations of the same agentset (for efficiency):
globals [ type-of-value ]
to setup
clear-all
...
set type-of-value ( list blue red green)
...
reset-ticks
end
to seize-value
*type "seize-value on tick " print ticks
foreach type-of-value
[ let changers consumers with [color = ?]
*print ?
*print count changers
if count changers >= 5
[ ask changers
[ set color white
set value? false
]
ask one-of cocreation-patches [ sprout 1 [gen-prevalue] ]
]
]
end
UPDATE for debugging I have added three lines that will output key information for debugging. They are marked with an asterisk (*). Add those lines (without the *) and look at the output.