how to call properties of other agents who are connected to each other - netlogo

Greeting,
let assume, I have one manufacture and 10 customers that manufacture create links with some of them randomly(I call these links "contract-links").
One of the properties of manufacture is "real-cost" and one of the properties of customers is "real-waiting-time". "real-waiting-time" is a clear number. Also, Assume service-cost as a global variable.
To calculate the "real-cost", I need the sum of "real-waiting-time" of customers who have links with the manufacture and then multiply in service cost.
I have a question here to calculate "real-cost". How can I call the "real-waiting-time" of all customers and then calculate the real-cost for manufacture?
manufactures-own [ final-costs]
customers-costs [ real-waiting-time]
contract-links [ the-real]
ask manufactures [
final-calculation-for-manufacture
]
to final-calculation-for-manufacture
let the-manufacture self
let the-contract my-contract-links
ask my-contract-links [
set the-real [real-waiting-time] of end2
]
let the-sum sum [ the-real] of my-contract-links
set final-cost the-sum * cost-service-slider
end
It gives me a number, but the answer is wrong.

I think the reason that you are getting the wrong number is that you are doing a lot of setting of the attribute values at the other end of the links instead of getting the information from that link. But your general approach is too complicated - if you have created a link breed called contract-links (which you seem to have), then the agents at the other ends of those links are the link neighbors of agent asking. Try something like this.
manufactures-own [ final-costs]
customers-costs [ real-waiting-time]
contract-links [ the-real]
ask manufactures
[ let the-sum final-costs sum [real-waiting-time] of contract-links-neighbors
set final-cost the-sum * cost-service-slider
]
end
This assumes you want the sum of the waiting times of the linked customers. I couldn't work out what the attribute the-real is for the links.

Related

Get a count of turtles with a combination of values

I am trying to count the number of "buyer" type turtles, which have a certain surplus (turtle variable) greater than or equal to zero, and price (another turtle variable) greater than the current turtle's price (already grabbed in local variable myprice...although there may be a more direct way to put it in)
let countup count buyers with ([surplus >= 0] and [price > myprice])
NetLogo returns
Expected a TRUE/FALSE here, rather than a list or block.
let countup count buyers with (surplus >= 0 and price > myprice) returns
WITH expected this input to be a TRUE/FALSE block, but got a TRUE/FALSE instead
Close! You're looking for:
let countput count buyers with [ surplus >= 0 and price > myprice ]
with is a report that takes two arguments, like so
<turtleset> with <report block>
where the reporter block is a clump of code surrounded by [ ] that will result in either true or false. In general [ ] is netlogo's way of grouping together code so you can doing something special with it, such as having each agent in an agentset run it. Hope that helps!
Also, I assume you've got something like let myprice price on, say, the line above this one. You can combine those lines like so (not saying this code is the right way to do it, just wanted to show another option):
let countput count buyers with [ surplus >= 0 and price > [ price ] of myself ]
Checkout the docs for (the very poorly named) myself.

Netlogo Coding - IF codes

here is the issue that I am facing in Netlogo. I want a turtle to check one of its own variable and another variable of the other turtle (different breed). based on these 2 two values I want to set a reward for the turtle. Let's say that I have "student" and "teachers" as two breeds. Students may "cheat" (binary) and teachers may catch (binary) - so based on whether they cheat and get caught or not an appropriate reward would follow. I am trying to incorporate this by the following code
if comply? = 1
[
ask students [ set gain reward1 ]
]
if comply? = 0 and caught? < random-float 1
[
ask students [set gain reward2 ]
]
if comply? = 0 and caught? > random-float 1
[
ask suppliers [set gain reward3 ]
]
end
gain is a student own variable and caught? is a teacher-own variable which represents the chances that the teacher may catch a student.
When I run the model there is an error "STUDENTS breed does not own variable CAUGHT? error while running Student1 running Caught?
I was wondering if someone can share some insights about this?
Thanks
Deb
STUDENTS breed does not own CAUGHT? : Insight
When the ownership error pops up, usually, the issue is that a turtle, or in this case student, referenced a variable that does not belong to their breed. Below is an example of how I imagine the model was initialized for your code, along with a passing and failing example.
breed [ students student]
breed [ teachers teacher]
students-own [ gain comply?]
teachers-own [ caught? ]
... ; initialize
to go
ask students [ set gain 3 ] ; this passes
ask students [ set caught? 3 ] ; this fails
end
The importance of context
Most likely your issue is related to adding conflicting variables in a procedure for students. (Example below)
to listen-in-class ; student procedure
if comply? = 0 [ set gain 7 ]
; the comply? variable assumes a student is calling the procedure
if gain = 3 [ set gain 4 ]
; The gain variable assumes a student is calling the procedure
if caught? = 0 [ set gain 2 ]
; The caught? variable assumes a teacher is calling the procedure
end
Since procedures can call other procedures, each procedure assumes their environment (context) from the variables/procedures.
to starting-class ; should be a student procedure
ask student [ listen-in-class ]
; "ask student" assumes listen-in-class only takes global or student only variables
end
Most likely, it could be that the wrong set of variables for a procedure was added. Asks tend to limit the scope of variables depending on the breed.

Is it possible to have enumerated data types in NetLogo?

