@@ -33,15 +33,15 @@ def __init__(
3333 direction ,
3434 vision ,
3535 separation ,
36- cohere = 0.025 ,
37- separate = 0.25 ,
38- match = 0.04 ,
36+ cohere = 0.03 ,
37+ separate = 0.015 ,
38+ match = 0.05 ,
3939 ):
4040 """
4141 Create a new Boid flocker agent.
4242
4343 Args:
44- unique_id: Unique agent identifyer .
44+ unique_id: Unique agent identifier .
4545 pos: Starting position
4646 speed: Distance to move per step.
4747 direction: numpy vector for the Boid's direction of movement.
@@ -62,51 +62,26 @@ def __init__(
6262 self .match_factor = match
6363 self .neighbors = None
6464
65- def cohere (self ):
66- """
67- Return the vector toward the center of mass of the local neighbors.
68- """
69- cohere = np .zeros (2 )
70- if self .neighbors :
71- for neighbor in self .neighbors :
72- cohere += self .model .space .get_heading (self .pos , neighbor .pos )
73- cohere /= len (self .neighbors )
74- return cohere
75-
76- def separate (self ):
77- """
78- Return a vector away from any neighbors closer than separation dist.
79- """
80- me = self .pos
81- them = (n .pos for n in self .neighbors )
82- separation_vector = np .zeros (2 )
83- for other in them :
84- if self .model .space .get_distance (me , other ) < self .separation :
85- separation_vector -= self .model .space .get_heading (me , other )
86- return separation_vector
87-
88- def match_heading (self ):
89- """
90- Return a vector of the neighbors' average heading.
91- """
92- match_vector = np .zeros (2 )
93- if self .neighbors :
94- for neighbor in self .neighbors :
95- match_vector += neighbor .direction
96- match_vector /= len (self .neighbors )
97- return match_vector
98-
9965 def step (self ):
10066 """
10167 Get the Boid's neighbors, compute the new vector, and move accordingly.
10268 """
10369
10470 self .neighbors = self .model .space .get_neighbors (self .pos , self .vision , False )
105- self .direction += (
106- self .cohere () * self .cohere_factor
107- + self .separate () * self .separate_factor
108- + self .match_heading () * self .match_factor
109- ) / 2
71+ n = 0
72+ match_vector , separation_vector , cohere = np .zeros ((3 , 2 ))
73+ for neighbor in self .neighbors :
74+ n += 1
75+ heading = self .model .space .get_heading (self .pos , neighbor .pos )
76+ cohere += heading
77+ if self .model .space .get_distance (self .pos , neighbor .pos ) < self .separation :
78+ separation_vector -= heading
79+ match_vector += neighbor .direction
80+ n = max (n , 1 )
81+ cohere = cohere * self .cohere_factor
82+ separation_vector = separation_vector * self .separate_factor
83+ match_vector = match_vector * self .match_factor
84+ self .direction += (cohere + separation_vector + match_vector ) / n
11085 self .direction /= np .linalg .norm (self .direction )
11186 new_pos = self .pos + self .direction * self .speed
11287 self .model .space .move_agent (self , new_pos )
@@ -119,15 +94,16 @@ class BoidFlockers(mesa.Model):
11994
12095 def __init__ (
12196 self ,
97+ seed = None ,
12298 population = 100 ,
12399 width = 100 ,
124100 height = 100 ,
125- speed = 1 ,
126101 vision = 10 ,
127- separation = 2 ,
128- cohere = 0.025 ,
129- separate = 0.25 ,
130- match = 0.04 ,
102+ speed = 1 ,
103+ separation = 1 ,
104+ cohere = 0.03 ,
105+ separate = 0.015 ,
106+ match = 0.05 ,
131107 ):
132108 """
133109 Create a new Flockers model.
@@ -142,7 +118,7 @@ def __init__(
142118 cohere, separate, match: factors for the relative importance of
143119 the three drives.
144120 """
145- super ().__init__ ()
121+ super ().__init__ (seed = seed )
146122 self .population = population
147123 self .vision = vision
148124 self .speed = speed
0 commit comments