Directing an agent on a specific path (Netlogo) - netlogo

there is a question that I want to ask that is when I trying to type this code, I got the error that is
The > operator can only be used on two numbers, two strings, or two agents of the same type, but not on a number and a list.
What I want to ask is how can I fix this, the false happen at this line on the code :
if pri-lev > [pri-lev] of oppoint1 and pri-lev > [pri-lev] of oppoint2
I tried to change it into "cars-on" or "cars with" but they are all useless. I also try to find on the Netlogo dictionary but I found no results on the code for directing an agent on a specific path.
What I am trying to do here is when an agent comes to a specific section, it will check if any agents listed as "oppoint1"; "oppoint2"; "oppoint3"; "oppoint4" and then compare a value call pri-lev to others value for setting its decision on keeping on moving or stopping and wait for others.
These are the part of my code:
ask cars
[
let oppoint1 (cars-at (xcor + 2) (ycor + 2))
let oppoint2 (cars-at (xcor - 1) (ycor + 1))
let oppoint3 (cars-at (xcor - 2) (ycor + 1))
let oppoint4 (cars-at (xcor - 3) (ycor + 1))
ifelse oppoint1 != nobody and oppoint2 != nobody
[
if pri-lev > [pri-lev] of oppoint1 and pri-lev > [pri-lev] of oppoint2
[
set pri-lev 4
speed-up
]
]
[
if oppoint2 = nobody and oppoint3 = nobody and oppoint4 = nobody
[
set speed 1
fd speed
if turning = "Rtrue"
[
set heading heading + 90
speed-up
]
]
]
]
Sincerely, Minh

it seems that the reason you are getting this error is that you are comparing the attribute of one (the current car) to the attributes of many (the oppoint agent-sets). Your code now says something like "If my privilege is greater than the privilege of that group, do this thing..." The problem is that [pri-lev] of oppoint1 returns a list of the pri-lev of all members of the oppoint1 agentset, like [ 10 12 13 24 ], and Netlogo won't automatically iterate over that list and compare each item to the attribute of the asking turtle.
There are several ways to deal with this. For example, you could make sure that you only ever compare two turtles- maybe by making sure that you only ever have one turtle per patch at a given time. If you are going to potentially compare one agent to an agent-set, you can use the any? primitive to check if any members of the group you're looking at satisfy your conditional statement. For example, given this setup:
turtles-own [
pri-lev
]
to setup
ca
reset-ticks
crt 10 [
set pri-lev 1 + random 10
]
end
You can ask one-of your turtles to check if not any? of the turtles on the current patch have a higher pri-lev than the asking turtle. If none of them do, the current turtle will move forward. Otherwise, it will print that there is another turtle with a higher pri-lev on the current patch.
to compare-with
ask one-of turtles [
let other-turtles other turtles-here
ifelse not any? other-turtles with [ pri-lev > [pri-lev] of myself ] [
fd 1
]
[
print ("A turtle here has a higher pri-lev than I do." )
]
]
tick
end

Related

Operator > and combining it with number and a string in NetLogo

I want a little help. I want turtles to cooperate with 50% probability if their land parcels are > 5.
I am writing as
ifelse random 1 = 0 and land > 5
[set cooperate? true]
[set cooperate? false]
But it gives error that; The > operator can only be used on two numbers, two strings, or two agents of the same type, but not on a string and a number.
how to correct it?
Thanks
There's not quite enough information to diagnose the problem. Is this code inside an ask turtles block with the variable 'land' as a turtles-own attribute? Also, you might want to print off some values of 'land' to make sure you actually have numbers in it.
As you can see from the working example below, there is no error in the code you have provided.
turtles-own [ land cooperate? ]
to testme
clear-all
create-turtles 10
[ set land random 10
ifelse random 1 = 0 and land > 5
[ set cooperate? true ]
[ set cooperate? false ]
]
type "Cooperating: " print count turtles with [cooperate?]
type "Not cooperating: " print count turtles with [not cooperate?]
end

Make turtle change variable if conditions are met

