Avete mai guardato un ingorgo stradale chiedendovi chi sia il colpevole? Spesso non c’è un incidente, né un semaforo rotto. È solo il risultato di tante piccole frenate individuali che, sommate, bloccano un’intera autostrada. Se provassimo a spiegare questo caos con una singola formula matematica, probabilmente falliremmo: la realtà è troppo disordinata per essere racchiusa in un’equazione statica. È qui che entra in gioco l’Agent-Based Modeling (ABM). Invece di guardare la foresta dall’alto, l’ABM si concentra sui singoli alberi o meglio, sugli individui, dando loro delle regole semplici e osservando cosa succede quando iniziano a interagire.
In questa guida vedremo come tradurre questo concetto in codice usando Mesa, la libreria che ha portato la simulazione complessa nel linguaggio di programmazione più amato del momento: Python.
Cos’è l’Agent-Based Modeling (ABM)?
Prima di parlare di Mesa, facciamo un passo indietro. L’Agent-Based Modeling (Modellazione Basata su Agenti) è un approccio di simulazione che studia il comportamento di un sistema complesso partendo dal basso. Invece di scrivere equazioni che descrivono il sistema dall’alto, si definiscono le regole di comportamento dei singoli componenti, chiamati agenti, e si osserva come dal loro interagire emerga spontaneamente il comportamento del sistema nel suo insieme.
Immagina di studiare il traffico. Invece di usare formule matematiche perfette ma irrealistiche (che presuppongono tutti i guidatori razionali con velocità costante), un ABM creerà una simulazione con centinaia di auto, ognuna con il suo guidatore.
Ogni guidatore ha regole: “se l’auto davanti rallenta, io freno” e “se c’è uno spazio a destra, cambio corsia”. Osservando questa moltitudine di interazioni locali, è possibile far emergere fenomeni macroscopici e spesso complessi, come un ingorgo. Niente equazioni che lo descrivono direttamente, solo tante piccole regole individuali che generano un effetto globale.
🧐 Cos’è Mesa e cosa lo rende uno “standard de facto”?
Mesa è proprio una libreria Python progettata per rendere semplice e veloce la creazione di queste simulazioni ad agenti. Fornisce tutti gli “ingredienti” di base per costruire un ABM: creare gli agenti, gestire lo spazio (griglie o reti), programmare l’ordine delle azioni e raccogliere i dati. Lo scopo principale di Mesa è essere l’alternativa Python a framework storicamente importanti come NetLogo, Repast e MASON, ma con un occhio di riguardo per le moderne pratiche di programmazione e data analysis.
Considerarlo uno “standard de facto” in Python è più che giustificato per queste ragioni:
-
È il più diffuso e maturo: Mesa è il framework Python per ABM più completo e utilizzato. La sua lunga storia (il progetto è iniziato nel 2014) lo ha reso estremamente stabile e ricco di funzionalità. Avere una vasta comunità e un ecosistema consolidato è fondamentale per essere uno standard.
-
È il più citato in ambito accademico e nei corsi: Se cerchi “Agent-Based Modeling in Python”, è praticamente certo che troverai Mesa. Molte università, come l’Università di Bologna e il Montana Tech, lo utilizzano per insegnare la simulazione ad agenti nei loro corsi. Viene anche ampiamente utilizzato in ricerche scientifiche pubblicate, come per lo studio della diffusione di opinioni sui vaccini a New York.
-
Ha un design moderno e ben integrato: A differenza di altri framework, Mesa è nato per integrarsi perfettamente con l’ecosistema Python. Questo significa che puoi utilizzare tutte le potenti librerie di analisi dati che già conosci, come Pandas, NumPy e Matplotlib, direttamente sulle simulazioni create con Mesa.
Le caratteristiche principali di Mesa
Mesa fornisce una serie di moduli che coprono gli aspetti essenziali di una simulazione:
-
Agenti: La classe
mesa.Agentè il cuore della simulazione. La sua specializzazione (sottoclasse) definisce il comportamento degli agenti, tipicamente attraverso un metodostep()che viene eseguito a ogni “tick” della simulazione. -
Modello: La classe
mesa.Modelè il contenitore della simulazione. Gestisce gli agenti, l’ambiente, i parametri e coordina l’esecuzione. La funzionalità AgentSet è uno strumento moderno per filtrare, raggruppare e gestire i tuoi agenti in modo efficiente. -
Spazio: Gli agenti vivono in uno spazio condiviso. Mesa supporta spazi discreti come griglie esagonali e spazi continui, che permettono movimenti realistici e interazioni tra agenti. La PropertyLayer è una feature avanzata che permette di gestire proprietà ambientali complesse (ad esempio, la mappa delle risorse o dei pericoli) in modo molto efficiente.
-
Scheduler: Lo scheduler definisce l’ordine in cui gli agenti agiscono. Puoi far agire gli agenti in ordine casuale, sequenziale o a fasi, per modellare l’aspetto temporale della simulazione.
-
DataCollector: Uno strumento integrato per raccogliere e salvare i dati durante la simulazione (ad esempio, la ricchezza media di tutti gli agenti o le coordinate di uno specifico tipo di agente).
-
Visualizzazione: Mesa include SolaraViz, un’interfaccia interattiva che si apre nel browser e permette di visualizzare la simulazione in tempo reale, muovere la visuale in diversi assi e modificare alcuni parametri al volo, con il supporto a schemi di colore scuro.
I 5 passi spiegati in modo semplice
Immagina di costruire una simulazione Mesa come se stessi creando un piccolo mondo virtuale.
1. L’Agente = il personaggio del gioco
Pensa agli agenti come a persone dentro un videogioco.
Ogni agente:
- ha delle caratteristiche (es. soldi, energia, stato)
- prende decisioni
👉 Il metodo step() è semplicemente:
Cosa faccio adesso?”
Esempio:
- Se ho soldi → compro qualcosa
- Se sono stanco → mi fermo
👉 È qui che nasce il comportamento.
2. Il Modello = il mondo + il regista
Il modello è:
- il mondo di gioco
- il regista invisibile
Fa due cose fondamentali:
- Crea tutto all’inizio (agenti, spazio)
- Fa avanzare il tempo
👉 Ogni “tick” (passo temporale):
dice a tutti:
Ok ragazzi, ora tocca a voi agire
3. Spazio + Scheduler = dove e quando
Qui succede la magia vera.
Spazio (dove stanno gli agenti)
È la mappa:
- griglia tipo scacchiera →
MultiGrid - spazio continuo → tipo coordinate reali
👉 Senza spazio:
gli agenti non possono incontrarsi → niente interazioni
Scheduler (ordine di azione)
Decide:
Chi si muove prima?
⚠️ Importantissimo:
Se sempre lo stesso agente parte per primo → risultati falsati
👉 Per questo si usa:
RandomActivation→ ordine casuale (più realistico)
4. DataCollector = il ricercatore
Qui smetti di “giocare” e inizi a misurare
Serve per rispondere a domande tipo:
- Quanti agenti sono ricchi?
- Come cambia il sistema nel tempo?
Due livelli:
- globale → totale ricchezza
- individuale → ricchezza di ogni agente
👉 Senza questo:
hai una simulazione… ma non impari nulla
5. Il ciclo = far vivere il mondo
Ora premi “play” ▶️
Ogni ciclo:
- Gli agenti agiscono
- Il modello aggiorna
- I dati vengono salvati
👉 Dopo tanti cicli:
emerge un comportamento globale
💡 Il concetto chiave (importantissimo)
👉 Mesa non simula direttamente il sistema
👉 Simula regole locali semplici
E poi succede qualcosa di potente:
Comportamenti complessi emergono da regole semplici
Esempio:
- ogni agente copia i vicini → boom, viralità
- ogni agente scambia soldi → nascono disuguaglianze
Riassunto super semplice
| Componente | Traduzione intuitiva |
|---|---|
| Agente | Personaggio |
| Modello | Mondo + regista |
| Spazio | Mappa |
| Scheduler | Turni di gioco |
| DataCollector | Analista |
| Ciclo | Il tempo che scorre |
Un cambio di mentalità
L’idea fondamentale (spiegata bene)
Quando usi Mesa non stai programmando il risultato.
👉 Non dici:
“voglio la viralità”
“voglio la disuguaglianza”
👉 Dici invece:
ogni individuo segue queste piccole regole
E poi osservi cosa succede.
Differenza chiave
Approccio classico (top-down)
- Parti dal sistema globale
- Scrivi equazioni (es. crescita, medie, curve)
👉 Esempio:
- “La domanda cresce del 10%”
- “La ricchezza media aumenta”
⚠️ Problema: perdi i comportamenti individuali
Approccio ABM (bottom-up)
- Parti dagli individui
- Definisci regole locali
👉 Esempio:
- “Se il mio vicino compra, forse compro anche io”
- “Se incontro qualcuno, posso scambiare soldi”
👉 Il sistema globale non è scritto da nessuna parte
La magia: emergenza
Questo fenomeno si chiama:
👉 emergenza (emergent behavior)
Significa:
pattern complessi nascono da interazioni semplici
Esempio 1: Viralità (marketing)
Regola locale
Ogni agente:
- guarda i vicini
- se qualcuno ha adottato → copia con probabilità
👉 Sembra banale, ma…
Cosa emerge?
Fase 1 → lenta
- pochi adottano
- diffusione quasi invisibile
Fase 2 → accelerazione
- più adottanti → più influenza
- effetto valanga
Fase 3 → saturazione
- quasi tutti adottano
Nel marketing reale…
Questa dinamica è:
- passaparola
- network effects
- crescita “a S” (sigmoide)
👉 Nessuno ha programmato la curva
👉 È emersa da regole locali
Esempio 2: Disuguaglianza (economia)
Regola locale
Ogni agente:
- incontra un altro agente
- scambia una piccola quantità di denaro casuale
👉 Fine. Niente altro.
Cosa ti aspetteresti?
👉 “Tutti restano più o meno uguali”
Sembra logico, no?
Cosa succede davvero 😮
Dopo tanti step:
- pochi diventano molto ricchi
- molti diventano poveri
👉 Nasce una distribuzione tipo:
- Pareto / power law
💡 Quindi…
Questo modello spiega perché:
- le disuguaglianze emergono anche senza “cattive intenzioni”
- il sistema stesso genera squilibri
👉 Non serve:
- truffa
- sfruttamento
- strategie complesse
Bastano:
interazioni casuali ripetute
Perché succede tutto questo?
Ci sono 3 ingredienti chiave:
1. Interazioni locali
Gli agenti vedono solo:
- vicini
- contatti diretti
👉 Nessuna visione globale
2. Non linearità
Piccoli cambiamenti → grandi effetti
Esempio:
- probabilità 0.2 → niente viralità
- probabilità 0.3 → esplosione
3. Feedback (effetto moltiplicatore)
Viralità:
più utenti → più influenza → più utenti
Ricchezza:
più soldi → più possibilità → ancora più soldi
👉 È qui che nasce la complessità
Ricorda..
“Non simuliamo il sistema.
Simuliamo le interazioni che lo generano.”
Collegamento diretto al marketing
Questo approccio ti permette di capire:
Viralità
- quando un prodotto “decolla”
- soglia critica (tipping point)
Segmentazione
- non tutti reagiscono uguale
- alcuni diventano influencer naturali
ROI campagne
- meglio 1000 utenti casuali?
- o 10 super connessi?
👉 ABM ti permette di testarlo
In Sintesi
La cosa controintuitiva è questa:
Più il modello è semplice, più può generare risultati complessi.
Non serve aggiungere mille regole.
Spesso:
- troppe regole → sistema rigido
- poche regole → sistema realistico
Primo esempio: agenti che si muovono casualmente in una griglia
Questo è il classico “Hello World” degli ABM: pochi concetti, ma fondamentali.
from mesa import Agent, Model
from mesa.space import MultiGrid
import random
# ======================
# Agente
# ======================
class RandomAgent(Agent):
def __init__(self, model):
super().__init__(model)
def step(self):
# Celle vicine (anche diagonali)
neighbors = self.model.grid.get_neighborhood(
self.pos,
moore=True,
include_center=False
)
# Movimento casuale
new_position = random.choice(neighbors)
self.model.grid.move_agent(self, new_position)
# ======================
# Modello
# ======================
class RandomModel(Model):
def __init__(self, n_agents, width, height):
super().__init__()
self.grid = MultiGrid(width, height, torus=True)
self.agents_list = []
# Creazione agenti
for _ in range(n_agents):
agent = RandomAgent(self)
self.agents_list.append(agent)
x = random.randrange(width)
y = random.randrange(height)
self.grid.place_agent(agent, (x, y))
def step(self):
# Attivazione casuale
random.shuffle(self.agents_list)
for agent in self.agents_list:
agent.step()
Esecuzione
model = RandomModel(n_agents=10, width=10, height=10)
for step in range(5):
model.step()
print(f"Step {step+1} completato")
Step 1 completato
Step 2 completato
Step 3 completato
Step 4 completato
Step 5 completato
Cosa sta succedendo
Questo esempio, per quanto semplice, contiene tutti i mattoni base dell’Agent-Based Modeling:
- Agenti (
RandomAgent)- hanno comportamento locale (
step) - non conoscono il sistema globale
- hanno comportamento locale (
- Ambiente (
MultiGrid)- spazio discreto 2D
- supporta interazioni locali
- Dinamica
- ogni agente si muove casualmente
- l’ordine di attivazione è random
👉 Non c’è nessuna equazione globale.
👉 Eppure stai già simulando un sistema dinamico.
Questo esempio può sembrare banale, ma è esattamente da qui che nascono simulazioni molto più complesse: epidemie, mercati finanziari, traffico urbano o diffusione delle opinioni. E’ la base della diffusione spaziale.
Rappresenta l’entropia.
In fisica si chiama “Random Walk” ed è fondamentale per modellare come i gas si espandono in una stanza o come i cercatori di cibo si muovono in un territorio inesplorato. Serve a capire il “punto zero”: cosa succede se non ci sono regole sociali, ma solo movimento?
Basta cambiare le regole locali degli agenti… e il comportamento globale del sistema cambia radicalmente.
Esempio 2: diffusione di un’informazione
Idea
Ogni agente può essere:
- 🟢 Ignaro (S) → non conosce l’informazione
- 🔴 Informato (I) → la diffonde agli altri
Regola:
Se un agente informato è vicino a uno ignaro → può “contagiarlo”
Codice completo
from mesa import Agent, Model
from mesa.space import MultiGrid
import random
# ======================
# Agente
# ======================
class PersonAgent(Agent):
def __init__(self, model, state="S"):
super().__init__(model)
self.state = state # S = ignaro, I = informato
def step(self):
neighbors = self.model.grid.get_neighbors(
self.pos,
moore=True,
include_center=False
)
# Se sono informato, provo a contagiare
if self.state == "I":
for neighbor in neighbors:
if neighbor.state == "S":
if random.random() < self.model.infection_prob:
neighbor.state = "I"
# Movimento casuale
possible_steps = self.model.grid.get_neighborhood(
self.pos,
moore=True,
include_center=False
)
new_position = random.choice(possible_steps)
self.model.grid.move_agent(self, new_position)
# ======================
# Modello
# ======================
class InfoSpreadModel(Model):
def __init__(self, n_agents, width, height, infection_prob=0.3):
super().__init__()
self.grid = MultiGrid(width, height, torus=True)
self.agents_list = []
self.infection_prob = infection_prob
# Creazione agenti
for i in range(n_agents):
# uno solo parte informato
state = "I" if i == 0 else "S"
agent = PersonAgent(self, state)
self.agents_list.append(agent)
x = random.randrange(width)
y = random.randrange(height)
self.grid.place_agent(agent, (x, y))
def step(self):
random.shuffle(self.agents_list)
for agent in self.agents_list:
agent.step()
def count_informed(self):
return sum(1 for a in self.agents_list if a.state == "I")
Esecuzione
model = InfoSpreadModel(n_agents=20, width=10, height=10, infection_prob=0.4)
for step in range(10):
model.step()
informed = model.count_informed()
print(f"Step {step+1}: Informati = {informed}")
Step 1: Informati = 1
Step 2: Informati = 1
Step 3: Informati = 1
Step 4: Informati = 3
Step 5: Informati = 5
Step 6: Informati = 7
Step 7: Informati = 7
Step 8: Informati = 8
Step 9: Informati = 9
Step 10: Informati = 11
Cosa dimostra
Qui succede qualcosa di molto più interessante rispetto al primo esempio:
1. Interazione locale → effetto globale
Gli agenti:
- vedono solo i vicini
- prendono decisioni semplici
👉 ma emerge una dinamica globale:
la diffusione dell’informazione
Non linearità
Cambiando leggermente:
infection_prob = 0.6 → esplosione rapida
piccoli cambiamenti nelle regole locali possono generare effetti macroscopici completamente diversi.
Questo esempio è praticamente:
- una base per modelli epidemiologici (SIR)
- una simulazione di viralità sui social
- un modello di diffusione delle opinioni
Questo esercizio è affascinante perché introduce la Soglia di Criticità. Se imposti la probabilità di contagio al 5%, l’informazione muore quasi subito. Se la imposti al 30%, invade il sistema. È il cuore del marketing virale e dell’epidemiologia: permette di trovare il “tipping point”, ovvero quel valore minimo per cui un fenomeno locale diventa una pandemia (o un trend su TikTok).
🌐 Dalle reti agli agenti: capire (e simulare) la complessità
Prima di simulare sistemi complessi con Mesa, devi capire come nascono: dalle connessioni tra individui, dati e comportamenti.
- 👉 Come rappresentare una rete in Python (e prepararla per una simulazione)
Matrici di adiacenza, strutture dati e basi per modelli agent-based.
- 👉Chi conta davvero in una rete? Il concetto di centralità spiegato bene
Identifica nodi chiave prima di simularne il comportamento.
- 👉 Campagne virali: la rete conta più del contenuto
Come usare la network science per progettare diffusione e impatto.
- 👉 Meme, epidemie e viralità: perché tutto segue le stesse leggi
Dai modelli epidemiologici alle simulazioni agent-based.
- 👉 Sei gradi di separazione: quanto è davvero connesso il tuo mercato?
La struttura nascosta delle reti che determina diffusione e conversioni.





