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

Updated Model with Tax System #219

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
71 changes: 47 additions & 24 deletions examples/boltzmann_wealth_model_experimental/Readme.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,67 @@
# Boltzmann Wealth Model (Tutorial)
# Модель Розподілу Багатства за Болцманом💰

## Summary
Цей проєкт моделює розподіл багатства серед агентів у суспільстві за допомогою моделі, натхненної розподілом Болцмана. Агенти взаємодіють, передаючи гроші сусідам, сплачуючи податки та отримуючи допомогу, коли вони бідніють. Програма відстежує нерівність у розподілі багатства за допомогою коефіцієнта Джині та візуалізує динаміку системи.

A simple model of agents exchanging wealth. All agents start with the same amount of money. Every step, each agent with one unit of money or more gives one unit of wealth to another random agent. This is the model described in the [Intro Tutorial](https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html), with the completed code.
## Особливості💡

If you want to go over the step-by-step tutorial, please go and run the [Jupyter Notebook](https://github.com/projectmesa/mesa/blob/main/docs/tutorials/intro_tutorial.ipynb). The code here runs the finalized code in the last cells directly.
- **Агентне моделювання (ABM)**: Модель складається з агентів із індивідуальним багатством та поведінкою, зокрема переміщенням на сітці, обміном грошима та сплатою податків.
- **Оподаткування та перерозподіл**: Агенти сплачують податки залежно від свого багатства, а зібрані податки перерозподіляються серед агентів, які втратили всі свої кошти.
- **Коефіцієнт Джині**: Вираховується для відстеження нерівності в розподілі багатства з часом.
- **Візуалізація**: Поведінка системи візуалізується через графічне зображення положення агентів і їх багатства, а також графік коефіцієнта Джині.

As the model runs, the distribution of wealth among agents goes from being perfectly uniform (all agents have the same starting wealth), to highly skewed -- a small number have high wealth, more have none at all.
## Як це працює🧠

## How to Run
1. **Агенти**: Кожен агент починає з початковим багатством, що дорівнює 1. Вони випадково переміщуються на 2D-сітці та взаємодіють із сусідами, передаючи частину свого багатства.
2. **Оподаткування**: Агенти сплачують податки за фіксованою ставкою. Зібрані податки зберігаються у податковому фонді, який використовується для підтримки агентів, що втратили всі свої кошти.
3. **Перерозподіл**: Коли багатство агента знижується до 0, він отримує допомогу з податкового фонду, якщо там є ресурси.
4. **Обмін багатством**: Агенти, які знаходяться в одній комірці сітки, можуть випадково обмінюватися багатством, що призводить до змін у його розподілі.
5. **Вимірювання нерівності**: На кожному кроці обчислюється коефіцієнт Джині для вимірювання рівня нерівності в розподілі багатства.

To follow the tutorial example, launch the Jupyter Notebook and run the code in ``Introduction to Mesa Tutorial Code.ipynb`` which you can find in the main mesa repo [here](https://github.com/projectmesa/mesa/blob/main/docs/tutorials/intro_tutorial.ipynb)
## Візуалізація 📊

Make sure to install the requirements first:
- **Простір агентів**: Показує агентів на сітці, де розмір і колір агента відображають його багатство. Агенти з багатством відображаються синім кольором, а ті, хто не має багатства, — червоним.
- **Графік коефіцієнта Джині**: Показує еволюцію коефіцієнта Джині з часом, що демонструє рівень нерівності в популяції.

```
## Як запустити🚀

1. Встановіть залежності:
```bash
pip install -r requirements.txt
```
```

2. Запустіть візуалізацію:
```bash
solara run app.py
```

3. Відкрийте надане посилання у вашому браузері, щоб побачити симуляцію. Ви побачите простір агентів та графік коефіцієнта Джині.

To launch the interactive server, as described in the [last section of the tutorial](https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html#adding-visualization), run:
## Параметри📉

```
$ solara run app.py
```
Наступні параметри можуть бути змінені:

If your browser doesn't open automatically, point it to [http://127.0.0.1:8765/](http://127.0.0.1:8765/). When the visualization loads, click on the Play button.
- **N**: Кількість агентів у моделі (від 10 до 100).
- **Ставка податку**: Податкова ставка, яка застосовується до багатства агентів (від 0.0 до 1.0).
- **Розміри сітки**: Ширина і висота сітки, по якій переміщуються агенти (за замовчуванням: 10x10).

Ці параметри можна налаштувати у веб-інтерфейсі за допомогою повзунків, наданих Solara.

## Files
## Збір даних🧮

* ``model.py``: Final version of the model.
* ``app.py``: Code for the interactive visualization.
Модель використовує `DataCollector` з бібліотеки Mesa для відстеження:

## Further Reading
- **Багатства** кожного агента на кожному кроці.
- **Коефіцієнта Джині** для всієї моделі, щоб спостерігати зміни в нерівності з часом.

The full tutorial describing how the model is built can be found at:
https://mesa.readthedocs.io/en/latest/tutorials/intro_tutorial.html
## Структура коду📑

This model is drawn from econophysics and presents a statistical mechanics approach to wealth distribution. Some examples of further reading on the topic can be found at:
- **BoltzmannWealthModel**: Основний клас моделі, де налаштовується сітка, агенти та податкова система.
- **MoneyAgent**: Агенти, які можуть переміщуватися, сплачувати податки, передавати гроші сусідам і отримувати допомогу.
- **compute_gini**: Функція для обчислення коефіцієнта Джині на основі розподілу багатства агентів.
- **Візуалізація**: Використовуються Solara та Matplotlib для візуалізації агентів та нерівності в розподілі багатства.

[Milakovic, M. A Statistical Equilibrium Model of Wealth Distribution. February, 2001.](https://editorialexpress.com/cgi-bin/conference/download.cgi?db_name=SCE2001&paper_id=214)
## Майбутні покращення🤙

[Dragulescu, A and Yakovenko, V. Statistical Mechanics of Money, Income, and Wealth: A Short Survey. November, 2002](http://arxiv.org/pdf/cond-mat/0211175v1.pdf)
- **Індивідуальні стратегії переміщення**: Додати складніші схеми переміщення або поведінку агентів.
- **Динамічні податкові ставки**: Реалізувати зміни податкових ставок залежно від багатства агентів або інших економічних чинників.
- **Економічні політики**: Випробувати вплив різних економічних політик на розподіл багатства.
9 changes: 9 additions & 0 deletions examples/boltzmann_wealth_model_experimental/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,19 @@ def agent_portrayal(agent):
"max": 100,
"step": 1,
},
"tax_rate": {
"type": "SliderFloat",
"value": 0.1,
"label": "Tax Rate:",
"min": 0.0,
"max": 1.0,
"step": 0.01,
},
"width": 10,
"height": 10,
}


# Create initial model instance
model1 = BoltzmannWealthModel(50, 10, 10)

Expand Down
91 changes: 58 additions & 33 deletions examples/boltzmann_wealth_model_experimental/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,76 +2,101 @@


def compute_gini(model):
# Compute Gini coefficient based on agents' wealth
agent_wealths = [agent.wealth for agent in model.agents]
x = sorted(agent_wealths)
x = sorted(agent_wealths) # Sort the wealth values
N = model.num_agents
# Calculate the Gini coefficient using the sorted wealth values
B = sum(xi * (N - i) for i, xi in enumerate(x)) / (N * sum(x))
return 1 + (1 / N) - 2 * B


class BoltzmannWealthModel(mesa.Model):
"""A simple model of an economy where agents exchange currency at random.

All the agents begin with one unit of currency, and each time step can give
a unit of currency to another agent. Note how, over time, this produces a
highly skewed distribution of wealth.
"""

def __init__(self, N=100, width=10, height=10):
def __init__(self, N=100, width=10, height=10, tax_rate=0.1):
super().__init__()
self.num_agents = N
self.grid = mesa.space.MultiGrid(width, height, True)
self.tax_fund = 0
self.tax_rate = tax_rate # Store the tax rate

# Data collector to track Gini coefficient and agents' wealth
self.datacollector = mesa.DataCollector(
model_reporters={"Gini": compute_gini}, agent_reporters={"Wealth": "wealth"}
)
# Create agents
for _ in range(self.num_agents):
a = MoneyAgent(self)

# Add the agent to a random grid cell
x = self.random.randrange(self.grid.width)
y = self.random.randrange(self.grid.height)
self.grid.place_agent(a, (x, y))
# Create and place agents on the grid
for _ in range(self.num_agents):
a = MoneyAgent(self) # Instantiate a MoneyAgent
x = self.random.randrange(self.grid.width) # Random x position
y = self.random.randrange(self.grid.height) # Random y position
self.grid.place_agent(a, (x, y)) # Place agent on the grid

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

def distribute_taxes(self):
# Distribute the tax fund among agents with zero wealth
for agent in self.agents:
if agent.wealth == 0 and self.tax_fund > 0:
agent.receive_aid()
self.tax_fund -= 1

def pay_taxes(self):
for agent in self.agents:
if agent.wealth > 0:
agent.pay_taxes() # Call pay_taxes method for each agent

def step(self):
self.agents.shuffle_do("step")
# collect data
self.agents.shuffle_do("step") # Randomize agent execution order
self.distribute_taxes()
self.datacollector.collect(self)

def run_model(self, n):
for i in range(n):
self.step()


class MoneyAgent(mesa.Agent):
"""An agent with fixed initial wealth."""
"""Agent with initial wealth and taxation function."""

def __init__(self, model):
super().__init__(model)
self.wealth = 1
self.wealth = 1 # Initialize wealth

def move(self):
# Get possible neighboring positions to move
possible_steps = self.model.grid.get_neighborhood(
self.pos, moore=True, include_center=False
)
new_position = self.random.choice(possible_steps)
self.model.grid.move_agent(self, new_position)
new_position = self.random.choice(
possible_steps
) # Randomly choose a new position
self.model.grid.move_agent(self, new_position) # Move agent to new position

def give_money(self):
cellmates = self.model.grid.get_cell_list_contents([self.pos])
cellmates.pop(
cellmates.index(self)
) # Ensure agent is not giving money to itself
if len(cellmates) > 0:
other = self.random.choice(cellmates)
# Give money to a random neighbor (cellmate)
cellmates = self.model.grid.get_cell_list_contents(
[self.pos]
) # Get agents in the same cell
cellmates.pop(cellmates.index(self)) # Remove self from the list of cellmates
if len(cellmates) > 0 and self.wealth > 0:
other = self.random.choice(
cellmates
) # Choose a random agent to give money to
other.wealth += 1
self.wealth -= 1

def pay_taxes(self):
tax_rate = 0.1

Choose a reason for hiding this comment

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

@sofiabrezden @sofibrezden isn't it supposed to read the tax rate from the model?

tax_amount = self.wealth * tax_rate # Calculate tax amount
if tax_amount > self.wealth: # Ensure agent has enough wealth to pay taxes
tax_amount = self.wealth # Pay what they have
self.wealth -= tax_amount
self.model.tax_fund += tax_amount

def receive_aid(self):
# Aid is received if the agent's wealth is zero
if self.wealth == 0:
self.wealth += 1

def step(self):
self.move()
self.pay_taxes() # Pay taxes based on current wealth
if self.wealth > 0:
self.give_money()
self.give_money() # Give money to another agent if wealthy
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
mesa~=2.0
mesa==3.0.0b0
solara
git+https://github.com/projectmesa/mesa-examples
Loading