Is it possible to have enumerated data types in NetLogo?
Let's say that I have a model of marital status change.
An agent can have 3 marital status states: single, married, divorced.
I would like to map those states into numbers so that it takes less memory when executed.
single = 1
married = 2
divorced = 3
so that I can just do
ask agents with [ marital-status = single ][ get-married ]
I have found a trick to do that with "to-report"
eg:
to-report single
report 1
end
But this means I have to create many to report functions if I were to have many categories in many variables. Is there a better workaround than this?
Thanks :)
How big is your model? My understanding is that an agent attribute is minimum 8 bytes anyway (see https://github.com/NetLogo/NetLogo/wiki/Optimizing-NetLogo-Runs)
I can't think of a natural way to do this. However, if you really wanted to, this workaround would work: store the marital status as 0, 1, 2. Also store a global variable called marriage-status-map and use the item primitive. So it would look like this:
globals [ marriage-status-map]
turtles-own [ marriage-status ]
to testme
clear-all
set marriage-status-map ["single" "married" "divorced"]
create-turtles 10
[ set marriage-status random 3
setxy random-xcor random-ycor
set color blue
]
ask turtles with [item marriage-status marriage-status-map = "single"] [set color red]
end

Associating turtles and links through attributes

I have a road network consisting of directed links between nodes. Cars drive over the network on paths that are randomly generated at setup but remain fixed for the duration of travel. I want to count the number of cars on any given link:
breed [cars car]
breed [road_nodes road_node]
directed-link-breed [road_segments road_segment]
cars-own [current-road-segment]
road-segments-own [number-cars-here]
I'd like the value of number-cars-here for road_segment x y to be number of cars with current-road-segment = "road_segment x y". Is there any way to do this? Thanks.
It is probably best to count them all at one go:
to count-cars ;;observer proc
ask road_segments [set number-cars-here 0]
ask cars [
ask current-road-segment [
set number-cars-here (number-cars-here + 1)
]
]
end

NetLogo : what is a good way for Storing link values and deducting the dead link values without calling links more than 1 time?

I am sorry to keep asking about links, but one of the features that I am going to add to my model is considering collective mutual relationship of people of different villages in village's future relationships,
I have a few thousand links and it's not efficient to call links and get their value whenever the village wants to make a decision (the decision is made every 48 ticks at clock 0)
Agents own belongs_to which is one one "Village1" Village2" Village3" or "Village4"
Links have a Value of Relationship.
This is the function I used to update links value:
to Update_link_Values [Other_Agent Value]
if self != Other_Agent
[
ifelse out-link-neighbor? Other_Agent
[
ask out-link-to Other_Agent
[
set Value-Of-The-Relationship Value-Of-The-Relationship + Value
set-List-of-Mutual-Obligations
]
]
[
create-link-to Other_Agent
[
set Value-Of-The-Relationship Value-Of-The-Relationship + Value
set-List-of-Mutual-Obligations
]
]
]
end
if I use following formula to store sum of relationship values for different villages it takes 0.003 MS to calculate all mutual relationship values
if [belongs_to] of end1 = "Village1" and [belongs_to] of end2 = "Village2"
[
set List-of-Mutual-Obligations replace-item 0 List-of-Mutual-Obligations (item 0 List-of-Mutual-Obligations + Value-Of-The-Relationship)
]
While this one takes 1.002 MS to execute,
if [belongs_to] of end1 = "Village1" and [belongs_to] of end2 = "Village2"
[
set List-of-Mutual-Obligations replace-item 0 List-of-Mutual-Obligations sum [Value-Of-The-Relationship] of links with [[Belongs_to] of end1 = "Village1" and [Belongs_to] of end2 = "Village2"]
]
my problem with first version is that it adds the value of each link to sum of all values of previous links in that group and does not consider if a link is dead or not, but second one is more accurate.
Since Value of relationship is link property I don't want to ask links more than once in the code and I update the sum values whenever a link is being changed or created.
I thought it might be better to update the values every 48 ticks , since many agents might call this function every tick, but for doing that I have to call links and I am not sure which way is better?
Update:
I have changed my code so I will calculate the links I need whenever a decision is made:
to-report Value-of-Mutual-Obligations [Village1 Village2]
report sum [Value-Of-The-Relationship] of links with [[Belongs_to] of end1 = Village1 and [Belongs_to] of end2 = Village2]
end
Another way of thinking of it.
Create a breed for the Villages.
breed [ villages village ]
Create new link breeds, one for the villages, and one for people. (you can't use the built-in links breed when you have any custom links breed):
directed-link-breed [ village-links village-link ]
directed-link-breed [ person-links person-link ]
give village-links a variable VALUE-OF-MUTUAL-OBLIGATIONS
give the villages a variable VALUE-OF-SELF-OBLIGATIONS -- this is to handle cases where both persons are from the same village -- sadly, netlogo does not allow self-links.
Create a village turtle for each village. They can be hidden. You can apply the name of the village ("Village 1") to the label of the village.
Link all the villages to each other, in both directions.
A person's belongs-to contains a village turtle.
e.g. to randomly assign a village:
set belongs-to one-of villages
So, now, rather than having to calculate the value of mutual obligations wholesale, you can alter it directly, as it changes.
Whenever you change the value of a link, you can also change the VOMO variable for the village link. You use the who numbers of the villages to figure out the link ID, or to use the SELF-OBLIGATIONS version in that special case.
to update-relationship-value [ #value ] ;; run by the person's LINK
set value-of-the-relationship value-of-the-relationship + #value
let from-village [ belongs-to ] of end1
let to-village [ belongs-to ] of end2
ifelse from-village != to-village
[ ask village-link ([who] of from-village ) ([who] of to-village)
[ set value-of-mutual-obligations value-of-mutual-obligations + #value
]
]
[ ask from-village ;; update self-obligation value
[ set value-of-self-obligations value-of-self-obligations + #value
]
]
end
So, you only touch the value of mutual obligations once, when you update the relationship value.
You could probably make this slightly more efficient by extracting the village link update code so that it's run by the turtle, not by the link, so that you don't have the extra "[stuff] of end1" stuff.