Skip to content

Commit dc38b5a

Browse files
bergio13Tortar
andauthored
Improve code for flocking example (#1152)
* improved code for flocking example * Update examples/flock.jl Co-authored-by: Adriano Meligrana <[email protected]> --------- Co-authored-by: Adriano Meligrana <[email protected]>
1 parent 7296f35 commit dc38b5a

File tree

1 file changed

+24
-25
lines changed

1 file changed

+24
-25
lines changed

examples/flock.jl

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ using Agents
1919
using Random, LinearAlgebra
2020

2121
@agent struct Bird(ContinuousAgent{2,Float64})
22-
speed::Float64
23-
cohere_factor::Float64
24-
separation::Float64
25-
separate_factor::Float64
26-
match_factor::Float64
27-
visual_distance::Float64
22+
const speed::Float64
23+
const cohere_factor::Float64
24+
const separation::Float64
25+
const separate_factor::Float64
26+
const match_factor::Float64
27+
const visual_distance::Float64
2828
end
2929

3030
# The fields `id` and `pos`, which are required for agents on [`ContinuousSpace`](@ref),
@@ -44,7 +44,7 @@ end
4444
# a model object using default values.
4545
function initialize_model(;
4646
n_birds = 100,
47-
speed = 1.5,
47+
speed = 1.0,
4848
cohere_factor = 0.1,
4949
separation = 2.0,
5050
separate_factor = 0.25,
@@ -53,10 +53,10 @@ function initialize_model(;
5353
extent = (100, 100),
5454
seed = 42,
5555
)
56-
space2d = ContinuousSpace(extent; spacing = visual_distance/1.5)
56+
space2d = ContinuousSpace(extent; spacing = visual_distance / 1.5)
5757
rng = Random.MersenneTwister(seed)
5858

59-
model = StandardABM(Bird, space2d; rng, agent_step!, scheduler = Schedulers.Randomly())
59+
model = StandardABM(Bird, space2d; rng, agent_step!, container = Vector, scheduler = Schedulers.Randomly())
6060
for _ in 1:n_birds
6161
vel = rand(abmrng(model), SVector{2}) * 2 .- 1
6262
add_agent!(
@@ -78,32 +78,31 @@ end
7878
# according to the three rules defined above.
7979
function agent_step!(bird, model)
8080
## Obtain the ids of neighbors within the bird's visual distance
81-
neighbor_ids = nearby_ids(bird, model, bird.visual_distance)
81+
neighbor_agents = nearby_agents(bird, model, bird.visual_distance)
8282
N = 0
83-
match = separate = cohere = (0.0, 0.0)
83+
match = separate = cohere = SVector{2}(0.0, 0.0)
8484
## Calculate behaviour properties based on neighbors
85-
for id in neighbor_ids
85+
for neighbor in neighbor_agents
8686
N += 1
87-
neighbor = model[id].pos
88-
heading = get_direction(bird.pos, neighbor, model)
87+
heading = get_direction(bird.pos, neighbor.pos, model)
8988

9089
## `cohere` computes the average position of neighboring birds
91-
cohere = cohere .+ heading
92-
if euclidean_distance(bird.pos, neighbor, model) < bird.separation
90+
cohere += heading
91+
## `match` computes the average trajectory of neighboring birds
92+
match += neighbor.vel
93+
if sum(heading .^ 2) < bird.separation^2
9394
## `separate` repels the bird away from neighboring birds
94-
separate = separate .- heading
95+
separate -= heading
9596
end
96-
## `match` computes the average trajectory of neighboring birds
97-
match = match .+ model[id].vel
9897
end
99-
N = max(N, 1)
98+
10099
## Normalise results based on model input and neighbor count
101-
cohere = cohere ./ N .* bird.cohere_factor
102-
separate = separate ./ N .* bird.separate_factor
103-
match = match ./ N .* bird.match_factor
100+
cohere *= bird.cohere_factor
101+
separate *= bird.separate_factor
102+
match *= bird.match_factor
104103
## Compute velocity based on rules defined above
105-
bird.vel = (bird.vel .+ cohere .+ separate .+ match) ./ 2
106-
bird.vel = bird.vel ./ norm(bird.vel)
104+
bird.vel += (cohere + separate + match) / max(N, 1)
105+
bird.vel /= norm(bird.vel)
107106
## Move bird according to new velocity and speed
108107
move_agent!(bird, model, bird.speed)
109108
end

0 commit comments

Comments
 (0)