turtles overshooting their target and getting stuck in infinite movement loop - netlogo

I am modeling tax evasion. My model has stationary traders (one breed of turtles) and customers (another breed).
The traders go towards the cheapest trader in their vicinity.
As long as my model has less than 10 traders, I have not experienced this problem. But as I ramp it up to over 20, one of the traders seem to, by chance, be at a set of coordinates that make every customer get stuck in an infinite movement loop where they move forward by 1, but overshoot the target, turn around, and overshoot again etc.
I can get less problems by decreasing forward movement to say 0.001 instead of 1, but the problem will still occur eventually.
Is there a quick fix to this problem? I can imagine a solution where an ifelse makes them jump directly into the traders coordinates when within range 1 or something, but is there an easier way?
I have tried implementing moving towards nearest trader given distance - as I suggested above, but now the customers get stuck in conga lines in groups in random locations without a trader
Here is the code regarding movement:
to find_food
ifelse ( num-traders-close < 2 )
[nearest_food]
[choose-cheapest]
end
to nearest_food
let nearest-food min-one-of (traders )[distance myself]
let cf-dist distance min-one-of traders [distance myself]
ifelse closest-trader > 1
[face nearest-food
fd 1]
[face nearest-food
fd cf-dist]
end
to choose-cheapest
let cheapest-food min-one-of traders [price]
let cf-dist distance min-one-of traders [distance myself]
ifelse closest-trader > 1
[face cheapest-food
fd 1]
[face cheapest-food
fd cf-dist ]
end

In the code in your other question , I have tried to follow your own code, but you can do this as well :
instead of finding one traders , you always check one-of close traders to that customer, and cheapest food and nearest food are customer property.
Breed [Customers Customer]
Breed [Traders trader]
Customers-own
[cheapest-food nearest-food traders-close]
traders-own [price]
to setup
random-seed 234523432
clear-all
Create-traders 10 [move-to one-of patches set price random 100 set shape "house" set color white ]
create-Customers 50 [move-to one-of patches set shape "person" ]
reset-ticks
end
to go
ask customers
[
set-customers
find_food
]
tick
end
to set-customers
rt random 100
fd 1
set traders-close traders with [distance myself < 5]
set nearest-food min-one-of (traders-close )[distance myself]
set cheapest-food min-one-of traders-close [price]
end
to find_food
ifelse ( count traders-close < 2 )
[ifelse nearest-food != nobody
[Move-to nearest-food ]
[Move-to min-one-of Traders [Distance myself]]
]
[ ifelse cheapest-food != nobody
[Move-to cheapest-food]
[Move-to min-one-of Traders with [Distance myself < 5][price]]
]
end

Related

Getting error "There is no agent for MYSELF to refer to" after new procedure is added, but worked before. (Netlogo)

I am trying to simulate an F1 race where the cars go around different tracks and need to pit when their tyres have degraded enough. They stick to the patches that are the track color (black). I have the code where I get the cars to follow the track shown below:
breed[cars car]
cars-own[tyre-level
tyre-type
tyre-total
speed
maxSpeed
draftSpeed
speed
]
;part of the setup
create-cars num-cars [
setxy xcord ycord
set shape "car top"
set size 5
set heading head
set tyre-level one-of (list soft_tyre_durability medium_tyre_durability hard_tyre_durability)
if tyre-level = soft_tyre_durability [set tyre-type "Soft"]
if tyre-level = medium_tyre_durability [set tyre-type "Medium"]
if tyre-level = hard_tyre_durability [set tyre-type "Hard"]
if tyre-level = soft_tyre_durability [set tyre-total soft_tyre_durability]
if tyre-level = medium_tyre_durability [set tyre-total medium_tyre_durability]
if tyre-level = hard_tyre_durability [set tyre-total hard_tyre_durability]
set maxSpeed 30
set draftSpeed 50
]
end
to move ;; turtle procedure
ask cars [face-chosen-neighbor
fd 0.5
set tyre-level tyre-level - 0.01]
end
to face-chosen-neighbor ;; turtle procedure
;; turtle faces the patch that requires the least change in
;; heading to face
let closest-border-patch min-one-of different-colored-neighbors [abs turn-amount]
rt [turn-amount * track-help] of closest-border-patch
end
;; computes the turn the calling turtle would have to make to face this patch
to-report turn-amount ;; patch procedure
let this-patch self
report [subtract-headings (towards this-patch) heading] of myself
end
to-report different-colored-neighbors ;; patch procedure
;; report neighbors that are a different color than me
report neighbors in-cone 2 180 with [pcolor = [pcolor] of myself] ;; report patches or neighbors in cone
end
This runs okay. However I now change the move procedure and add a speed procedure for the accelerating and decelerating - they slow down on turns and speed up if they aren't. They also have an increased max speed if drafting another car.
to move ;; turtle procedure
ask cars [face-chosen-neighbor
control-speed
fd speed / 200
set tyre-level tyre-level - 0.01]
end
to control-speed
let drafting any? other cars in-cone 4 130
ifelse drafting = nobody [set maxSpeed maxSpeed * ( (tyre-level + 50 ) / tyre-total)] [set maxSpeed draftSpeed * ( (tyre-level + 50 ) / tyre-total)]
if turn-amount * track-help > 60 [set speed speed - (deceleration * turn-amount * 0.5)]
let car-ahead any? other cars in-cone 1 130
ifelse car-ahead = nobody [
ifelse speed < maxSpeed [set speed speed + acceleration] [set speed speed - deceleration]
]
[
ifelse [speed] of car-ahead >= maxSpeed [
set speed maxSpeed
set speed speed - deceleration
] [
;try to overtake
ifelse [pcolor] of patch-left-and-ahead 90 1 = [pcolor] of myself and not any? turtles-on patch-left-and-ahead 90 1
[move-to patch-left-and-ahead 90 1] [
ifelse [pcolor] of patch-right-and-ahead 90 1 = [pcolor] of myself and not any? turtles-on patch-right-and-ahead 90 1
[move-to patch-right-and-ahead 90 1] [
set speed [speed] of car-ahead
set speed speed - deceleration]
]
]
]
end
Now if I run this, I get the error "There is no agent for MYSELF to refer to". I assume its got to do with the different definitions of self and myself. I have tried my best to understand it all and have scoured the forums. I'm not sure if I still understand it correctly.
Any help will be greatly appreciated!
I suspect that the error occurs in the lines where you look at the [pcolor] of myself. self and myself can be confusing. Here you have asked cars to look at the color of the patches that they are on, so it is self that you want. Agents can directly determine the color of the patch they are on, in a sense, the patch's pcolor is one of the agent's built-in variables, like its own color, so in fact, you could just ask the car to look at pcolor. Since an agent, in this case a car, can be on only one patch at a time, there is no confusion as to which patch is being referred to. Equivalently, you could use [pcolor] of patch-here.
myself would be used if the car asked the patch to then look at one of the car's variables. E.g., if the car asked the patch to do something with the tyre-type of the car who asked, it would be [tyre-type] of myself.

