Mesa

From Sensors in Schools
Jump to navigation Jump to search

Introduction

Code 1

from mesa import Agent, Model
from mesa.time import RandomActivation
from mesa.datacollection import DataCollector
import matplotlib.pyplot as plt

class VillageResident(Agent):
    """An agent representing a resident choosing between personal cars and public transport."""
    
    def __init__(self, unique_id, model):
        super().__init__(unique_id, model)
        self.transport_mode = "car" if self.random.random() < model.car_preference else "public"

    def step(self):
        """At each step, agents may switch transport mode based on congestion."""
        if self.model.traffic_congestion > 0.7:  # If congestion is high, some switch to public transport
            if self.random.random() < 0.3:  # 30% chance to switch to public transport
                self.transport_mode = "public"
        elif self.model.traffic_congestion < 0.3:  # If congestion is low, some switch to cars
            if self.random.random() < 0.2:  # 20% chance to switch to cars
                self.transport_mode = "car"

class VillageModel(Model):
    """A model representing transport in a village."""
    
    def __init__(self, num_agents, car_preference):
        self.num_agents = num_agents
        self.car_preference = car_preference  # % of people preferring cars initially
        self.schedule = RandomActivation(self)

        # Create agents
        for i in range(self.num_agents):
            agent = VillageResident(i, self)
            self.schedule.add(agent)
        
        # Data collector to track transport usage
        self.datacollector = DataCollector(
            model_reporters={"Car Users": lambda m: sum(1 for a in m.schedule.agents if a.transport_mode == "car"),
                             "Public Transport Users": lambda m: sum(1 for a in m.schedule.agents if a.transport_mode == "public")}
        )

    def step(self):
        """Advance the model by one step."""
        car_users = sum(1 for agent in self.schedule.agents if agent.transport_mode == "car")
        self.traffic_congestion = car_users / self.num_agents  # Simple congestion measure (0 to 1)

        self.schedule.step()
        self.datacollector.collect(self)

# Run the model
village = VillageModel(num_agents=100, car_preference=0.7)  # 70% start with cars

for i in range(50):  # Simulate 50 steps
    village.step()

# Get data
data = village.datacollector.get_model_vars_dataframe()

# Plot results
plt.plot(data["Car Users"], label="Car Users")
plt.plot(data["Public Transport Users"], label="Public Transport Users")
plt.xlabel("Time Step")
plt.ylabel("Number of Users")
plt.legend()
plt.title("Transport Mode Choice Over Time in a Village")
plt.show()