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
]
]
Related
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!
Building my first ABM using Netlogo and have a problem involving ifelse statements and how to use them. I'm modelling agents response to flooded properties. The concepts are as follows:
If an agent is flooded, they will consider adopting protective measures (if they haven't already).
If an agent has adopted protective measures, and are flooded, the success of the measure is calculated.
My code is as follows:
to process-property
let $random-flood-number random-float 1
ask properties [
set flood-damage-list-consequent replace-item 1 flood-damage-list-consequent (item 1 flood-damage-list-initial * (1 - PLP-reduction))
set flood-damage-list-consequent replace-item 2 flood-damage-list-consequent (item 2 flood-damage-list-initial * (1 - PLP-reduction))'
ifelse $random-flood-number < probability-flooding
[
set flooded? TRUE
set number-of-times-flooded (number-of-times-flooded + 1)
if plp-adopted? != TRUE [
calculate-adoption-intention
]
]
[
set flooded? FALSE
]
]
ask properties with [plp-adopted? = TRUE] [
plp-reliability-analysis
]
end
to plp-reliability-analysis
if plp-abandoned? = TRUE [stop]
if flooded? = TRUE [
if number-of-times-flooded > 1 [
let plp-reliability-factor 0.77 ;;This variable represents the probability of success that Manual PLP will offer full reduction in damage. Taken from JBA (2012;2014).
ifelse random-float 1 < plp-reliability-factor
[
set plp-deployed-successful? TRUE
set PLP-reduction 0.25
set successful-flood-damage-reduction (sum flood-damage-list-initial * PLP-reduction)
]
[
set plp-deployed-successful? FALSE
set PLP-reduction 0.9
set unsuccessful-flood-damage-reduction (sum flood-damage-list-initial * PLP-reduction)
calculate-abandonment-intention
]
]
]
end
I have written the following code as an error check, which i keep getting:
if flooded? = FALSE and plp-deployed-successful? = TRUE [error["Properties should only deploy PLP when they are flooded"]]
I believe the problem lies in the ifelse statements in "plp-reliability-analysis" procedure. I'm new to Netlogo and am confused as to when to use an 'if' or 'ifelse' statement. If someone could explain and have a look at the above code i'd be very grateful.
Thanks,
David
The difference between if and ifelse is that:
if is used when you want to run some piece of code only under certain conditions
ifelse is used when you want to run some piece of code under some condition and a different piece of code if the condition is not met.
Have a look at this shortened version of your code. Note that I moved the opening bracket to the beginning of the line to line up the start and end of code blocks. I also put end bracket on the same line for very short code blocks, but the bracketing is the same as yours.
to process-property
let $random-flood-number random-float 1
ask properties
[ ifelse $random-flood-number < probability-flooding
[ set flooded? TRUE ]
[ set flooded? FALSE ]
]
ask properties with [plp-adopted? = TRUE]
[ plp-reliability-analysis
]
end
to plp-reliability-analysis
if flooded? = TRUE
[ if number-of-times-flooded > 1
[ let plp-reliability-factor 0.77
ifelse random-float 1 < plp-reliability-factor
[ set plp-deployed-successful? TRUE ]
[ set plp-deployed-successful? FALSE ]
]
]
end
You draw a random number and assign it to the variable $random-flood-number. Then you ask every property agent to compare that number to the value of probability-flooding. However, you never draw a new random number. So if it's true for one property, it will be true for all the properties. Given it is a flood model, that is presumably intentional as all houses are equally affected by flooding.
Imagine that a low number is drawn and they all get flooded. All the ones with plp-adopted? are then sent to the plp-reliability-analysis procedure. For all of them, the variable flooded? is true so the code block is run.
The first line is if number-of-times-flooded > 1. The first time a flood occurs, the number-of-times-flooded is changed from 0 to 1. That will fail the test (did you mean to use >= instead of > ?) and the remainder of the code will not be run. It will simply jump to the end bracket.
[ let plp-reliability-factor 0.77
ifelse random-float 1 < plp-reliability-factor
[ set plp-deployed-successful? TRUE ]
[ set plp-deployed-successful? FALSE ]
]
But for the second and later code, it will run and 77% of the properties will have the plp recorded as successful, and the others set to unsuccessful.
So, how do you end up with some properties having the combination of false flood? and true plp-deployed-successful?.
Now jump forward in time and 2 (or more) floods have occurred. A flood has just happened, so 77% of the properties with plp-adopted? have true plp-deployed-successful? This time, there is not a flood and all properties have flooded? set to false. Those with plp-adopted? are sent to the plp-reliability-analysis procedure. However, flooded? is now false so the code block does not run and they retain their values of plp-deployed-successful? from the previous run through.
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
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.
I'm writing a program which groups turtles into different groups.
I am trying to write a command where if there is a turtle in a different group within a 1 until radius of the turtle the command runs.
This is what I have
to confront
ask turtles
[if [ group ] of turtles in-cone 1 180 != group
[set color brown]]
end
However the command is coming out true even when there is not a turtle in a different group nearby.
may be something like :
to confront
ask turtles
if any? turtles in radius 2 [
if any? turtles in radius 2 with [group != [group] of myself][
set color brown
]
]
end
I don't know if it can work directly (I haven't test this code) but I think it's a way