netlogo realistic predator behaviour

I am working with Netlogo to create a realistic predator prey-model and am stumped at the distance command.
ifelse any? sheep in-radius senserange [
let prey min-one-of sheep in-radius senserange [distance myself]
**ifelse [distance prey] < speedrange**
[move-to prey
let addenergy [energy] of prey
ask prey [die]
set energy energy + (addenergy * energy-gain-from-sheep)
rt 180
fd speedrange
]
[set heading towards prey
fd speedrange
]
]
[wiggle
fd 1]
The code in bold is the problem: I want the wolves not to immediately go to the prey but move towards it in an increment of its speedrange, unless of course it is within that range, then run to it and grab it ;).
I get ERROR: "Expected an agent or number or string here, rather than a list or block"
I think it is with the distance command, I've also tried something like this
ifelse prey in-radius speedrange [distance myself]
Thsi version results in ERROR: "IFELSE expected this input to be a T/F but got a turtle agentset or patch agentset instead
try ifelse distance prey < speedrange instead of ifelse [distance prey] < speedrange - you don't need the reporter/command brackets here

Minimum distance and interference between turtles

I am doing boarding processes model with anti-Covid measures. I would like to know if any of you could help me.
I would like to enforce that the minimum distance between turtles will be 4 patches.
I would like to identify if there is an interference, that is, that a previous turtle occupies a seat that prevents a new agent from passing through.
I don't know how to insert this in my code:
to go
; stop when all the pessengers have found a seat
if not any? turtles with [seated? = false]
[stop]
set counter counter + 1
(foreach (sort turtles with [seated? = false] ) [a ->
ask a [
; check if we have reached the correct row of seats
ifelse [seat-row] of patch-at 1 -1 = assigned-seat-row
[
; only seat the passenger if he/she has stored the luggage OR if we don't take luggages into account
ifelse luggage-store-ticks = 0 or storing-luggage-takes-time = false
[
let seat patch-at 1 -1
set xcor [pxcor] of seat
set ycor assigned-seat-number
set seated? true
]
[
set luggage-store-ticks luggage-store-ticks - 1
]
]
[
let passenger-ahead one-of turtles-on patch-ahead 1
ifelse passenger-ahead != nobody
[
set speed [speed] of passenger-ahead
if xcor != airplane-door-x-cor
[fd speed]
]
[
set speed default-speed
fd speed
]
]
]
])
end
You could extend your existing patch-ahead 1 to also look at the patches 2, 3 and 4 ahead. But I think it would be easiest to use in-cone 5 10 or similar. That will look ahead in a cone shape, 10 degrees on either side of the heading and a distance of 5. So you could do something like:
let potential-blockers turtles in-cone 5 10
let blocker min-one-of potential-blockers [distance myself]
That should (not tested) find the closest turtle approximately in front and name it "blocker" so that you can do things like check if it's far enough away, match speed (see the basic traffic model in the NetLogo models library)

