forked from omelyanchikd/ace
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbasic_world.py
102 lines (81 loc) · 4.22 KB
/
basic_world.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
import random
import numpy
from firm import Firm
#from firm_result import FirmResult
from firm_labormarket_result import FirmLaborMarketResult
from firm_goodmarket_result import FirmGoodMarketResult
from worker import Worker
from world import World
def invert(x):
if x != 0:
return 1 / x
else:
return 0
class BasicWorld(World):
def manage_firm_actions(self, firm_actions):
"""
Basic World! Contains basic algorithms for labor market and good market.
:param firm_actions:
:return:
"""
salaries = numpy.array(list(firm_action.salary if firm_action.salary >= 0 else 0 for firm_action in self.firm_actions))
self.fire()
new_workers, quited = self.manage_job_offers()
sales = self.manage_sales()
# Aggregate firm results
# for firm in self.firms:
# self.firm_results[firm.id] = FirmResult(new_workers[firm.id], quited[firm.id], salaries[firm.id],
# sales[firm.id])
def manage_job_offers(self):
initial_salaries = numpy.array(list(firm_action.salary if firm_action.salary >= 0 and firm_action.offer_count > 0
else 0 for firm_action in self.firm_labormarket_actions))
salaries = numpy.array(list(firm_action.salary if firm_action.salary > 0 and firm_action.offer_count > 0 else 0
for firm_action in self.firm_labormarket_actions))
max_salary = max(salaries)
quited = [[] for i in range(len(self.firms))]
new_workers = [[] for i in range(len(self.firms))]
potential_candidates = []
for worker in self.workers:
if worker.employer is None or worker.salary < max_salary:
potential_candidates.append(worker)
while len(potential_candidates) > 0 and sum(salaries) > 0:
worker = random.choice(potential_candidates)
employer = numpy.random.choice(self.firms, replace=False, p=salaries / sum(salaries))
assert isinstance(employer, Firm)
potential_candidates.remove(worker)
if worker.salary < salaries[employer.id]:
new_workers[employer.id].append(worker)
if worker.employer is not None:
quited[worker.employer].append(worker)
if self.firm_labormarket_actions[employer.id].offer_count == len(new_workers[employer.id]):
salaries[employer.id] = 0
for firm in self.firms:
self.firm_labormarket_results[firm.id] = FirmLaborMarketResult(new_workers[firm.id], quited[firm.id], initial_salaries[firm.id])
def manage_sales(self):
# Basic selection algorithm for good market
prices = numpy.array(list(firm_action.price if firm_action.price >= 0 and firm_action.production_count > 0
else 0 for firm_action in self.firm_goodmarket_actions))
inverted_prices = numpy.array(list(invert(x) for x in prices))
sales = [0] * len(self.firms)
money = self.money
for firm in self.firms:
if self.firm_goodmarket_actions[firm.id].production_count > self.firms[firm.id].stock:
self.firm_goodmarket_actions[firm.id].production_count = self.firms[firm.id].stock
production_counts = numpy.array(list(firm_action.production_count for firm_action in self.firm_goodmarket_actions))
while sum(prices) > 0 and money > 0:
seller = numpy.random.choice(self.firms, replace=False, p=inverted_prices / sum(inverted_prices))
assert isinstance(seller, Firm)
sales[seller.id] += 1
production_counts[seller.id] -= 1
money -= prices[seller.id]
if production_counts[seller.id] <= 0:
prices[seller.id] = 0
inverted_prices[seller.id] = 0
for firm in self.firms:
self.firm_goodmarket_results[firm.id] = FirmGoodMarketResult(sales[firm.id])
def fire(self):
fired_workers = list(firm_action.fire_people for firm_action in self.firm_actions)
# for worker in fired_workers:
# assert isinstance(worker, Worker)
# worker.employer = None
# worker.salary = 0