@@ -19,12 +19,12 @@ using Agents
19
19
using Random, LinearAlgebra
20
20
21
21
@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
28
28
end
29
29
30
30
# The fields `id` and `pos`, which are required for agents on [`ContinuousSpace`](@ref),
44
44
# a model object using default values.
45
45
function initialize_model (;
46
46
n_birds = 100 ,
47
- speed = 1.5 ,
47
+ speed = 1.0 ,
48
48
cohere_factor = 0.1 ,
49
49
separation = 2.0 ,
50
50
separate_factor = 0.25 ,
@@ -53,10 +53,10 @@ function initialize_model(;
53
53
extent = (100 , 100 ),
54
54
seed = 42 ,
55
55
)
56
- space2d = ContinuousSpace (extent; spacing = visual_distance/ 1.5 )
56
+ space2d = ContinuousSpace (extent; spacing = visual_distance / 1.5 )
57
57
rng = Random. MersenneTwister (seed)
58
58
59
- model = StandardABM (Bird, space2d; rng, agent_step!, scheduler = Schedulers. Randomly ())
59
+ model = StandardABM (Bird, space2d; rng, agent_step!, container = Vector, scheduler = Schedulers. Randomly ())
60
60
for _ in 1 : n_birds
61
61
vel = rand (abmrng (model), SVector{2 }) * 2 .- 1
62
62
add_agent! (
78
78
# according to the three rules defined above.
79
79
function agent_step! (bird, model)
80
80
# # 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)
82
82
N = 0
83
- match = separate = cohere = (0.0 , 0.0 )
83
+ match = separate = cohere = SVector {2} (0.0 , 0.0 )
84
84
# # Calculate behaviour properties based on neighbors
85
- for id in neighbor_ids
85
+ for neighbor in neighbor_agents
86
86
N += 1
87
- neighbor = model[id]. pos
88
- heading = get_direction (bird. pos, neighbor, model)
87
+ heading = get_direction (bird. pos, neighbor. pos, model)
89
88
90
89
# # `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
93
94
# # `separate` repels the bird away from neighboring birds
94
- separate = separate .- heading
95
+ separate -= heading
95
96
end
96
- # # `match` computes the average trajectory of neighboring birds
97
- match = match .+ model[id]. vel
98
97
end
99
- N = max (N, 1 )
98
+
100
99
# # 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
104
103
# # 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)
107
106
# # Move bird according to new velocity and speed
108
107
move_agent! (bird, model, bird. speed)
109
108
end
0 commit comments