face to minimum heading difference

How can I face or rotate or set the heading of an agent (turtle for example) to that an element of a patch-set which needs minimum rotation.
So the agent has a initial heading, and we have a patch-set (for example 5 patches in a cone), and I would like to face the agent that one which is at minimum in angle difference. I don't want to use patch-ahead because it can be one patch backward if that is the only one.
I tried some combinations with these commands:
min-one-of towards myself self heading subtract-headings towardsxy face - 180
Thank you in advance.
Are you having trouble getting the heading differences with subtract headings? Then you can try this:
to-report abs-hdiff [#t #p]
let _current [heading] of #t
let _new [towards #p] of #t
report abs (subtract-headings _current _new)
end
For example:
to test
ca
ask n-of 5 patches [set pcolor red]
let _patches (patches with [pcolor = red])
crt 1
ask turtle 0 [
hatch 1 [pen-down fd 10 die] ;just to see old heading
face min-one-of _patches [abs-hdiff myself self]
]
end

Streamline agent behavior in NetLogo

I'm trying to model the avoidance of animal agents from human agents in NetLogo. First, I asked a single predator to avoid people using two behaviors, "wary" and "scared". This worked nicely. But then I asked the prey animals (168 individuals right now but potentially many more) to do the same and the model has slowed down to a snail's pace. As I'm pretty new to NetLogo I'm sure that there is a more efficient way to code this behavior. Any suggestions on how to streamline this process? I'm sure there is a better way to do it. Thanks!
to avoid-people ;; test if people too close to predator and prey and animals moves away if is.
ask predator [
ifelse ticks mod 24 >= 5 and ticks mod 24 < 18 [ ;makes sure the animals respond to people during the daytime
humans-near
ifelse any? wary
[ fd 0 ]
[ ]
humans-too-near
if any? scared
[run-away]
] [set wary 0 set scared 0]]
ask preys [
ifelse ticks mod 24 >= 5 and ticks mod 24 < 18 [
humans-near
ifelse any? wary
[ fd 0 ]
[ ]
humans-too-near
if any? scared
[run-away]
] [set wary 0 set scared 0]]
end
;;Humans-near and humans-too-near are functions
;;Alert-distance and flight initiation distance are sliders for the predator but are set values for prey
to humans-near ;;adds all humans in alert-distance radius of animal to an agent subset for that agent.
ask predator [
set wary humans in-radius alert-distance]
ask preys [
set wary humans in-radius 10]
end
to humans-too-near ;;adds all humans in flight-initiation-distance radius of animal to an agent subset for that agent.
ask predator [
set scared humans in-radius flight-initiation-distance]
ask preys [
set scared humans in-radius 5]
end
to run-away ;;Make animal avoid the human closest to it.
set nearest-human min-one-of scared [distance myself]
turn-away ([heading] of nearest-human) max-separate-turn
end
;;this keeps the animals inside the tropical forest and away from human settlement.
;;Max-separate-turn is a slider dictating the angle that the predator runs away from the human
to turn-away [new-heading max-turn]
turn-at-most (subtract-headings heading new-heading) max-turn
ifelse [habitat = typeTrop] of patch-ahead run-distance
[fd run-distance] [turn-away ([heading] of nearest-human) max-separate-turn]
end
to turn-at-most [turn max-turn]
ifelse abs turn > max-turn
[ ifelse turn > 0
[ rt max-turn ]
[ lt max-turn ] ]
[ rt turn ]
end
I did not understand your code, but this is one way to do what you want, I am not sure how agents should behave if they are scared or they move with wary, but you can change these easily :
Breed [predators predator]
Breed [Humans Human]
Breed [Preys Prey]
turtles-own [
wary
scared
]
to setup
Clear-all
Create-humans 5 [Set color orange set shape "person" move-to patch random 30 random 30]
Create-Preys 5[Set color white Set shape "Sheep" move-to patch random 30 random 30]
Create-predators 5 [set color red Set shape "wolf" move-to patch random 30 random 30]
ask turtles
[set Wary false
Set Scared False
]
reset-ticks
end
to go
ask turtles
[rt random 5
fd 0.3]
avoid-people
tick
end
to avoid-people
ifelse is-day?
[
ask predators
[ if humans-near?
[
set wary true
if humans-too-near? [Set Scared true]
set label (word wary "," Scared )
]
]
Ask Preys
[ if humans-near?
[
set wary true
if humans-too-near? [Set Scared true]
set label (word wary "," Scared )
]
]
]
[; what they should do when its night time
]
end
to-report humans-too-near?
report any? humans in-radius 2
end
to-report humans-near?
report any? humans in-radius 5
end
to-report is-day?
report (ticks mod 24 >= 5 and ticks mod 24 < 18)
end
*Update:
Your problem was in having 2 ask inside each other , I am glad your model now runs faster.