Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reinstate PR #161: Replace schedulers with AgentSet functionality #183

Merged
merged 2 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions examples/bank_reserves/bank_reserves/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,18 @@
Northwestern University, Evanston, IL.
"""

import mesa

from .random_walk import RandomWalker


class Bank(mesa.Agent):
def __init__(self, unique_id, model, reserve_percent=50):
# initialize the parent class with required parameters
super().__init__(unique_id, model)
class Bank:
"""Note that the Bank class is not a Mesa Agent, but just a regular Python
class. This is because there is only one bank in this model, and it does not
use any Mesa-specific features like the scheduler or the grid, and doesn't
have a step method. It is just used to keep track of the bank's reserves and
the amount it can loan out, for Person agents to interact with."""

def __init__(self, model, reserve_percent=50):
self.model = model
# for tracking total value of loans outstanding
self.bank_loans = 0
"""percent of deposits the bank must keep in reserves - this is set via
Expand Down Expand Up @@ -173,7 +176,6 @@ def take_out_loan(self, amount):
# increase the bank's outstanding loans
self.bank.bank_loans += amount

# step is called for each agent in model.BankReservesModel.schedule.step()
def step(self):
# move to a cell in my Moore neighborhood
self.random_move()
Expand Down
22 changes: 9 additions & 13 deletions examples/bank_reserves/bank_reserves/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,38 @@
def get_num_rich_agents(model):
"""return number of rich agents"""

rich_agents = [a for a in model.schedule.agents if a.savings > model.rich_threshold]
rich_agents = [a for a in model.agents if a.savings > model.rich_threshold]
return len(rich_agents)


def get_num_poor_agents(model):
"""return number of poor agents"""

poor_agents = [a for a in model.schedule.agents if a.loans > 10]
poor_agents = [a for a in model.agents if a.loans > 10]
return len(poor_agents)


def get_num_mid_agents(model):
"""return number of middle class agents"""

mid_agents = [
a
for a in model.schedule.agents
if a.loans < 10 and a.savings < model.rich_threshold
a for a in model.agents if a.loans < 10 and a.savings < model.rich_threshold
]
return len(mid_agents)


def get_total_savings(model):
"""sum of all agents' savings"""

agent_savings = [a.savings for a in model.schedule.agents]
agent_savings = [a.savings for a in model.agents]
# return the sum of agents' savings
return np.sum(agent_savings)


def get_total_wallets(model):
"""sum of amounts of all agents' wallets"""

agent_wallets = [a.wallet for a in model.schedule.agents]
agent_wallets = [a.wallet for a in model.agents]
# return the sum of all agents' wallets
return np.sum(agent_wallets)

Expand All @@ -75,7 +73,7 @@ def get_total_money(model):

def get_total_loans(model):
# list of amounts of all agents' loans
agent_loans = [a.loans for a in model.schedule.agents]
agent_loans = [a.loans for a in model.agents]
# return sum of all agents' loans
return np.sum(agent_loans)

