-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathWealthModel.py
168 lines (147 loc) · 6.33 KB
/
WealthModel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import random
import math
import mesa
from mesa import Agent, Model
from mesa.time import RandomActivation
from mesa.space import MultiGrid
from mesa.datacollection import DataCollector
#Global variables
treasury = 0
economy_scale = 10
project_participation = 0
def compute_gini(model):
agent_wealths = [agent.wealth for agent in model.schedule.agents]
x = sorted(agent_wealths)
N = model.num_agents
B = sum(xi * (N - i) for i, xi in enumerate(x)) / (N * sum(x))
return (1 + (1 / N) - 2 * B)
class WealthModel(Model):
"""A model with some number of agents."""
global treasury
def __init__(self, N, width, height):
self.num_agents = N
self.running = True
self.grid = MultiGrid(height, width, True)
self.schedule = RandomActivation(self)
self.datacollector = DataCollector(
model_reporters={"Gini": compute_gini},
agent_reporters={"Wealth": lambda a: a.wealth}
)
# Create agents
for i in range(self.num_agents):
a = WealthAgent(i, self)
self.schedule.add(a)
# Add the agent to a random grid cell
x = random.randrange(self.grid.width)
y = random.randrange(self.grid.height)
self.grid.place_agent(a, (x, y))
def step(self):
self.datacollector.collect(self)
self.schedule.step()
def run_model(self, n):
for i in range(n):
self.step()
print("step = ", step())
"""tax_period = step()%10
if tax_period == 0
return_tax(self, treasury)"""
class WealthAgent(Agent):
""" An agent with fixed initial wealth."""
def __init__(self, unique_id, model):
super().__init__(unique_id, model)
self.wealth = 1
x = random.randint(0, self.model.grid.width-1)
y = random.randint(0, self.model.grid.height-1)
#print("X Y", x, "and", y)
if self.model.grid.is_cell_empty([x,y]) == False:
rich_pos = (x,y)
rich_receivers = self.model.grid.get_cell_list_contents(rich_pos)
rich = random.choice(rich_receivers)
inequality_c = 4
rich.wealth += inequality_c
def move(self):
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)
## Daily expenses
# At every step, the agent makes a transaction with one of their neighbors
def daily_transactions(self, coins):
cellmates = self.model.grid.get_cell_list_contents([self.pos])
if len(cellmates) > 1:
other = random.choice(cellmates)
other.wealth += coins
self.wealth -= coins
## Altruism
# At every step, the agent makes a 50/50 choice of whether to donate money or not
# If the agent chooses to donate, they donate
def donate_money(self):
neighbours = self.model.grid.get_neighborhood(self.pos, moore=True, include_center=False)
if len(neighbours) > 1:
altruism_c = 2
if self.wealth > altruism_c:
altruism = random.randint(0,1)
if altruism != 0:
for i in neighbours:
poor_cell_choice = random.choice(neighbours)
#print("POOR CELL CHOICE = ", poor_cell_choice)
poor_cell_contents = self.model.grid.get_cell_list_contents([poor_cell_choice])
if len(poor_cell_contents) != 0:
poor = random.choice(poor_cell_contents)
# If my neighbour's wealth is less than x% of my wealth,
# I will donate to them an arbitrary sum of money less than 30% of my wealth
if poor.wealth < 0.2*self.wealth:
print("Oh no, my neighbour is poor!", poor)
max_donation = int(round(0.3*self.wealth))
donation = random.randint(0, max_donation)
poor.wealth += donation
self.wealth -= donation
#print("My wealth after donation = ", self.wealth
break
else:
pass
## Taxes
# At every step, the agent's wealth is checked.
# If their wealth exceeds a certain amount, they are taxed 30% of their wealth.
# Upon paying tax, the agent is admitted to the Committee and can post a public project
def collect_tax(self):
global treasury
tax_c = 5
if self.wealth > tax_c:
tax = math.floor(0.3*self.wealth)
treasury += tax
self.wealth -= tax
print("I, member", self.pos, "have been taxed , paid", tax, "coin")
print("TREASURY =", treasury)
## Reward agents
# Agents who have participated in projects are rewarded with a bounty for completing the project
# Bounty coins are taken from the Treasury
def project_reward(self, width, height):
global treasury
global project_participation
treasury_c = 6
if treasury > treasury_c:
self.grid = MultiGrid(height, width, True)
x = random.randint(0, self.grid.width)
y = random.randint(0, self.grid.height)
#print("EMPTY = ", self.model.grid.is_cell_empty([x,y]))
if self.model.grid.is_cell_empty([x,y]) == False:
position = (x,y)
potential_receivers = self.model.grid.get_cell_list_contents(position)
receiver = random.choice(potential_receivers)
reward_c = 2
receiver.wealth += reward_c
treasury -= reward_c
project_participation += 1
#print("After reward, I own this much =", receiver.wealth)
print("TOTAL PARTICIPANTS = ", project_participation)
def step(self):
#self.move()
if self.wealth > 0:
expenditure_c = 5
self.daily_transactions(expenditure_c)
self.donate_money()
self.collect_tax()
self.project_reward(economy_scale,economy_scale)
#print("------------step------------")