Skip to content

Commit f1b2f7f

Browse files
committed
first fixed
1 parent e6492dc commit f1b2f7f

File tree

3 files changed

+29
-77
lines changed

3 files changed

+29
-77
lines changed

examples/virus_antibody/agents.py

Lines changed: 23 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -9,113 +9,86 @@
99
from collections import deque
1010

1111
import numpy as np
12-
13-
sys.path.insert(0, os.path.abspath("../../mesa"))
1412
from mesa.experimental.continuous_space import ContinuousSpaceAgent
1513

1614

1715
class AntibodyAgent(ContinuousSpaceAgent):
1816
"""An Antibody agent. They move randomly until they see a virus, go fight it.
1917
If they lose, stay KO for a bit, lose health and back to random moving.
2018
"""
19+
speed = 1.5
20+
sight_range = 10
21+
ko_timeout = 15
22+
memory_capacity = 3
23+
health = 2
2124

2225
def __init__(
2326
self,
2427
model,
2528
space,
26-
sight_range,
2729
duplication_rate,
28-
ko_timeout,
29-
memory_capacity,
3030
initial_position=(0, 0),
3131
direction=(1, 1),
3232
):
3333
super().__init__(model=model, space=space)
3434

35-
# Movement & state
35+
# Movement & characteristics
3636
self.position = initial_position
37-
self.speed = 1.5
3837
self.direction = np.array(direction, dtype=float)
39-
40-
# Characteristics
41-
self.sight_range = sight_range
42-
self.health = 2
4338
self.duplication_rate = duplication_rate
4439

4540
# Memory
46-
self.st_memory: deque = deque()
41+
self.st_memory: deque = deque(maxlen=self.memory_capacity)
4742
self.lt_memory: list = []
48-
self.memory_capacity = memory_capacity
4943

5044
# Target & KO state
5145
self.target = None # will hold a weakref.ref or None
52-
self.ko_timeout = ko_timeout
5346
self.ko_steps_left = 0
5447

5548
def step(self):
49+
nearby_agents,_ = self.space.get_agents_in_radius(self.position, self.sight_range)
50+
nearby_viruses = [a for a in nearby_agents if isinstance(a, VirusAgent)]
51+
nearby_antibodies = [a for a in nearby_agents if isinstance(a, AntibodyAgent) and a.unique_id != self.unique_id]
52+
5653
# Acquire a virus target if we don't already have one
57-
if self.target is None:
58-
closest = self.find_closest_virus()
59-
if closest:
60-
self.target = weakref.ref(closest)
54+
if self.target is None and nearby_viruses:
55+
closest = nearby_viruses[0]
56+
self.target = weakref.ref(closest)
6157

6258
# Communicate and maybe duplicate
63-
self.communicate()
59+
self.communicate(nearby_antibodies)
6460
if self.random.random() < self.duplication_rate:
6561
self.duplicate()
6662

6763
# Then move
6864
self.move()
6965

70-
def find_closest_virus(self):
71-
agents, _ = self.space.get_agents_in_radius(self.position, self.sight_range)
72-
viruses = [a for a in agents if isinstance(a, VirusAgent)]
73-
return viruses[0] if viruses else None
74-
75-
def communicate(self) -> bool:
76-
agents, _ = self.space.get_agents_in_radius(self.position, self.sight_range)
77-
peers = [
78-
a
79-
for a in agents
80-
if isinstance(a, AntibodyAgent) and a.unique_id != self.unique_id
81-
]
82-
if not peers:
83-
return False
84-
85-
for other in peers:
66+
def communicate(self, nearby_antibodies) -> bool:
67+
for other in nearby_antibodies:
8668
to_share = [
8769
dna for dna in self.st_memory if dna and dna not in other.lt_memory
8870
]
8971
if to_share:
9072
other.st_memory.extend(to_share)
9173
other.lt_memory.extend(to_share)
92-
while len(other.st_memory) > self.memory_capacity:
93-
other.st_memory.popleft()
9474
return True
9575

9676
def duplicate(self):
9777
clone = AntibodyAgent(
9878
self.model,
9979
self.space,
100-
sight_range=self.sight_range,
10180
duplication_rate=self.duplication_rate,
102-
ko_timeout=self.ko_timeout,
103-
memory_capacity=self.memory_capacity,
10481
initial_position=self.position,
10582
direction=self.direction,
10683
)
10784
# Copy over memory
108-
clone.st_memory = deque(item for item in self.st_memory if item)
85+
clone.st_memory = deque(maxlen=self.memory_capacity)
86+
clone.st_memory.extend([item for item in self.st_memory if item])
10987
clone.lt_memory = [item for item in self.lt_memory if item]
11088
clone.target = None
11189
clone.ko_steps_left = 0
11290

113-
self.model.antibodies_set.add(clone)
114-
11591
def move(self):
116-
# If we've been removed from the space, bail out
117-
if getattr(self, "space", None) is None:
118-
return
11992

