22import random
33
44import numpy as np
5- from mesa import Agent
65
6+ from mesa .experimental .cell_space import CellAgent
77
8- class StoreAgent (Agent ):
8+
9+ class StoreAgent (CellAgent ):
910 """An agent representing a store with a price and ability to move
1011 and adjust prices."""
1112
@@ -22,10 +23,8 @@ def __init__(self, model, price=10, can_move=True, strategy="Budget"):
2223 # / differential (Premium)
2324
2425 def estimate_market_share (self , new_position = None ):
25- position = new_position if new_position else self .pos
26- nearby_consumers = self .model .grid .get_neighborhood (
27- position , moore = True , include_center = False , radius = 8
28- )
26+ position = new_position if new_position else self .cell
27+ nearby_consumers = position .get_neighborhood (radius = 8 ).agents
2928
3029 # Filter nearby agents to include only ConsumerAgents.
3130 nearby_consumers = [
@@ -45,24 +44,23 @@ def move(self):
4544 if not self .can_move :
4645 return
4746
48- best_position = self .pos
47+ best_position = self .cell
4948 best_market_share = self .estimate_market_share ()
5049
51- for neighbor in self .model .grid .get_neighborhood (
52- self .pos , moore = True , include_center = False
53- ):
50+ for neighbor in self .cell .neighborhood :
5451 potential_market_share = self .estimate_market_share (new_position = neighbor )
5552 if potential_market_share >= best_market_share :
5653 best_market_share = potential_market_share
5754 best_position = neighbor
58- self .model .grid .move_agent (self , best_position )
55+
56+ self .cell = best_position
5957
6058 def adjust_price (self ):
6159 # Calculate competitor prices and the average competitor price
6260 competitor_prices = [
6361 store .price
64- for store in self .model .get_store_agents ()
65- if store . unique_id != self . unique_id
62+ for store in self .model .agents_by_type [ StoreAgent ]
63+ if store is not self
6664 ]
6765 average_competitor_price = (
6866 np .mean (competitor_prices ) if competitor_prices else self .price
@@ -71,7 +69,7 @@ def adjust_price(self):
7169 # Calculate the current and average market share
7270 current_market_share = self .market_share
7371 all_market_shares = [
74- store .market_share for store in self .model .get_store_agents ()
72+ store .market_share for store in self .model .agents_by_type [ StoreAgent ]
7573 ]
7674 average_market_share = np .mean (all_market_shares ) if all_market_shares else 0
7775
@@ -119,8 +117,8 @@ def adjust_price(self):
119117
120118 def identify_competitors (self ):
121119 competitors = []
122- for agent in self .model .agents :
123- if isinstance ( agent , StoreAgent ) and agent . unique_id != self . unique_id :
120+ for agent in self .model .agents_by_type [ StoreAgent ] :
121+ if agent is not self :
124122 # Estimate market overlap as a measure of competition
125123 overlap = self .estimate_market_overlap (agent )
126124 if overlap > 0 : # If there's any market overlap,
@@ -133,7 +131,7 @@ def estimate_market_overlap(self, other_store):
133131 This could be based on shared consumer base or other factors."""
134132 overlap = 0
135133
136- for consumer in self .model .get_consumer_agents () :
134+ for consumer in self .model .agents_by_type [ ConsumerAgent ] :
137135 preferred_store = consumer .determine_preferred_store ()
138136 if preferred_store in (self , other_store ):
139137 overlap += 1
@@ -156,7 +154,7 @@ def step(self):
156154 self .adjust_price ()
157155
158156
159- class ConsumerAgent (Agent ):
157+ class ConsumerAgent (CellAgent ):
160158 """A consumer agent that chooses a store
161159 based on price and distance."""
162160
@@ -165,8 +163,8 @@ def __init__(self, model):
165163 self .preferred_store = None
166164
167165 def determine_preferred_store (self ):
168- consumer_preference = self .model .consumer_preferences
169- stores = self .model .get_store_agents ()
166+ consumer_preference = self .model .agents_by_type [ ConsumerAgent ]
167+ stores = self .model .agents_by_type [ StoreAgent ]
170168
171169 if len (stores ) == 0 : # Check if the stores AgentSet is empty
172170 return None
@@ -177,11 +175,11 @@ def determine_preferred_store(self):
177175 for store in stores :
178176 # Calculate score based on consumer preference
179177 if consumer_preference == "proximity" :
180- score = self .euclidean_distance (self .pos , store .pos )
178+ score = self .euclidean_distance (self .cell . coordinate , store .cell . coordinate )
181179 elif consumer_preference == "price" :
182180 score = store .price
183181 else : # Default case includes both proximity and price
184- score = store .price + self .euclidean_distance (self .pos , store .pos )
182+ score = store .price + self .euclidean_distance (self .cell . coordinate , store .cell . coordinate )
185183
186184 # Update the list of best stores if a new minimum score is found
187185 if score < min_score :
0 commit comments