2022-08-29 10:39:29 +08:00
|
|
|
|
import math
|
2022-10-31 15:05:22 +08:00
|
|
|
|
import random
|
2022-08-29 10:39:29 +08:00
|
|
|
|
|
|
|
|
|
import agentpy as ap
|
|
|
|
|
from random import uniform, randint
|
|
|
|
|
|
|
|
|
|
# 编程可以自动补充一些东西,减少报错
|
|
|
|
|
from typing import TYPE_CHECKING
|
2022-10-31 15:05:22 +08:00
|
|
|
|
|
2022-08-29 10:39:29 +08:00
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
from firm import FirmAgent
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WorkerAgent(ap.Agent):
|
2023-01-18 22:21:22 +08:00
|
|
|
|
# select_firm: object
|
|
|
|
|
c_effort: float # used in self.update_yield
|
|
|
|
|
s_is_hired: bool # updated in self.update_working_firm_is_hired, env.create_and_destroy_bankrupt_firms
|
2022-08-29 10:39:29 +08:00
|
|
|
|
# c_work_months: int
|
2023-01-18 22:21:22 +08:00
|
|
|
|
s_work_duration: int # updated in self.update_wd_by_is_hired
|
|
|
|
|
working_firm: 'FirmAgent' # updated in self.update_working_firm_is_hired, env.create_and_destroy_bankrupt_firms
|
|
|
|
|
s_salary: float # updated in self.update_salary
|
|
|
|
|
s_yield: float # updated in self.update_yield
|
2022-08-29 10:39:29 +08:00
|
|
|
|
# s_w_applied: bool
|
|
|
|
|
c_alpha: float
|
|
|
|
|
|
|
|
|
|
def setup(self, alpha):
|
|
|
|
|
self.c_effort = uniform(0, 1)
|
|
|
|
|
self.s_is_hired = False
|
2023-01-18 22:21:22 +08:00
|
|
|
|
self.s_work_duration = randint(30, 60)
|
2022-08-29 10:39:29 +08:00
|
|
|
|
self.c_alpha = alpha
|
|
|
|
|
self.update_yield()
|
2022-10-31 15:05:22 +08:00
|
|
|
|
|
2022-08-29 10:39:29 +08:00
|
|
|
|
self.s_salary = 0
|
|
|
|
|
|
|
|
|
|
def select_firm(self):
|
2023-01-18 22:21:22 +08:00
|
|
|
|
"""
|
2022-08-29 10:39:29 +08:00
|
|
|
|
挑选出来的企业列表
|
|
|
|
|
数量:列表的长度
|
2023-01-18 22:21:22 +08:00
|
|
|
|
"""
|
2022-08-29 10:39:29 +08:00
|
|
|
|
lst_firms = self.model.provide_lst_random_firms(self)
|
2023-01-18 22:21:22 +08:00
|
|
|
|
# n_firms = len(lst_firms)
|
2022-08-29 10:39:29 +08:00
|
|
|
|
# find the max incentive and profit among all firms
|
2022-10-31 15:05:22 +08:00
|
|
|
|
max_incentive, max_value = 0, 0
|
2022-08-29 10:39:29 +08:00
|
|
|
|
for f in lst_firms:
|
|
|
|
|
if f.c_incentive > max_incentive:
|
|
|
|
|
max_incentive = f.c_incentive
|
2022-10-31 15:05:22 +08:00
|
|
|
|
if f.s_value > max_value:
|
|
|
|
|
max_value = f.s_value
|
2022-08-29 10:39:29 +08:00
|
|
|
|
# computer the utility for each firm
|
2022-10-31 15:05:22 +08:00
|
|
|
|
if max_value == 0:
|
|
|
|
|
return random.choice(lst_firms)
|
2022-08-29 10:39:29 +08:00
|
|
|
|
max_utility, best_firm = 0, None
|
|
|
|
|
for f in lst_firms:
|
2023-01-18 22:21:22 +08:00
|
|
|
|
if self.s_salary < f.s_profit / 10:
|
2022-10-31 15:05:22 +08:00
|
|
|
|
u = math.pow(f.c_incentive / max_incentive, self.c_alpha) * math.pow(f.s_value / max_value,
|
2023-01-18 22:21:22 +08:00
|
|
|
|
1 - self.c_alpha)
|
2022-10-31 15:05:22 +08:00
|
|
|
|
if u > max_utility:
|
|
|
|
|
max_utility = u
|
|
|
|
|
best_firm = f
|
|
|
|
|
best_firm.apply(self)
|
|
|
|
|
|
2022-08-29 10:39:29 +08:00
|
|
|
|
def update_wd_by_is_hired(self):
|
2022-10-31 15:05:22 +08:00
|
|
|
|
if self.s_is_hired:
|
2022-08-29 10:39:29 +08:00
|
|
|
|
self.s_work_duration += 1
|
|
|
|
|
self.update_yield()
|
2022-10-31 15:05:22 +08:00
|
|
|
|
self.update_salary(self.working_firm)
|
2022-08-29 10:39:29 +08:00
|
|
|
|
|
|
|
|
|
def update_salary(self, the_firm: 'FirmAgent'):
|
|
|
|
|
if self.s_salary == 0:
|
|
|
|
|
self.s_salary = the_firm.initial_f_salary
|
|
|
|
|
else:
|
2023-01-18 22:21:22 +08:00
|
|
|
|
self.s_salary = max(min(self.s_salary * (1 + the_firm.c_incentive), the_firm.s_profit / 10), self.s_salary)
|
2022-08-29 10:39:29 +08:00
|
|
|
|
|
|
|
|
|
def update_yield(self):
|
|
|
|
|
self.s_yield = 2 / (1 + math.exp(-0.01 * self.s_work_duration * self.c_effort)) - 1
|
|
|
|
|
|
|
|
|
|
def update_working_firm_is_hired(self, f: 'FirmAgent'):
|
|
|
|
|
self.s_is_hired = True
|
|
|
|
|
self.working_firm = f
|
2022-10-31 15:05:22 +08:00
|
|
|
|
self.update_wd_by_is_hired()
|