2022-08-29 10:39:29 +08:00
|
|
|
|
import math
|
|
|
|
|
from typing import Union, Any
|
|
|
|
|
|
|
|
|
|
import agentpy as ap
|
|
|
|
|
from random import uniform, randint
|
|
|
|
|
|
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
|
from worker import WorkerAgent
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FirmAgent(ap.Agent):
|
|
|
|
|
c_incentive: float
|
|
|
|
|
s_IsRH: bool
|
|
|
|
|
s_avg_senior_yield: float
|
|
|
|
|
s_avg_junior_yield: float
|
|
|
|
|
s_a_yield: float
|
|
|
|
|
# s_salary: float
|
|
|
|
|
initial_f_salary: float
|
|
|
|
|
s_revenue: float
|
|
|
|
|
s_profit: float
|
|
|
|
|
l_senior_workers: list
|
|
|
|
|
l_junior_workers: list
|
|
|
|
|
l_applied_workers: list
|
|
|
|
|
|
|
|
|
|
def setup(self, is_RH):
|
|
|
|
|
self.c_incentive = uniform(0, 1)
|
|
|
|
|
# self.s_profit = randint(10, 20)
|
|
|
|
|
self.l_applied_workers = []
|
|
|
|
|
self.s_IsRH = is_RH
|
|
|
|
|
self.initial_f_salary = randint(8000, 10000)
|
|
|
|
|
|
|
|
|
|
def apply(self, the_worker):
|
|
|
|
|
self.l_applied_workers.append(the_worker)
|
|
|
|
|
|
|
|
|
|
def empty_apply(self):
|
|
|
|
|
self.l_applied_workers = []
|
|
|
|
|
|
|
|
|
|
def select_worker(self):
|
|
|
|
|
'''
|
|
|
|
|
企业找到最想招聘的员工
|
|
|
|
|
:return:
|
|
|
|
|
'''
|
|
|
|
|
n_workers = len(self.l_applied_workers)
|
|
|
|
|
if n_workers > 0:
|
|
|
|
|
selected_worker = None
|
|
|
|
|
if n_workers > 1:
|
|
|
|
|
# 对员工产出进行排队和比较
|
|
|
|
|
# 先判断是什么选择方式
|
|
|
|
|
if self.s_IsRH:
|
|
|
|
|
max_s_yield, best_worker = 0.0, None
|
|
|
|
|
for the_worker in self.l_applied_workers:
|
|
|
|
|
if the_worker.s_yield > max_s_yield:
|
|
|
|
|
max_s_yield = the_worker.s_yield
|
|
|
|
|
best_worker = the_worker
|
|
|
|
|
selected_worker = best_worker
|
|
|
|
|
else:
|
|
|
|
|
selected_worker = self.l_applied_workers[0] # TODO
|
|
|
|
|
# print(f'{self}: my best firm is {best_firm} from {n_firms} firms with utility {max_utility}')
|
|
|
|
|
# return best_worker
|
|
|
|
|
# 当企业是想要利用产出最高的员工时,从申请的员工中选出产出最高的员工
|
|
|
|
|
# if self.s_IsRH :
|
|
|
|
|
# # 计算该名员工的工资水平: 原有工资水平* (1+incentive)
|
|
|
|
|
# # bw_salary = self.best_worker.salary()
|
|
|
|
|
#
|
|
|
|
|
# # 将该名员工的产出与公司原有员工的产出进行对比,如果高于senior列表中的最后一名的产出,就进入senior_list, 否则进入junior_list
|
|
|
|
|
# self.l_senior_workers.append(best_worker)
|
|
|
|
|
# else:
|
|
|
|
|
# self.l_junior_workers.append(best_worker)
|
|
|
|
|
# # best_worker.apply(self)
|
|
|
|
|
# else:
|
|
|
|
|
# # 计算由于改名员工下一期的薪资总数(根据薪资函数更新)以及企业下一期的利润的差值,并选出最大值
|
|
|
|
|
else:
|
|
|
|
|
selected_worker = self.l_applied_workers[0]
|
|
|
|
|
selected_worker.update_working_firm_is_hired(self)
|
|
|
|
|
self.update_two_worker_list(selected_worker)
|
|
|
|
|
|
|
|
|
|
def update_two_worker_list(self, new_worker):
|
|
|
|
|
lst_all_worker = self.l_senior_workers + self.l_junior_workers + [new_worker]
|
|
|
|
|
lst_sorted = lst_all_worker.sort(key=lambda x: x['s_yield'], reverse=True) # from highest yield to lowest
|
|
|
|
|
n_all_worker = len(lst_all_worker)
|
|
|
|
|
# 向上取整数值
|
|
|
|
|
n_senior_worker = math.ceil(n_all_worker * 0.2)
|
|
|
|
|
n_junior_worker = n_all_worker - n_senior_worker
|
|
|
|
|
self.l_senior_workers = lst_sorted[:n_senior_worker]
|
|
|
|
|
if n_junior_worker == 0:
|
|
|
|
|
self.l_junior_workers = []
|
|
|
|
|
else:
|
|
|
|
|
self.l_junior_workers = lst_sorted[n_senior_worker:]
|
|
|
|
|
|
|
|
|
|
def update_yields(self): # 需要改
|
|
|
|
|
n_sw, n_jw = len(self.l_senior_workers), len(self.l_junior_workers)
|
|
|
|
|
# acc_all_yield = 0
|
|
|
|
|
|
|
|
|
|
if n_sw == 0:
|
|
|
|
|
self.s_avg_senior_yield = 0
|
|
|
|
|
else:
|
|
|
|
|
s_acc_senior_yield = 0
|
|
|
|
|
for sw in self.l_senior_workers:
|
|
|
|
|
# 加入工人主体的产出属性
|
|
|
|
|
s_acc_senior_yield += sw.s_yield
|
|
|
|
|
# acc_all_yield += sw.s_yield
|
|
|
|
|
self.s_avg_senior_yield = s_acc_senior_yield / n_sw
|
|
|
|
|
|
|
|
|
|
if n_jw == 0:
|
|
|
|
|
self.s_avg_junior_yield = 0
|
|
|
|
|
else:
|
|
|
|
|
s_acc_junior_yield = 0
|
|
|
|
|
for jw in self.l_junior_workers:
|
|
|
|
|
# 加入工人主体的产出属性
|
|
|
|
|
s_acc_junior_yield += jw.s_yield
|
|
|
|
|
self.s_avg_junior_yield = s_acc_junior_yield / n_jw
|
|
|
|
|
self.s_a_yield = 0.8 * self.s_avg_senior_yield + 0.2 * self.s_avg_junior_yield
|
|
|
|
|
|
|
|
|
|
def logit_share(self):
|
|
|
|
|
logit_share = math.exp(self.s_a_yield) / np.sum(math.exp(self.s_a_yield))
|
|
|
|
|
return logit_share
|
|
|
|
|
|
|
|
|
|
def sum_salary(self, l_senior_workers, l_junior_workers):
|
|
|
|
|
'''
|
|
|
|
|
计算某公司整体的薪金水平
|
|
|
|
|
'''
|
|
|
|
|
l_all_workers = l_senior_workers + l_junior_workers
|
|
|
|
|
sum_salary = self.salary
|
|
|
|
|
for the_worker in l_all_workers:
|
|
|
|
|
sum_salary += the_worker.salary
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
def s_profit(self):
|
|
|
|
|
# ?
|
|
|
|
|
self.s_profit = self.logit_share() * self.p.e_revenue - self.sum_salary()
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
def step(self):
|
|
|
|
|
pass
|