Expand Down Expand Up @@ -118,7 +116,7 @@ def __init__(
self.height = height
self.width = width
self.init_people = init_people
self.schedule = mesa.time.RandomActivation(self)

self.grid = mesa.space.MultiGrid(self.width, self.height, torus=True)
# rich_threshold is the amount of savings a person needs to be considered "rich"
self.rich_threshold = rich_threshold
Expand All @@ -138,7 +136,7 @@ def __init__(
)

# create a single bank for the model
self.bank = Bank(1, self, self.reserve_percent)
self.bank = Bank(self, self.reserve_percent)

# create people for the model according to number of people set by user
for i in range(self.init_people):
Expand All @@ -148,15 +146,13 @@ def __init__(
p = Person(i, self, True, self.bank, self.rich_threshold)
# place the Person object on the grid at coordinates (x, y)
self.grid.place_agent(p, (x, y))
# add the Person object to the model schedule
self.schedule.add(p)

self.running = True
self.datacollector.collect(self)

def step(self):
# tell all the agents in the model to run their step function
self.schedule.step()
self.agents.shuffle().do("step")
# collect data
self.datacollector.collect(self)

Expand Down
24 changes: 10 additions & 14 deletions examples/bank_reserves/batch_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@
def get_num_rich_agents(model):
"""list of rich agents"""

rich_agents = [a for a in model.schedule.agents if a.savings > model.rich_threshold]
rich_agents = [a for a in model.agents if a.savings > model.rich_threshold]
# return number of rich agents
return len(rich_agents)


def get_num_poor_agents(model):
"""list of poor agents"""

poor_agents = [a for a in model.schedule.agents if a.loans > 10]
poor_agents = [a for a in model.agents if a.loans > 10]
# return number of poor agents
return len(poor_agents)

Expand All @@ -54,9 +54,7 @@ def get_num_mid_agents(model):
"""list of middle class agents"""

mid_agents = [
a
for a in model.schedule.agents
if a.loans < 10 and a.savings < model.rich_threshold
a for a in model.agents if a.loans < 10 and a.savings < model.rich_threshold
]
# return number of middle class agents
return len(mid_agents)
Expand All @@ -65,15 +63,15 @@ def get_num_mid_agents(model):
def get_total_savings(model):
"""list of amounts of all agents' savings"""

agent_savings = [a.savings for a in model.schedule.agents]
agent_savings = [a.savings for a in model.agents]
# return the sum of agents' savings
return np.sum(agent_savings)


def get_total_wallets(model):
"""list of amounts of all agents' wallets"""

agent_wallets = [a.wallet for a in model.schedule.agents]
agent_wallets = [a.wallet for a in model.agents]
# return the sum of all agents' wallets
return np.sum(agent_wallets)

Expand All @@ -91,7 +89,7 @@ def get_total_money(model):
def get_total_loans(model):
"""list of amounts of all agents' loans"""

agent_loans = [a.loans for a in model.schedule.agents]
agent_loans = [a.loans for a in model.agents]
# return sum of all agents' loans
return np.sum(agent_loans)

Expand Down Expand Up @@ -129,7 +127,7 @@ def __init__(
self.height = height
self.width = width
self.init_people = init_people
self.schedule = mesa.time.RandomActivation(self)

self.grid = mesa.space.MultiGrid(self.width, self.height, torus=True)
# rich_threshold is the amount of savings a person needs to be considered "rich"
self.rich_threshold = rich_threshold
Expand All @@ -150,8 +148,8 @@ def __init__(
agent_reporters={"Wealth": "wealth"},
)

# create a single bank for the model
self.bank = Bank(1, self, self.reserve_percent)
# create a single bank object for the model
self.bank = Bank(self, self.reserve_percent)

# create people for the model according to number of people set by user
for i in range(self.init_people):
Expand All @@ -162,16 +160,14 @@ def __init__(
p = Person(i, (x, y), self, True, self.bank, self.rich_threshold)
# place the Person object on the grid at coordinates (x, y)
self.grid.place_agent(p, (x, y))
# add the Person object to the model schedule
self.schedule.add(p)

self.running = True

def step(self):
# collect data
self.datacollector.collect(self)
# tell all the agents in the model to run their step function
self.schedule.step()
self.agents.shuffle().do("step")

def run_model(self):
for i in range(self.run_time):
Expand Down
2 changes: 1 addition & 1 deletion examples/boid_flockers/Flocker Test.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"def draw_boids(model):\n",
" x_vals = []\n",
" y_vals = []\n",
" for boid in model.schedule.agents:\n",
" for boid in model.agents:\n",
" x, y = boid.pos\n",
" x_vals.append(x)\n",
" y_vals.append(y)\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __init__(self, portrayal_method=None, canvas_height=500, canvas_width=500):

def render(self, model):
space_state = []
for obj in model.schedule.agents:
for obj in model.agents:
portrayal = self.portrayal_method(obj)
x, y = obj.pos
x = (x - model.space.x_min) / (model.space.x_max - model.space.x_min)
Expand Down
5 changes: 2 additions & 3 deletions examples/boid_flockers/boid_flockers/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def __init__(
self.vision = vision
self.speed = speed
self.separation = separation
self.schedule = mesa.time.RandomActivation(self)

self.space = mesa.space.ContinuousSpace(width, height, True)
self.factors = {"cohere": cohere, "separate": separate, "match": match}
self.make_agents()
Expand All @@ -144,7 +144,6 @@ def make_agents(self):
**self.factors,
)
self.space.place_agent(boid, pos)
self.schedule.add(boid)

def step(self):
self.schedule.step()
self.agents.shuffle().do("step")
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


def compute_gini(model):
agent_wealths = [agent.wealth for agent in model.schedule.agents]
agent_wealths = [agent.wealth for agent in model.agents]
x = sorted(agent_wealths)
N = model.num_agents
B = sum(xi * (N - i) for i, xi in enumerate(x)) / (N * sum(x))
Expand All @@ -21,14 +21,14 @@ def __init__(self, N=100, width=10, height=10):
super().__init__()
self.num_agents = N
self.grid = mesa.space.MultiGrid(width, height, True)
self.schedule = mesa.time.RandomActivation(self)

self.datacollector = mesa.DataCollector(
model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"}
)
# Create agents
for i in range(self.num_agents):
a = MoneyAgent(i, self)
self.schedule.add(a)

# Add the agent to a random grid cell
x = self.random.randrange(self.grid.width)
y = self.random.randrange(self.grid.height)
Expand All @@ -38,7 +38,7 @@ def __init__(self, N=100, width=10, height=10):
self.datacollector.collect(self)

def step(self):
self.schedule.step()
self.agents.shuffle().do("step")
# collect data
self.datacollector.collect(self)

Expand Down
8 changes: 4 additions & 4 deletions examples/boltzmann_wealth_model_experimental/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


def compute_gini(model):
agent_wealths = [agent.wealth for agent in model.schedule.agents]
agent_wealths = [agent.wealth for agent in model.agents]
x = sorted(agent_wealths)
N = model.num_agents
B = sum(xi * (N - i) for i, xi in enumerate(x)) / (N * sum(x))
Expand All @@ -21,14 +21,14 @@ def __init__(self, N=100, width=10, height=10):
super().__init__()
self.num_agents = N
self.grid = mesa.space.MultiGrid(width, height, True)
self.schedule = mesa.time.RandomActivation(self)

self.datacollector = mesa.DataCollector(
model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"}
)
# Create agents
for i in range(self.num_agents):
a = MoneyAgent(i, self)
self.schedule.add(a)

# Add the agent to a random grid cell
x = self.random.randrange(self.grid.width)
y = self.random.randrange(self.grid.height)
Expand All @@ -38,7 +38,7 @@ def __init__(self, N=100, width=10, height=10):
self.datacollector.collect(self)

def step(self):
self.schedule.step()
self.agents.shuffle().do("step")
# collect data
self.datacollector.collect(self)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@


def compute_gini(model):
agent_wealths = [agent.wealth for agent in model.schedule.agents]
agent_wealths = [agent.wealth for agent in model.agents]
x = sorted(agent_wealths)
N = model.num_agents
B = sum(xi * (N - i) for i, xi in enumerate(x)) / (N * sum(x))
Expand All @@ -19,7 +19,7 @@ def __init__(self, num_agents=7, num_nodes=10):
self.num_nodes = num_nodes if num_nodes >= self.num_agents else self.num_agents
self.G = nx.erdos_renyi_graph(n=self.num_nodes, p=0.5)
self.grid = mesa.space.NetworkGrid(self.G)
self.schedule = mesa.time.RandomActivation(self)

self.datacollector = mesa.DataCollector(
model_reporters={"Gini": compute_gini},
agent_reporters={"Wealth": lambda _: _.wealth},
Expand All @@ -30,15 +30,15 @@ def __init__(self, num_agents=7, num_nodes=10):
# Create agents
for i in range(self.num_agents):
a = MoneyAgent(i, self)
self.schedule.add(a)

# Add the agent to a random node
self.grid.place_agent(a, list_of_random_nodes[i])

self.running = True
self.datacollector.collect(self)

def step(self):
self.schedule.step()
self.agents.shuffle().do("step")
# collect data
self.datacollector.collect(self)

Expand Down
6 changes: 2 additions & 4 deletions examples/caching_and_replay/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ def __init__(
self.homophily = homophily
self.radius = radius

self.schedule = mesa.time.RandomActivation(self)
self.grid = mesa.space.SingleGrid(width, height, torus=True)

self.happy = 0
Expand All @@ -87,7 +86,6 @@ def __init__(
agent_type = 1 if self.random.random() < self.minority_pc else 0
agent = SchellingAgent(self.next_id(), self, agent_type)
self.grid.place_agent(agent, pos)
self.schedule.add(agent)

self.datacollector.collect(self)

Expand All @@ -96,9 +94,9 @@ def step(self):
Run one step of the model.
"""
self.happy = 0 # Reset counter of happy agents
self.schedule.step()
self.agents.shuffle().do("step")

self.datacollector.collect(self)

if self.happy == self.schedule.get_agent_count():
if self.happy == len(self.agents):
self.running = False
Loading
Loading