I need help!
So I want to specify a parameter in the agents own as an average of the values of a parameter in links-own.
frienships-own [strength]
household-own [ influence-factor]
to create-influence
if friendship = TRUE
[
ask household
[
if count my-links > 1
[
set influence-factor (sum [strength] of link-neighbors) / (count my-links)
]
]
]
end
I tried this but doesn't do anything. The idea is to specify the variable "influence-factor" as an average of the variable "strength" which is a variable owned by the households with unidirectional links to other households.
Thanks!
Related
I have 2 turtles bread:
globals [ max-applicant ]
breed [ applicants applicant ]
breed [ investors investor ]
applicants-own [ ask-amount applied? industry country-of-origin funded? ]
investors-own [ allowed-industries-list allowed-countries-list no-of-applicants-funded ]
I want to perform a transaction based on whether the investor is allowed to do business with the applicant's industry and country of origin. An Investors can only perform a limited number of transactions based on the max-applicant value
In the code below, I'm trying to select an investor that hasn't reached the max transaction limit and then select an applicant that meets the conditions of the selected investor and fund that applicant:
to close-deal
let investorPerson one-of investors-here with [no-of-applicants-funded < max-applicant]
if investorPerson != nobody [
ask investorPerson [
let applicantPerson one-of applicants-here with [
industry member? [allowed-industries] and country-of-origin member? [allowed-countries] of myself
]
if applicantPerson != nobody [
ask applicantPerson [
set funded? TRUE
]
]
set no-of-applicants-funded no-of-applicants-funded + 1
]
]
end
This code doesn't run. is this the right way to design this operation?
There seem to be two problems:
See here the syntax of member?: it is member? value list, while in your code you have value member? list.
In the first of the two boolean statements where you use member?, you omitted the of myself that should address [allowed-industries].
Combining the two points above, you should have:
let applicantPerson one-of applicants-here with [
(member? industry [allowed-industries] of myself) AND (member? country-of-origin [allowed-countries] of myself)
]
The use of parentheses and the capitalisation of boolean operators are optional, just my own stylistic choice.
Side note: be aware that you are asking your investorPerson to
set no-of-applicants-funded no-of-applicants-funded + 1
outside of the command block that gets executed if there actually is an applicantPerson; i.e. your investors will increment no-of-applicants-funded even when applicantPerson = NOBODY.
I have two turtle breeds (products and consumers) each with a 3-dimension list that defines their needs (consumers) and their attributes (products).
What I'd like is to have each consumer (i) look for a product that satisfies all their needs and create a link with them. If that product does not exist, I'd like them to (ii) drop the one need with the lowest value and look for a product that satisfies the other two. If that product does not exist, then I want them to (iii) look for another one that only satisfies the need with the highest value.
So say that consumer 20 has needs [0.2 0.5 0.3]. If they find a product whith exactly the same list of attributes [0.2 0.5 0.3] I want the link to take place. If there's no such product then I want the consumer to ignore the lowest value (0.2 in the example) and look for a product that has attributes [xx 0.5 0.3], where xx stands for "whatever".
Using examples from elsewhere here in SO, I have cobbled up the following code that (almost!) does the first part of the trick (i), but can't manage to do (ii) and (iii) despite multiple efforts. Would anyone have an indea on how to do this?
breed [consumers consumer]
breed [products product]
consumers-own [
needs
]
products-own [
attributes
number-buyers
]
to setup
ca
create-consumers 100 [ setxy random-xcor random-ycor]
create-products 100 [ setxy random-xcor random-ycor]
set-default-shape consumers "person"
set-default-shape products "box"
ask consumers [
set needs n-values 3 [ precision (random-float 1) 1 ]
]
ask products [
set attributes n-values 3 [ precision (random-float 1) 1 ]
]
reset-ticks
end
to go
buy
tick
end
to buy
ask links [ die ]
ask consumers [
carefully [ create-link-with one-of products with [reduce and (map = attributes [ needs ] of myself)] ] [ show "how do I find a sub-optimal product by ignoring my need with the lowest value ?" ]
]
ask products [
set number-buyers count link-neighbors
]
end
You are overthinking the full match - just check if the two lists are the same. However, the almost match is a bit more complicated. Here is a complete example model that finds the position in the list of the lowest and then checks that the other items are the same.
breed [consumers consumer]
breed [products product]
consumers-own [
needs
]
products-own [
attributes
number-buyers
]
to setup
clear-all
ask patches [set pcolor white]
create-consumers 10
[ setxy random-xcor random-ycor
set shape "person"
set color blue
set needs n-values 3 [ one-of [1 2 3] ]
]
create-products 10
[ setxy random-xcor random-ycor
set shape "box"
set color red
set attributes n-values 3 [ one-of [1 2 3] ]
]
reset-ticks
end
to go
ask consumers [buy]
tick
end
to buy ; set up as turtle procedure for testing purposes
ask my-links [ die ]
let candidates products with [attributes = [needs] of myself]
ifelse any? candidates
[ create-link-with one-of candidates ]
[ type self type " attributes: " type needs print " no matches"
let lowpoint position (min needs) needs ; note will take first if two equal min
set candidates products with
[ ((item 0 attributes = item 0 [needs] of myself) or lowpoint = 0) and
((item 1 attributes = item 1 [needs] of myself) or lowpoint = 1) and
((item 2 attributes = item 2 [needs] of myself) or lowpoint = 2)
]
ifelse any? candidates
[ create-link-with one-of candidates ]
[ print "no almost-match available" ]
]
end
I created the agentset (called candidates) of potential products to link to and then created the link. This makes the code much more readable. It also allows the if any? construction if no matches were found. And it also makes it easier to debug because you can put print statements reporting numbers of matches and similar. I recommend that you always do this if you are applying some sort of condition that restricts the choices.
Also, you have a three item list with 10 possible values for each item. This means there will be 1000 combinations. You only have 100 consumers and 100 products, so matching will be fairly rare.
Background
I used this answer to select a turtle based on a probability distribution determined by the turtle's popularity or fitness.
Issue
I am trying to pass a parameter that determines which of the turtle's property the probability distribution is determined by.
Question
How can I perform an equivalent of a "python unpacking" of a parameter in netlogo?
Sample code
turtles-own
[
fitness
strength
degree ;;Node's Connectness
popularity
wealth
]
to-report pick-turtle-biased-by-property [turtle-list property-to-unpack]
let prob-list []
let turtle-list []
ask turtles [
set prob-list lput [[property-to-unpack] of self ] prob-list
set turtle-list lput self turtle-list
]
report first rnd:weighted-one-of-list (map list turtle_list prob-list) last
end
The key to what you're trying to do is to use "anonymous reporters" for passing the "property to unpack". See the Anonymous procedures section of the programming guide.
Here is a full example:
extensions [ rnd ]
turtles-own [
strength
wealth
]
to setup
clear-all
create-turtles 10 [
set strength random 100
set wealth random 100
]
end
to go
print pick-turtle-biased-by-property [ -> strength ]
print pick-turtle-biased-by-property [ -> wealth ]
end
to-report pick-turtle-biased-by-property [ property-to-unpack ]
let pairs [ (list self runresult property-to-unpack) ] of turtles
report first rnd:weighted-one-of-list pairs last
end
Is there an equivalent of the command one-of that does all agents? So an all-of command? I need my agents to ask specific other agents to sum and report back a value. The one-of command will only randomly select one other agent but I need to select all agents on a list.
Details: I need my household agents to to ask other householdagents to sum and report back their HHwaterUse value. Each household agent will ask all other agents on their SocialNetwork list. The SocialNetwork list is composed of a Public_ID values, which is a value that each agent possesses.
Ex: So if household-1 posses a SocialNetwork list that looks like [9126 3495 4197 8771], I need all agents with a Public_ID value of 9126, 3495, etc to report back their HHwaterUse value.
ask households [
set NetUseSum sum [HHwaterUse] of households with [[Public_ID] of myself = all-of [SocialNetwork] of self]
]
The member? primitive should work, check out the dictionary entry for details. Here is an example where just a single household checks the sum of its social network's water use:
breed [ households household ]
households-own [ Public_ID Social_Network HH_Water_Use]
to setup
ca
create-households 10 [
setxy random-xcor random-ycor
set Public_ID 1000 + random 1000
set HH_Water_Use 100 + random 50
]
ask households [
set Social_Network sort [Public_ID] of n-of 4 other households
]
reset-ticks
end
to sum-social-network
ask one-of households [
show ( word "My social network comprises: " Social_Network )
ask households with [ member? Public_ID [Social_Network] of myself ] [
print ( word Public_ID " has a water use of " HH_Water_Use )
]
let social_sum sum [HH_Water_Use] of households with [ member? Public_ID [Social_Network] of myself ]
print ( word "My social network has a sum water use of " social_sum )
]
end
Edit:
Just a note that I agree with Nicolas and Jen above- this is definitely not the best approach. Use their link or agentset suggestions instead if possible.
That worked, Luke C's suggestion of using the member? snippet did the trick. I was able to sum, all at once, the value from the list of agents.
let social_sum sum [HH_Water_Use] of households with [ member? Public_ID [Social_Network] of myself ]
how can i create a dynamic number of breeds at runtime?
I want my user to be able to choose the amount of breeds.
I thought about something like
to setup_breeds
let j 1
while[j <= n_groups][
breed[j]
]
end
where n_groups is the number of breeds whick is taken from a slider.
But unfortunatly i cannot use breed inside a method...
Any ideas?
Thanks!
You need to explicitly declare each breed with the breed keyword, so the short answer is: no, you can't have a dynamic number of breeds.
But do you really need actual NetLogo breeds? The main purpose of having different breeds is to have different variables for each breed. If that is not case, perhaps you can get away with having a group-id turtle variable. To create a certain number of turtles for each of n_groups, you could just do something like:
turtles-own [ group-id ]
to setup
clear-all
let n_groups 10
let n-turtles-per-group 5
foreach n-values n_groups [ ? ] [
create-turtles 10 [ set group-id ? ]
]
ask turtles [ set label group-id ]
; do something with only turtles of, e.g., group 2:
ask turtles with [ group-id = 2 ] [
fd 5
]
end
If you think you really need breeds, edit your question to tell us why, and we'll see if we can find a solution for you.
Side note:
I used foreach n-values n_groups [ ? ] to loop through your n groups. That's the equivalent of:
let i 0
while [ i < n_groups ] [
set i i + 1
]
...but arguably more "NetLogo-ish".