Skip to content
Open
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
27 changes: 27 additions & 0 deletions examples/ideology_diffusion/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Ideological Diffusion Under Economic Stress

---

## Overview

Historical analysis reveals that authoritarian regimes often gain momentum by exploiting acute **socio-economic crises**. These movements leverage public dissatisfaction to shift political paradigms and consolidate power by convincing the population that radical measures are the only solution to systemic failures.

This **Agent-Based Model (ABM)** simulates how a population, when faced with adverse conditions such as high unemployment and economic instability, becomes vulnerable to extremist influence. The model explores the transition from neutral or moderate positions to radical ideologies, highlighting how external stressors and propaganda can drive political alignment—often as a desperate response to environmental pressure.

---

## Key Features

* **Ideological Evolution:** Agents move through three stages (Neutral, Moderate, and Radical) based on cumulative pressure.
* **Socio-Economic Stressors:** Global variables like economic crises and unemployment rates act as catalysts for dissatisfaction.
* **Media Influence:** Simulates the impact of propaganda based on individual susceptibility.
* **State Dynamics:** Includes government repression logic, which can either suppress or inadvertently accelerate radicalization (the "backfire effect").

---

## How to Run

To run the model interactively, ensure you have `mesa` and `solara` installed, then run the following command in the project root:

```bash
solara run app.py
Empty file.
31 changes: 31 additions & 0 deletions examples/ideology_diffusion/agents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from mesa import Agent


class Person(Agent):
def __init__(self, model, opinion="neutral"):
super().__init__(model)
self.opinion = opinion
self.resistance = self.random.uniform(0.2, 0.8)
self.susceptibility = self.random.uniform(0.0, 1.0)

def step(self):
# External pressure
external_pressure = (
self.model.economic_crisis + self.model.propaganda
) * self.susceptibility

# Social pressure
neighbors = self.model.grid.get_neighbors(self.pos, moore=True)
if neighbors:
radicals = sum(1 for n in neighbors if n.opinion == "radical")
social_pressure = radicals / len(neighbors)
else:
social_pressure = 0

influence = external_pressure + social_pressure - self.resistance

if influence > 0.4:
if self.opinion == "neutral":
self.opinion = "moderate"
elif self.opinion == "moderate":
self.opinion = "radical"
46 changes: 46 additions & 0 deletions examples/ideology_diffusion/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import solara
from mesa.experimental.solara_viz import (
SolaraViz,
make_plot_component,
make_space_component,
)
from model import IdeologyModel


def agent_portrayal(agent):
color = {
"neutral": "gray",
"moderate": "orange",
"radical": "red",
}[agent.opinion]

return {
"color": color,
"size": 40,
}


model_params = {
"N": solara.SliderInt(10, 300, value=120, label="Population"),
"economic_crisis": solara.SliderFloat(0.0, 1.0, value=0.5, label="Economic Crisis"),
"propaganda": solara.SliderFloat(0.0, 1.0, value=0.2, label="Propaganda"),
}

space = make_space_component(agent_portrayal)
plot = make_plot_component(
{
"Neutrals": "gray",
"Moderates": "orange",
"Radicals": "red",
}
)


@solara.component
def App():
SolaraViz(
IdeologyModel,
components=[space, plot],
model_params=model_params,
name="Ideology Diffusion Model",
)
50 changes: 50 additions & 0 deletions examples/ideology_diffusion/model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
from agents import Person
from mesa import Model
from mesa.datacollection import DataCollector
from mesa.space import MultiGrid
from mesa.time import RandomActivation
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RandomActivation was removed with Mesa 3



class IdeologyModel(Model):
def __init__(
self,
n=120,
width=15,
height=15,
economic_crisis=0.5,
propaganda=0.2,
seed=None,
):
super().__init__(seed=seed)

self.grid = MultiGrid(width, height, torus=True)
self.schedule = RandomActivation(self)

self.economic_crisis = economic_crisis
self.propaganda = propaganda

for _ in range(n):
agent = Person(self)
self.schedule.add(agent)

x = self.random.randrange(width)
y = self.random.randrange(height)
self.grid.place_agent(agent, (x, y))

self.datacollector = DataCollector(
{
"Neutrals": lambda m: sum(
a.opinion == "neutral" for a in m.schedule.agents
),
"Moderates": lambda m: sum(
a.opinion == "moderate" for a in m.schedule.agents
),
"Radicals": lambda m: sum(
a.opinion == "radical" for a in m.schedule.agents
),
}
)

def step(self):
self.datacollector.collect(self)
self.schedule.step()
Loading