import numpy as np
days = 30
init_users = 5
order_amounts = [1000, 2000, 5000]
order_probs = [0.4, 0.35, 0.25]
p_order = 0.2
p_promote = 0.1
base_release_rate = 0.001
accel_release_rate = 0.005
def blind_box_draw(scenario):
if scenario == 'A':
return np.random.choice([1, 2, 3, 4], p=[0.25, 0.25, 0.25, 0.25])
elif scenario == 'B':
return np.random.choice([1, 2, 3, 4], p=[0.4, 0.3, 0.2, 0.1])
elif scenario == 'C':
return np.random.choice([1, 2, 3, 4], p=[0.1, 0.2, 0.3, 0.4])
class User:
def __init__(self, user_id, referrer=None, leg=None):
self.id = user_id
self.referrer = referrer
self.leg = leg
self.pending = 0
self.available = 0
self.total_orders = 0
self.left_team = []
self.right_team = []
self.orders = []
def add_order(self, amount, scenario):
if self.available >= amount and (self.total_orders + amount) <= 50000:
multiplier = blind_box_draw(scenario)
points_gained = amount * multiplier
self.pending += points_gained
self.total_orders += amount
self.orders.append(amount)
return True
return False
def release_points(self, rate):
release_amount = self.pending * rate
self.available += release_amount
self.pending -= release_amount
return release_amount
def simulate(scenario):
users = [User(i) for i in range(init_users)]
for user in users:
user.add_order(1000, scenario)
metrics = {
'day': [], 'total_pending': [], 'total_available': [], 'num_users': [],
'num_orders': [], 'team_growth': [], 'release_rate': [], 'total_team_points': []
}
zero_growth_streak = 0
for day in range(1, days + 1):
new_users = []
for user in list(users):
if np.random.rand() < p_promote:
new_id = len(users)
leg = 'left' if np.random.rand() < 0.5 else 'right'
new_user = User(new_id, referrer=user, leg=leg)
users.append(new_user)
new_users.append(new_user)
new_user.add_order(1000, scenario)
user.available += 1000
if leg == 'left':
user.left_team.append(new_user)
else:
user.right_team.append(new_user)
num_orders = 0
for user in users:
if np.random.rand() < p_order:
amount = np.random.choice(order_amounts, p=order_probs)
if user.add_order(amount, scenario):
num_orders += 1
for user in users:
if user.left_team or user.right_team:
L = sum(u.total_orders for u in user.left_team)
R = sum(u.total_orders for u in user.right_team)
min_R = min(R, L / 10)
effective_team_points = 11 * min_R
user.pending += effective_team_points
total_team_points = 0
for user in users:
L = sum(u.total_orders for u in user.left_team)
R = sum(u.total_orders for u in user.right_team)
total_team_points += L + R
if day == 1:
team_growth = total_team_points
else:
team_growth = total_team_points - metrics['total_team_points'][-1]
if team_growth == 0:
zero_growth_streak += 1
if zero_growth_streak >= 3:
release_rate = base_release_rate
elif zero_growth_streak >= 4:
release_rate = 0.0049
else:
release_rate = accel_release_rate
else:
zero_growth_streak = 0
release_rate = accel_release_rate
total_release = 0
for user in users:
total_release += user.release_points(release_rate)
total_pending = sum(user.pending for user in users)
total_available = sum(user.available for user in users)
metrics['day'].append(day)
metrics['total_pending'].append(total_pending)
metrics['total_available'].append(total_available)
metrics['num_users'].append(len(users))
metrics['num_orders'].append(num_orders)
metrics['team_growth'].append(team_growth)
metrics['release_rate'].append(release_rate)
metrics['total_team_points'].append(total_team_points)
return metrics
if __name__ == '__main__':
metrics_A = simulate('A')
metrics_B = simulate('B')
metrics_C = simulate('C')
print(metrics_A)
print(metrics_B)
print(metrics_C)