12093
# Dereference weakref if needed
12194
target = (
@@ -163,22 +136,17 @@ def move(self):
163136
self.position = new_pos
164137

165138
def engage_virus(self, virus) -> str:
166-
# If it's already gone
167-
if virus not in self.model.agents:
168-
self.target = None
169-
return "no_target"
170139

171140
dna = copy.deepcopy(virus.dna)
172141
if dna in self.st_memory or dna in self.lt_memory:
173142
virus.remove()
174143
self.target = None
175-
return "win"
144+
176145
else:
177146
# KO (or death)
178147
self.health -= 1
179148
if self.health <= 0:
180149
self.remove()
181-
return "dead"
182150

183151
self.st_memory.append(dna)
184152
self.lt_memory.append(dna)
@@ -190,6 +158,7 @@ def engage_virus(self, virus) -> str:
190158

191159
class VirusAgent(ContinuousSpaceAgent):
192160
"""A virus agent: random movement, mutation, duplication, passive to antibodies."""
161+
speed = 1
193162

194163
def __init__(
195164
self,
@@ -205,28 +174,23 @@ def __init__(
205174
self.position = position
206175
self.mutation_rate = mutation_rate
207176
self.duplication_rate = duplication_rate
208-
self.speed = 1
209177
self.direction = np.array((1, 1), dtype=float)
210178
self.dna = dna if dna is not None else self.generate_dna()
211179

212180
def step(self):
213-
# If already removed from the space, don't do anything
214-
if getattr(self, "space", None) is None:
215-
return
216181
if self.random.random() < self.duplication_rate:
217182
self.duplicate()
218183
self.move()
219184

220185
def duplicate(self):
221-
clone = VirusAgent(
186+
VirusAgent(
222187
self.model,
223188
self.space,
224189
mutation_rate=self.mutation_rate,
225190
duplication_rate=self.duplication_rate,
226191
position=self.position,
227192
dna=self.generate_dna(self.dna),
228193
)
229-
self.model.viruses_set.add(clone)
230194

231195
def generate_dna(self, dna=None):
232196
if dna is None:
@@ -240,9 +204,6 @@ def generate_dna(self, dna=None):
240204
return dna
241205

242206
def move(self):
243-
if getattr(self, "space", None) is None:
244-
return
245-
246207
# Random walk
247208
perturb = np.array(
248209
[
@@ -255,5 +216,4 @@ def move(self):
255216
if norm > 0:
256217
self.direction /= norm
257218

258-
# Step
259-
self.position = self.position + self.direction * self.speed
219+
self.position += self.direction * self.speed

examples/virus_antibody/app.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from matplotlib.markers import MarkerStyle
77
from model import VirusAntibodyModel
88

9-
sys.path.insert(0, os.path.abspath("../../mesa"))
9+
sys.path.insert(0, os.path.abspath("../../../mesa"))
1010

1111
from mesa.experimental.devs import ABMSimulator
1212
from mesa.visualization import (

examples/virus_antibody/model.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import os
88
import sys
99

10-
sys.path.insert(0, os.path.abspath("../../mesa"))
10+
sys.path.insert(0, os.path.abspath("../../../mesa"))
1111

1212
import numpy as np
1313
from agents import AntibodyAgent, VirusAgent
@@ -31,11 +31,10 @@ def __init__(
3131
initial_viruses=20,
3232
width=100,
3333
height=100,
34+
3435
# Antibody parameters
3536
antibody_duplication_rate=0.01,
36-
antibody_sight_range=10,
37-
antibody_ko_timeout=15,
38-
antibody_memory_capacity=3,
37+
3938
# Virus parameters
4039
virus_duplication_rate=0.01,
4140
virus_mutation_rate=0.01,
@@ -54,7 +53,6 @@ def __init__(
5453
5554
Indirect Args (not chosen in the graphic interface for clarity reasons):
5655
antibody_memory_capacity: Number of virus DNA an antibody can remember
57-
antibody_sight_range: Radius within which antibodies can detect viruses
5856
antibody_ko_timeout : Number of step after which an antibody can move after a KO
5957
6058
"""
@@ -69,9 +67,6 @@ def __init__(
6967

7068
# antibody parameters
7169
self.antibody_duplication_rate = antibody_duplication_rate
72-
self.antibody_sight_range = antibody_sight_range
73-
self.antibody_ko_timeout = antibody_ko_timeout
74-
self.antibody_memory_capacity = antibody_memory_capacity
7570

7671
# virus parameters
7772
self.virus_duplication_rate = virus_duplication_rate
@@ -103,16 +98,13 @@ def __init__(
10398
size=(self.initial_antibody, 2)
10499
) * np.array(self.space.size)
105100
directions = self.rng.uniform(-1, 1, size=(self.initial_antibody, 2))
106-
self.antibodies_set = AntibodyAgent.create_agents(
101+
AntibodyAgent.create_agents(
107102
self,
108103
self.initial_antibody,
109104
self.space,
110105
initial_position=antibodies_positions,
111106
direction=directions,
112-
sight_range=self.antibody_sight_range,
113107
duplication_rate=self.antibody_duplication_rate,
114-
ko_timeout=self.antibody_ko_timeout,
115-
memory_capacity=self.antibody_memory_capacity,
116108
)
117109

118110
# Create and place the Virus agents
@@ -122,7 +114,7 @@ def __init__(
122114
)
123115
directions = self.rng.uniform(-1, 1, size=(self.initial_viruses, 2))
124116

125-
self.viruses_set = VirusAgent.create_agents(
117+
VirusAgent.create_agents(
126118
self,
127119
self.initial_viruses,
128120
self.space,

0 commit comments

Comments
 (0)