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

Minor edits to benchmarking code #1985

Merged
merged 18 commits into from
Jan 21, 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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Benchmarking
benchmarking/**/*.pickle
benchmarks/**/*.pickle

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down Expand Up @@ -69,6 +69,7 @@ target/

# PyCharm environment files
.idea/
*.pclprof

# VSCode environment files
.vscode/
Expand All @@ -88,3 +89,4 @@ pythonenv*/
# JS dependencies
mesa/visualization/templates/external/
mesa/visualization/templates/js/external/

80 changes: 0 additions & 80 deletions benchmarks/Flocking/Flocking.py

This file was deleted.

90 changes: 89 additions & 1 deletion benchmarks/Flocking/boid.py → benchmarks/Flocking/flocking.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
"""
Flockers
=============================================================
A Mesa implementation of Craig Reynolds's Boids flocker model.
Uses numpy arrays to represent vectors.
"""

import numpy as np

from mesa import Agent
from mesa import Agent, Model
from mesa.space import ContinuousSpace
from mesa.time import RandomActivation


class Boid(Agent):
Expand Down Expand Up @@ -79,3 +88,82 @@ def step(self):
self.velocity /= np.linalg.norm(self.velocity)
new_pos = self.pos + self.velocity * self.speed
self.model.space.move_agent(self, new_pos)


class BoidFlockers(Model):
"""
Flocker model class. Handles agent creation, placement and scheduling.
"""

def __init__(
self,
seed,
population,
width,
height,
vision,
speed=1,
separation=1,
cohere=0.03,
separate=0.015,
match=0.05,
):
"""
Create a new Flockers model.

Args:
population: Number of Boids
width, height: Size of the space.
speed: How fast should the Boids move.
vision: How far around should each Boid look for its neighbors
separation: What's the minimum distance each Boid will attempt to
keep from any other
cohere, separate, match: factors for the relative importance of
the three drives."""
super().__init__(seed=seed)
self.population = population
self.vision = vision
self.speed = speed
self.separation = separation
self.schedule = RandomActivation(self)
self.space = ContinuousSpace(width, height, True)
self.factors = {"cohere": cohere, "separate": separate, "match": match}
self.make_agents()

def make_agents(self):
"""
Create self.population agents, with random positions and starting headings.
"""
for i in range(self.population):
x = self.random.random() * self.space.x_max
y = self.random.random() * self.space.y_max
pos = np.array((x, y))
velocity = np.random.random(2) * 2 - 1
boid = Boid(
i,
self,
pos,
self.speed,
velocity,
self.vision,
self.separation,
**self.factors,
)
self.space.place_agent(boid, pos)
self.schedule.add(boid)

def step(self):
self.schedule.step()


if __name__ == "__main__":
import time

# model = BoidFlockers(15, 200, 100, 100, 5)
model = BoidFlockers(15, 400, 100, 100, 15)

start_time = time.perf_counter()
for _ in range(100):
model.step()

print(time.perf_counter() - start_time)
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import random

from mesa import Agent, Model
from mesa.space import SingleGrid
Expand All @@ -10,22 +9,20 @@ class SchellingAgent(Agent):
Schelling segregation agent
"""

def __init__(self, pos, model, agent_type):
def __init__(self, unique_id, model, agent_type):
"""
Create a new Schelling agent.
Args:
unique_id: Unique identifier for the agent.
x, y: Agent initial location.
agent_type: Indicator for the agent's type (minority=1, majority=0)
"""
super().__init__(pos, model)
self.pos = pos
super().__init__(unique_id, model)
self.type = agent_type

def step(self):
similar = 0
r = self.model.radius
for neighbor in self.model.grid.iter_neighbors(self.pos, moore=True, radius=r):
for neighbor in self.model.grid.iter_neighbors(self.pos, moore=True, radius=self.model.radius):
if neighbor.type == self.type:
similar += 1

Expand All @@ -36,7 +33,7 @@ def step(self):
self.model.happy += 1


class SchellingModel(Model):
class Schelling(Model):
"""
Model class for the Schelling segregation model.
"""
Expand All @@ -63,9 +60,9 @@ def __init__(
# the coordinates of a cell as well as
# its contents. (coord_iter)
for _cont, pos in self.grid.coord_iter():
if random.random() < self.density: # noqa: S311
agent_type = 1 if random.random() < self.minority_pc else 0 # noqa: S311
agent = SchellingAgent(pos, self, agent_type)
if self.random.random() < self.density:
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)

Expand All @@ -75,3 +72,16 @@ def step(self):
"""
self.happy = 0 # Reset counter of happy agents
self.schedule.step()


if __name__ == "__main__":
import time

# model = Schelling(15, 40, 40, 3, 1, 0.625)
model = Schelling(15, 100, 100, 8, 2, 0.8)

start_time = time.perf_counter()
for _ in range(100):
model.step()

print(time.perf_counter() - start_time)
14 changes: 14 additions & 0 deletions benchmarks/WolfSheep/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from .wolf_sheep import WolfSheep

if __name__ == "__main__":
# for profiling this benchmark model
import time

# model = WolfSheep(15, 25, 25, 60, 40, 0.2, 0.1, 20)
model = WolfSheep(15, 100, 100, 1000, 500, 0.4, 0.2, 20)

start_time = time.perf_counter()
for _ in range(100):
model.step()

print(time.perf_counter() - start_time)
File renamed without changes.
8 changes: 4 additions & 4 deletions benchmarks/configurations.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from Flocking.Flocking import BoidFlockers
from Schelling.Schelling import SchellingModel
from WolfSheep.WolfSheep import WolfSheep
from Flocking.flocking import BoidFlockers
from Schelling.schelling import Schelling
from WolfSheep.wolf_sheep import WolfSheep

configurations = {
# Schelling Model Configurations
SchellingModel: {
Schelling: {
"small": {
"seeds": 50,
"replications": 5,
Expand Down
6 changes: 5 additions & 1 deletion benchmarks/global_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
import time
import timeit

# making sure we use this version of mesa and not one
# also installed in site_packages or so.
sys.path.insert(0, os.path.abspath(".."))

from configurations import configurations


Expand Down Expand Up @@ -56,7 +60,7 @@ def run_experiments(model_class, config):
mean_run = sum(results[1]) / len(results[1])

print(
f"{time.strftime("%H:%M:%S", time.localtime())} {model.__name__:<14} ({size}) timings: Init {mean_init:.5f} s; Run {mean_run:.4f} s"
f"{time.strftime('%H:%M:%S', time.localtime())} {model.__name__:<14} ({size}) timings: Init {mean_init:.5f} s; Run {mean_run:.4f} s"
)

results_dict[model, size] = results
Expand Down