-
Notifications
You must be signed in to change notification settings - Fork 182
Update boltzmann example for mesa 3.1.5
#247
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
base: main
Are you sure you want to change the base?
Changes from all commits
13b5c8a
863cc10
db3c30f
fce8682
96edde4
009a8cc
9657b57
4ae6426
0c38d34
c3d3754
2c9a720
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from boltzmann_wealth_model_network.model import BoltzmannWealthModelNetwork | ||
from mesa.visualization import ( | ||
Slider, | ||
SolaraViz, | ||
make_plot_component, | ||
make_space_component, | ||
) | ||
|
||
|
||
def agent_portrayal(agent): | ||
return { | ||
"color": "red" if agent.wealth == 0 else "green", | ||
"size": 30, | ||
} | ||
|
||
|
||
model_params = { | ||
"num_agents": Slider( | ||
label="Number of agents", | ||
value=10, | ||
min=5, | ||
max=20, | ||
step=1, | ||
), | ||
"num_nodes": Slider( | ||
label="Number of nodes", | ||
value=10, | ||
min=5, | ||
max=20, | ||
step=1, | ||
), | ||
} | ||
Comment on lines
+17
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I noticed that you handled the case where the number of agents is more than the number of nodes in the code (as one node only supports one agent) by ignoring the given value of number of nodes, which I think is a good approach. I would prefer that you let the user know that you are doing this though, by butting some sort of warning when the user does set the number of nodes<number of agents. I am saying this as the visualization will be counter intuitive if the user hasn't read the code. For instance, I set the number of nodes to 8 here but the visualization shows 18 I would prefer it if the warning were given in the GUI, but if that's too hard I think a terminal message should do it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
|
||
def post_process_lineplot(ax): | ||
ax.set_ylim(ymin=0) | ||
ax.set_xlim(xmin=0) | ||
|
||
|
||
SpacePlot = make_space_component(agent_portrayal) | ||
GiniPlot = make_plot_component("Gini", post_process=post_process_lineplot) | ||
|
||
model = BoltzmannWealthModelNetwork() | ||
|
||
page = SolaraViz( | ||
model, | ||
components=[ | ||
SpacePlot, | ||
GiniPlot, | ||
], | ||
model_params=model_params, | ||
name="Boltzmann_wealth_model_network", | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from mesa.discrete_space import CellAgent | ||
|
||
|
||
class MoneyAgent(CellAgent): | ||
"""An agent with fixed initial wealth""" | ||
|
||
def __init__(self, model): | ||
super().__init__(model) | ||
self.wealth = 1 | ||
|
||
def give_money(self): | ||
neighbours = list(self.cell.neighborhood.agents) | ||
if len(neighbours) > 0: | ||
other = self.random.choice(neighbours) | ||
other.wealth += 1 | ||
self.wealth -= 1 | ||
|
||
def step(self): | ||
if self.wealth > 0: | ||
self.give_money() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
import mesa | ||
import networkx as nx | ||
from mesa.discrete_space import Network | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should be "mesa.discrete_space.network import Network" |
||
|
||
from .agent import MoneyAgent | ||
|
||
|
||
def compute_gini(model): | ||
|
@@ -13,26 +16,31 @@ def compute_gini(model): | |
class BoltzmannWealthModelNetwork(mesa.Model): | ||
"""A model with some number of agents.""" | ||
|
||
def __init__(self, num_agents=7, num_nodes=10): | ||
def __init__(self, num_agents=10, num_nodes=10): | ||
super().__init__() | ||
self.num_agents = num_agents | ||
self.num_nodes = num_nodes if num_nodes >= self.num_agents else self.num_agents | ||
if self.num_agents > num_nodes: | ||
self.num_nodes = self.num_agents | ||
print(""" | ||
╔═══════════════════════════════════ Warning ════════════════════════════════════════╗ | ||
║ Number of agents > Number of nodes. ║ | ||
║ Since each node can hold only one agent, so num_nodes has been set to num_agents. ║ | ||
╚════════════════════════════════════════════════════════════════════════════════════╝ | ||
""") | ||
else: | ||
self.num_nodes = num_nodes | ||
self.G = nx.erdos_renyi_graph(n=self.num_nodes, p=0.5) | ||
self.grid = mesa.experimental.cell_space.Network( | ||
self.G, random=self.random, capacity=1 | ||
) | ||
self.grid = Network(self.G, random=self.random, capacity=1) | ||
|
||
self.datacollector = mesa.DataCollector( | ||
model_reporters={"Gini": compute_gini}, | ||
agent_reporters={"Wealth": lambda _: _.wealth}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand that agent_reporters is not used explicitly in the code, but do you think we should just leave it in if the user wants to do post-simulation analysis? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I feel it should be the user's choice |
||
) | ||
|
||
list_of_random_nodes = self.random.sample(list(self.G), self.num_agents) | ||
|
||
# Create agents | ||
for position in list_of_random_nodes: | ||
agent = MoneyAgent(self) | ||
|
||
# Add the agent to a random node | ||
agent.move_to(self.grid[position]) | ||
|
||
|
@@ -43,30 +51,3 @@ def step(self): | |
self.agents.shuffle_do("step") | ||
# collect data | ||
self.datacollector.collect(self) | ||
|
||
def run_model(self, n): | ||
for i in range(n): | ||
self.step() | ||
|
||
|
||
class MoneyAgent(mesa.experimental.cell_space.CellAgent): | ||
"""An agent with fixed initial wealth.""" | ||
|
||
def __init__(self, model): | ||
super().__init__(model) | ||
self.wealth = 1 | ||
|
||
def give_money(self): | ||
neighbors = [agent for agent in self.cell.neighborhood.agents if not self] | ||
if len(neighbors) > 0: | ||
other = self.random.choice(neighbors) | ||
other.wealth += 1 | ||
self.wealth -= 1 | ||
|
||
def step(self): | ||
empty_neighbors = [cell for cell in self.cell.neighborhood if cell.is_empty] | ||
if empty_neighbors: | ||
self.cell = self.random.choice(empty_neighbors) | ||
|
||
if self.wealth > 0: | ||
self.give_money() |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
jupyter | ||
matplotlib | ||
mesa~=2.0 | ||
numpy | ||
mesa | ||
solara | ||
networkx | ||
matplotlib | ||
altair |
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.