I have to breeds, breed1 and breed2, and only breed1 can change a variable var if members of breed2 are close enough radius 4. However, my code does not work, see below.
This is part of a code which breed1 will execute:
let x min-one-of other breed2 with [ var >= 6 ] in-radius 4 [ distance myself ] ;check whether there is one (or more) members of breed2 with a value of or above 6 of var
ifelse (x != nobody) [ ;if there is one
ask one-of breed2 in-radius 4 with [ var >= 6 ] [ set var var + 1 ] ;change value
[right random 360 forward 1] ;else walk random
My idea is that breed1 checks for members of breed2 in its vicinity (radius 4) if there is one or many, it shall change one of them with a value above 6 of a given variable (var).
However, the above code does not change the variable var. How can I achieve what I want?
I think you have a bracketing error - your then code is not ended before starting your else code. But you also have an efficiency issue because you are constructing the nearby turtles twice. Once you have x, you can simply use it. So fixing that and the bracketing error:
ifelse (x != nobody)
[ ask x [ set var var + 1 ] ] ; x changes value
[ right random 360 forward 1 ] ; the asking turtle moves

Netlogo: Making a turtle interact with anotherone after evaluating similarity in a given variable

I have several turtles each with three variables opinion1, opinion2 and opinion3. I need them to:
identify which of these three variables has the highest value
find another turtle in their network with a value at least as high
as the one found in 1.
update its own value found in 1. with
respect to that of the turtle found in 2.
What I have done doesn't really work because it only updates looking at o1 without really having a look at which of the tree (opinion1, opinion2 or opinion3) is the highest and THEN looking for a neighbour.
to update-opinion
ask turtles [
let my-nearby-turtles nw:turtles-in-radius 1
let my-opinion1 opinion1
set neighbour one-of my-nearby-turtles with [ opinion1 > my-opinion1 ]
if neighbour != nobody [
let opinion_n [opinion1] of neighbour
set opinion1 ((opinion1 + opinion_n) / (2))
]
]
end
I don't know a simple way to do this with unique variables like opinion1 etc, but maybe having a list of opinions instead of individual variables for each opinion will work. For example, with this setup:
extensions [ nw ]
turtles-own [
opinions
]
to setup
ca
resize-world -5 5 -5 5
set-patch-size 30
crt 30 [
set shape "dot"
set opinions n-values 3 [ precision random-float 10 2]
set color scale-color blue sum opinions -5 35
while [ any? other turtles-here ] [
move-to one-of neighbors4
]
]
ask turtles [
create-links-with turtles-on neighbors4
]
reset-ticks
end
You get something like this:
Where each turtle has an opinions list variable that is three items long. Now, you can have each turtle determine its highest opinion value using max, get that maximum values index position in the list using position, and then query that turtle's neighbors to see if any of them have a higher value in the same index position. If they do, modify your asking turtles opinions list using replace-item to be the average of the two values:
to go
ask turtles [
; Get adjacent turtles
let my-nearby-turtles nw:turtles-in-radius 1
; Identify the highest highest value variable of
; the current turtle, and get its list position
let my-opinion max opinions
let my-op-ind position my-opinion opinions
; Pick one of the turtles whose value in the same indexed
; position is higher than my-opinion
let influence one-of my-nearby-turtles with [
item my-op-ind opinions > my-opinion
]
; If that turtle exists, update my own opinions list as appropriate
if influence != nobody [
let new-opinion precision (
( [ item my-op-ind opinions ] of influence + my-opinion ) / 2
) 2
set opinions replace-item my-op-ind opinions new-opinion
]
set color scale-color blue sum opinions -5 35
]
tick
end
Hopefully that is sort of on the right track, not sure if a list will work for what you need. If you must have the variables as standalone values at each tick, I suppose you could convert them to a list then follow the procedure above. If you only need them for output, you could just update your unique variables as needed based on the values in the list (as long as you are consistent with the order).

Netlogo - identifying a subset of an agentset

I spent all afternoon trying to work out with a part of my code and I don't seem to be getting anywhere. Basically, I'm trying to create a social network on model setup. Each person in the model starts off with a set of people that are nearby to them people-nearby. It is from this set that people choose who to connect with:
create-people population-size
[
set people-nearby turtle-set other people in-radius neighborhood-radius
]
to create-network
let num-links round (average-node-degree * population-size) / 2
while [ count links < num-links and count people with [length sort people-nearby > 0] > 0 ]
[ ask one-of people
[ *... initiate probabilistic link creation process...*
create-unlink-with chosen-friend
Once person A has connected to someone (ie. person B), person B is removed from person A's people-nearby set. I'm having trouble with this portion of the code where the people-nearby set is updated by excluding all nearby people that are members of the unlink-neighbors set (i.e., those to whom person A is already connected - this set including person B):
ifelse count turtle-set people-nearby > 1
[ let nearby-people-not-linked-to-me ( turtle-set people-nearby with [ not member? self [ turtle-set unlink-neighbors ] of myself ] )
set people-nearby nearby-people-not-linked-to-me ]
[ set people-nearby [ ] ]
For some reason this error keeps popping up:
"WITH expected input to be an agentset but got the list [(person 0) (person 1) (person 3) (person 4)] instead." whenever
people-nearby with [ not member? self [ turtle-set unlink-neighbors ] of myself is called.
I looked up so many posts but can't seem to get the form of the argument right so that it stops showing this error.
Can anyone help me fix this please? (Oh and it's my first post so apologies if I haven't set up the issue properly)
When you submit code, try to submit what is needed to recreate your problem- check out the asking help page, and specifically the section on helping others reproduce your problem. As is, I think your problem comes from using turtle-set. That primitive is mostly used to combine agentsets, not to query them. So in your line:
( turtle-set people-nearby with [ not member? self [ turtle-set unlink-neighbors ] of myself ] )
there is an syntax issue related to turtle-set. The error itself is saying that you have not returned an agentset but a list of agents, which behave differently.
If I understand correctly, you want all people to have a variable that contains all people within a radius of themselves: "people-nearby". Then, you want the people to form a link with one of their "neighbor" turtles. Finally, you want the people to update their "people-nearby" variable to exclude the person to whom they just formed a link. Below is some code with comments where I tried to follow those steps- obviously your variables will be different, but it may get you started. Let me know if I need to clarify anything or if I missed a step.
breed [ people person ]
turtles-own [ people-nearby ]
to setup
ca
reset-ticks
create-people 70 [
setxy (random 30 - 15) (random 30 - 15)
]
; do this after all turtles have spawned
ask people [
set people-nearby other people in-radius 3
]
end
to create-links
let num-links 10
;; Create a temporary agentset out of turtles that have people nearby
let turtles-with-neighbors turtles with [ any? people-nearby ]
; ask some number of the temporary agentset:
ask n-of num-links turtles-with-neighbors [
;; This just makes it easy to identify the turtle that causes the link
ask patches in-radius 3 [
set pcolor white
]
; create a link to one of the nearby people
create-link-to one-of people-nearby
; newly set people-nearby to only include turtles in radius
; that are not linked-to from the currently acting turtle
set people-nearby other people in-radius 3 with [ not member? self [ out-link-neighbors ] of myself ]
ask people-nearby [ set size 0.5 ]
]
end

nw:weighted-path-to, nw:turtles-on-weighted-path-to and multiple equally weighted paths

I apologise upfront if this is a stupid question.
When one calls nw:weighted-path-to a list of links is returned describing the shortest path between origin and destination turtles.
Similarly, calling nw:turtles-on-weighted-path-to returns a list of the turtles on the shortest path between origin and destination.
It is my understanding that if there are 2 equally weighted paths between origin and destination both functions returns one of these paths at random. This happens independently and as such one set of links can be produced for the shortest path, but another set of turtles. This can be replicated using the following code:
extensions [nw]
links-own [ weight ]
to go
clear-all
create-turtles 4
ask turtle 0 [ create-link-with turtle 1 [ set weight 2 ] ]
ask turtle 0 [ create-link-with turtle 2 [ set weight 2 ] ]
ask turtle 1 [ create-link-with turtle 3 [ set weight 2] ]
ask turtle 2 [ create-link-with turtle 3 [ set weight 2] ]
ask turtle 0
[
let pathLinks nw:weighted-path-to turtle 3 "weight"
let pathNodes nw:turtles-on-weighted-path-to turtle 3 "weight"
let pathUtility nw:weighted-distance-to turtle 3 "weight"
show pathLinks
show pathNodes
show pathUtility
]
end
Which will happily produce:
(turtle 0): [(link 0 2) (link 2 3)]
(turtle 0): [(turtle 0) (turtle 1) (turtle 3)]
(turtle 0): 4
Obviously, this is not an error but it has unfortunately tripped me up.
My question is - what is the most sensible way to link these two procedures to produce lists of links and turtles that make up a single randomly selected shortest path?
I am assuming it would be best to return the links with nw:weighted-path-to, then ask the links to return both-ends and do some sort of unique operation to produce a set of turtles on that path, if that is the case I'm not sure how to preserve the order of turtles. Does this make sense? Is that how you would do it?
As ever, thanks for reading.
Edit: this also applies to path-to and turtles-on-path-to in a topological network with multiple equal length paths.
Good question! You can generate either list from the other, but I think turtle-path to link-path is easier:
;; Construct the turtle path, putting the current turtle on the front:
let turtle-path fput self nw:turtles-on-weight-path-to turtle 3 "weight"
;; Iterate through pairs of turtles, getting the link connecting them
let link-path (map [[link-with ?2] of ?1] but-last turtle-path but-first turtle-path)
Edit:
Nicolas is absolutely right about "link-path to turtle-path". However, his comment made me realize you could use the almighty reduce and the ever-useful other-end to do it!
reduce [ lput [[other-end] of ?2] of (last ?1) ?1 ] fput (list self) nw:weighted-path-to turtle 3 "weight"
Edit2: The "link-path to turtle-path" code is pretty opaque. Here's an attempt to clarify it:
to-report add-link-to-turtle-path [ turtle-path next-link ]
let last-turtle last turtle-path
report lput [[other-end] of next-link] of last-turtle
end
;; turtle-procedure - Assumes the current turtle is the starting point of the path
to-report link-path-to-turtle-path [ link-path ]
let start-of-path (list self)
report reduce add-link-to-turtle-path fput start-of-path link-path
end