Hi everyone, So I am trying to solve a netlogo model where there are nodes linked to each other. Its a search and rescue based model where there are two types of agents population-agents and rescue-agents, whom are placed on a node.
Similar to the image below, where orange and purple nodes represent nodes on which there is an pop/resc agent. The Rescue-agents need to find the closest population agent based on the links distance, and travel to them. The link distances for example are the numbers shown on the image below. (Note the idea is not to use min-one-of in-radius command which will give the closest distance as to the closest link distance)
Any idea on how to find the closest population agent to each resc-agent?
This is a job for the networks extension, which contains the primitives nw:turtles-in-radius and nw:weighted-distance-to to calculate distances along links.
Yep managed to solve the problem. But it involves making many list. If ANY ONES GOT A BETTER SOLUTION OR IMPROVING THE FOLLOWING CODE. PLS DO LET ME KNOW. THANKS :)
I managed it to solve it by creating 3 lists,
1. a list for all the population agents (N-pop-list)
2. a list for all the nodes the population agents are on (N-pop-node-list)
3. and a list for distances, where each node will calculate the distance from itself to the node the pop-agents on. (N-pop-distance-list)
globals [G-target-agent G-node-target-agent]
breed [pop-agents pop-agent]
breed [resc-agents resc-agent]
breed [nodes node]
pop-agents-own [node-pop (;node the pop agents on)]
resc-agents-own [node-resc (;node resc-agents on) target-agent (;agent they want to
travel to) target-pop-agent-at (;node target-pop-agents on)]
nodes-own [N-pop-list N-pop-node-list N-pop-distance-list]
links-own [dist (pretty much length/distance of the link !)]
...
to setup-lists
ask nodes [
let temp-pop-list []
let temp-pop-node-list []
set N-pop-distance-list []
ask pop-agents[
set temp-pop-list lput self temp-pop-list
set temp-pop-node-list lput node-pop temp-pop-node-list
]
set N-pop-list temp-pop-list
set N-pop-node-list temp-pop-node-list
foreach N-pop-node-list
[[i] ->
let dist-to-node nw:weighted-distance-to i dist
set N-pop-distance-list lput dist-to-node N-pop-distance-list
]
]
end
to search-pop-agent
ask resc-agent[
ask node-resc[
let min-val min N-pop-distance-list
let min-val-pos position min-val N-pop-distance-list
set G-target-agent item min-val-pos N-pop-list
set G-node-pop-agent-at item min-val-pos N-pop-node-list
]
set target-agent G-target-agent
set node-pop-agent-at G-node-pop-agent-at
]
end
Related
This is the code of a 2 player game that I manipulated
o play-the-game
if (any-friends-nearby?) [gain-energy]
if (any-opponents-nearby?) [fight-opponent]
end
to-report any-friends-nearby?
report (any? (turtles-on neighbors4) with [breed = [breed] of myself])
end
to-report any-opponents-nearby?
report (any? (turtles-on neighbors4) with [breed != [breed] of myself])
end
to gain-energy
set similar-nearby count ( turtles-on neighbors4 )
with
[color = [color] of myself]
set total-nearby count (turtles-on neighbors)
;
;
if (similar-nearby >= total-nearby - similar-nearby)
[set energy energy + 5]
end
to fight-opponent
let my-breed [breed] of green-players
let my-color [color] of green-players
let opponent-breed [breed] of red-players
;
;;
ask my-breed
[check-random-winner]
end
to check-random-winner
let pick random-float 2
let winner nobody
ask turtles
[if winner = nobody
[ ifelse size > pick
[set winner self ]
[set pick pick - size] ] ]
end
to change-opponent
ask red-players
[ set breed green-players
set color green ]
end
Sorry if it's a bit long but when I setup up and then press go "ASK expected input to be an agent or agentset but got the list [green-players...]"
How can I fix this?
Also I'm very new to Netlogo and StackOverflow, apologies if I haven't asked my question properly.
The error message tells you that you are passing a list (more specifically, a list of breeds) to ask, when it comes to ask my-breed.
This is because the my-breed local variable is determined by
let my-breed [breed] of green-players
Let's see what we have there:
breed is a turtles-own variable: it holds the turtle's breed, and being an agents' variable can be used as a reported in the of construct (see below).
of is a reporter: it takes a reporter (normally an agents' variable) on its left (in your case: breed) and either an agent or an agentset on its right (in your case: green-players). What of reports (i.e. what it outputs) is...
... a single value if there is an agent on the right.
... a list of values if there is an agentset on the right*.
*Think about it: if I ask the color of your eyes (you are a single person, i.e. a single agent), you will tell me a single color. But if I ask the color of your friends' eyes (your friends are a group of people, i.e. an agentset), the only way for you to answer my question is to tell me a list of colors.
green-players is an agentset: all of the agents whose breed is green-players (note that for NetLogo green-players is an agentset even if it contains 1 or 0 agents).
From this, we can see that in this case of reports a list of breeds, because it reports the breed of every agent that is part of green-players, hence it will report the list [green-players green-players green-players green-players ... ] which is as long as the number of green-players in the model. You can verify this by clicking setup and then running [breed] of green-players in the Command Center.
This is a list of breeds (which can also be seen as a list of agentsets), which is not an agent or an agentset (which are the only possible targets of ask).
((note that the exact same thing happens with let my-color [color] of green-players and let opponent-breed [breed] of red-players))
So, how do you construct an agentset based on a variable? The most common way to do it is by using with (read here why).
But how can you fix your code? I don't know because I don't understand what you want to achieve.
I am not sure how you would want to use it in the code you posted, as I'm not even sure you need to use ask in fight-opponent (let alone ask an agentset).
Your fight-opponent procedure is such that, apart from the problem we just discussed, the "my-" things (i.e. my-breed and my-color) always refer to the green players while opponent-breed always refers to the red players - even if fight-opponent is run by a red player! And also, it is not clear what you want to achieve with the check-random-winner procedure and if you want this procedure to be ran by an entire breed. These things make it quite confusing to understand how you could want to fix the fight-opponent procedure.
For example: who do you want to run the check-random-winner command?
A combination of two things would be beneficial: develop your model one step at a time and make sure that every new little piece of code does exactly what you expect it to do; also, when you ask for how to fix something it is useful that you explain what you want your code to do. By doing these two things I believe it will be a lot easier to answer your questions
The final part of my design involves me recording down anytime a car breed drives into or in netlogo terms, is on the same patch or X and Y coordinate as the people breed as they navigate across the edge of the screen. Had this been java I could've done something like
if Car.xPostion == Person.xPostion
(Do something...)
But unfortunately I do not know how to do the same in NetLogo, all I've been able to do so far is just ask the two breeds by giving every turtle a boolean variable called movable and setting them to true and the rest to false, is there anyway I can check the two coordinates of two different turtles on Netlogo? This is all I 've been able to do so far.
to record-accidents
ask turtles with [movable? = true]
[
]
If you tried something like your java approach, it would fail because turtle positions are continuous and floating numbers are nearly always not equal.
If I have understood your question correctly, you have given a boolean variable called movable? set to true for cars and false for all other breeds. You don't need to do this, turtles know their own breed so you can do ask cars.
To answer your specific question, there are several ways to approach it depending on the perspective (sort of, which agent is in charge).
You could identify patches where there are accidents:, which is the answer to your question in the title (about identifying patches with two breeds).
let accident-locations patches with [any? people-here and any? cars-here]
if any? accident-locations
[ ask accident-locations
[ <do something>
But you can also take a turtle perspective. You could start from pedestrians who have been hit. This takes advantage of the fact that turtles can automatically access the patch variables (like turtles-here) for the patch where they are located:
let hit people with [any? cars-here]
if any? hit
[ ask hit...
or from cars:
let hitters cars with [any? people-here]
if any? hitters
[ ask hitters...
I would like to know how I can count the degrees of separation among nodes within a network.
I have created a network with two breeds that spread virus through time.
to setup
create-people_inf 5 [set label "Infected"]
create-people_well 20 [set label "Good health"]
end
Then I added new nodes to the preexisting ones as follows:
ask people_inf
[ create-links-to other people_inf
[set color red ]
let this_turtle self
ask people_well
[
if random-float 1 < 0.5
[
create-link-to this_turtle [set color green]
]
]
]
This is just a default network. My question would be on how I can count the degrees of separation between one selected node and another one, randomly chosen. I thought of adding a flag and consider a logical condition (if connected?=true), but I do not know to consider the nodes in between. My approach would give me only information on one node and its directed connections.
Any suggestion is more than welcomed. Thanks.
You need to use the Network (nw) extension, see documentation at https://ccl.northwestern.edu/netlogo/docs/nw.html. From that, you can use the nw:distance-to for any turtle to find the number of hops to any specified turtle
I'm new in NetLogo and this may be a too obvious question, but I don't see how to test if what I am doing is right.
I'm making a selection of an agent of breed1 (turtles) based on its distance to breed2 (crocodiles). I would like the crocodile to choose one turtle randomly from the ones around it, but with a higher probability to be chosen the closer the turtle is. Thus, I am using rnd extension and distance command.
My question is if the distance command is referring to the right agent (i.e. distance between the crocodile and the turtles):
ask crocodiles [
let potential_preys turtles in-radius max_distance
let selected_prey rnd:weighted-one-of potential_preys [ (1 - ( distance ? / max_distance ) ) ]
ask selected_prey [
scape
]
]
Before I get to your question, there is another problem I noticed with your code.
I had never realized this before, but NetLogo's semantics can make it tricky to model actual turtles! (At least when other breeds are involved.)
What I mean by this is that turtles refer to all turtles in the model, regardless of their breed. It means that, in your case, crocodiles are included in turtles, so when you say:
let potential_preys turtles in-radius max_distance
...crocodiles can be included in the potential preys!
Getting around this is easy enough, though: just choose another name for the breed that represent actual turtles in your model, e.g.:
breed [ tortoises tortoise ]
And then you can write:
let potential_preys tortoises in-radius max_distance
And now, for your question regarding distance, I think what you want is the distance to myself, where myself would be the crocodile that is selecting its prey. The myself primitive refers to the agent in the "outer" context of the block where you use it, i.e., the "calling" agent.
This gives you something like:
let selected_prey rnd:weighted-one-of potential_preys [
1 - (distance myself / max_distance)
]
Haha, I didn't thought about the turtles detail, indeed... ^^
Anyway it was an example, not the actual name of my breeds, so no problem, but thanks for noticing it!
Regarding the question itself, I also think myself will do, so I'll keep it like this, but now with higher confidence :D
Thanks Nicolas!
The following won't work because nw:weak-component-clusters reports a list of agentsets, not an agentset:
extensions [nw]
ask turtles[
ifelse any? nw:weak-component-clusters with [points > living] []
]
How do you make this work please? I'm trying to get a list of agents that can be reached by a network path from the current turtle, and find out whether they have turtles-own values for 'point' greater than the global value 'living'.
nw:weak-component-clusters gets all the weak component clusters, not just the current turtles. Furthermore, these are weak component clusters, which basically treats all links as undirected, so will still report turtles that are connected by directed paths going the wrong way. Instead, you can use nw:turtles-in-radius with just a large radius to get all turtles reachable from the current turtle:
any? (nw:turtles-in-radius count links) with [ points > living ]
If, for some reason, you do want to use nw:weak-component-clusters, you can do
let component first filter [ member? self ? ] nw:weak-component-clusters
ifelse any? component with [points > living] []
Note that this is equivalent to my first solution for undirected networks.