diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..20be81a --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +worker.py \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/0829/env.py b/0829/env.py deleted file mode 100644 index b92e811..0000000 --- a/0829/env.py +++ /dev/null @@ -1,91 +0,0 @@ -import agentpy as ap - -from random import uniform - -from worker import WorkerAgent -from firm import FirmAgent - - -class Env(ap.Model): - - float_market_size: float - percent_rh: float - percent_search: float - n_worker: int - n_firm: int - e_revenue: float - - a_lst_worker: ap.AgentList - a_lst_firm: ap.AgentList - - def setup(self): - # 工作人员、企业数量、搜寻企业数量赋值 - self.n_worker = self.p.n_worker - self.n_firm = self.p.n_firm - self.percent_search = self.p.percent_search - # 工人、企业列表 - self.a_lst_worker = ap.AgentList(self) - self.a_lst_firm = ap.AgentList(self) - self.e_revenue = 119.3 - - # 在工人列表中添加工人 - for i in range(self.n_worker): - # 初始化 workeragent,并把alpha属性传过去 - w = WorkerAgent(self, self.p.alpha) - self.a_lst_worker.append(w) - - # 在企业列表中添加企业,放入一个is_RH_ratio, 即有多大比例的企业是属于RH类型的 - for i in range(self.n_firm): - # 对于企业属性true or false 的判断, 影响到firm 板块下, self.s_IsRH = is_RH 语句的判断 - f = FirmAgent(self, self.p.is_RH_ratio >= uniform(0, 1)) - self.a_lst_firm.append(f) - - def update_e_revenue(self): - self.e_revenue += 0.01 * self.e_revenue - - def step(self): - self.update_e_revenue() - # 先清空每次的选择列表 - self.a_lst_firm.empty_apply() - # 一开始worker要去选择很多firm - self.a_lst_worker.select_firm() - # 第二步, firm 去选 worker - self.a_lst_firm.select_worker() - - if self.t == 100: - self.stop() - pass - - def provide_lst_random_firms(self, the_worker: WorkerAgent): - '''选择企业数量 = 企业总数*百分比 - 选择企业的列表 = 随机选择的企业的个数 - 如果员工处于被雇佣的状态: - 如果员工工作的企业在随机选定的企业列表中: - 打开列表中的企业 - 移除该企业 - 返回值:移除后,再重新选择随机选择企业 - 否则: - 返回值:选择企业列表 - ''' - n_select_firms = int(self.percent_search * self.n_firm) - a_lst_select_firms = self.a_lst_firm.random(n_select_firms) - if the_worker.s_is_hired: - if the_worker.working_firm in a_lst_select_firms: - # 转换为 list - lst_f = list(self.a_lst_firm) - lst_f.remove(the_worker.working_firm) - return ap.AgentList(self, lst_f).random(n_select_firms) - # 假如以上都不满足, 直接返回 - return ap.AgentList(self, a_lst_select_firms) - - -if __name__ == '__main__': - dict_para = {'n_worker': 100, - 'n_firm': 20, - 'percent_search': 0.2, - 'alpha': 0.5, - 'is_RH_ratio': 0.5} - my_model = Env(dict_para) - my_model.run() - - diff --git a/0829/firm.py b/0829/firm.py deleted file mode 100644 index c535e9c..0000000 --- a/0829/firm.py +++ /dev/null @@ -1,138 +0,0 @@ -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 diff --git a/0829/main.py b/0829/main.py deleted file mode 100644 index bf8b9e5..0000000 --- a/0829/main.py +++ /dev/null @@ -1,16 +0,0 @@ -# This is a sample Python script. - -# Press Shift+F10 to execute it or replace it with your code. -# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings. - - -def print_hi(name): - # Use a breakpoint in the code line below to debug your script. - print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint. - - -# Press the green button in the gutter to run the script. -if __name__ == '__main__': - print_hi('PyCharm') - -# See PyCharm help at https://www.jetbrains.com/help/pycharm/ diff --git a/0829/worker.py b/0829/worker.py deleted file mode 100644 index 7a5d89b..0000000 --- a/0829/worker.py +++ /dev/null @@ -1,93 +0,0 @@ -import math - -import agentpy as ap -from random import uniform, randint - -# 编程可以自动补充一些东西,减少报错 -from typing import TYPE_CHECKING -if TYPE_CHECKING: - from firm import FirmAgent - - -class WorkerAgent(ap.Agent): - select_firm: object - c_effort: float - s_is_hired: bool - # c_work_months: int - s_work_duration: int - working_firm: 'FirmAgent' - s_salary: float - s_yield: float - # s_w_applied: bool - c_alpha: float - - def setup(self, alpha): - # super().__init__(unique_id, model) - # self.num_workers = 10000 - self.c_effort = uniform(0, 1) - # self.c_work_months = randint(0, 60) - self.s_is_hired = False - self.s_work_duration = randint(0, 60) - self.c_alpha = alpha - self.update_yield() - self.s_salary = 0 - - # return - - # def A_Utility(self, c_w_weight=0.5): - # a = np.exp(FirmAgent.c_f_incentive, c_w_weight) - # b = np.exp(FirmAgent.s_f_profit/max(FirmAgent.s_f_profit), 1-c_w_weight) - # self.select_firm = a * b - - def select_firm(self): - ''' - 挑选出来的企业列表 - 数量:列表的长度 - ''' - lst_firms = self.model.provide_lst_random_firms(self) - n_firms = len(lst_firms) - # find the max incentive and profit among all firms - max_incentive, max_profit = 0, 0 - for f in lst_firms: - if f.c_incentive > max_incentive: - max_incentive = f.c_incentive - if f.s_profit > max_profit: - max_profit = f.s_profit - # computer the utility for each firm - max_utility, best_firm = 0, None - for f in lst_firms: - u = math.pow(f.c_incentive / max_incentive, self.c_alpha) * math.pow(f.s_profit/max_profit, 1-self.c_alpha) - if u > max_utility: - max_utility = u - best_firm = f - # print(f'{self}: my best firm is {best_firm} from {n_firms} firms with utility {max_utility}') - # 选出能够给自己带来最好的效用的企业,并输出/返回 - best_firm.apply(self) - return best_firm - - def update_wd_by_is_hired(self): - if self.s_is_hired == 1: - self.s_work_duration += 1 - self.update_yield() - self.update_salary() - - def update_salary(self, the_firm: 'FirmAgent'): - if self.s_salary == 0: - self.s_salary = the_firm.initial_f_salary - pass - else: - self.s_salary = self.s_salary * (1 + the_firm.c_incentive) - pass - - 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 - - def step(self): - self.update_wd_by_is_hired() - ''' - 是否更换公司成功的状态转换? - ''' \ No newline at end of file diff --git a/data_analysis.py b/data_analysis.py new file mode 100644 index 0000000..a71d30d --- /dev/null +++ b/data_analysis.py @@ -0,0 +1,27 @@ +import numpy as np +import pandas as pd + +num_time_step = 20 +num_iter = 10 + +env_data = pd.DataFrame(pd.read_excel('env_data.xlsx', engine='openpyxl')) + +assert env_data.shape[0] == num_iter * (num_time_step + 1) + +lst_df = [] +for i in range(num_iter): + df_tmp = env_data.iloc[i * (num_time_step + 1): (i + 1) * (num_time_step + 1), 1:] + lst_df.append(df_tmp) +# df_tmp = env_data.iloc[1: 21] +# lst_df.append(df_tmp) + + +x = np.array(env_data[['t']]) +y = np.array(env_data[['out_w_avg_salary']]) + +import matplotlib.pyplot as plt + +plt.xlabel('t') +plt.ylabel('out_w_avg_salary') +plt.plot(x, y) +plt.show() diff --git a/env.py b/env.py index b92e811..0338b21 100644 --- a/env.py +++ b/env.py @@ -1,13 +1,16 @@ import agentpy as ap - +import numpy as np from random import uniform +import math + +from traits.trait_types import self from worker import WorkerAgent from firm import FirmAgent +# plt.ion() class Env(ap.Model): - float_market_size: float percent_rh: float percent_search: float @@ -18,6 +21,17 @@ class Env(ap.Model): a_lst_worker: ap.AgentList a_lst_firm: ap.AgentList + """ + Worker: Mean(s), Gini(s) + Firm: Mean(($$\pi_{j,t}$$)), Gini($$\pi_{j,t}$$) + Env: Percent(IsHired) + """ + out_w_avg_salary: float + out_w_gini_salary: float + out_f_avg_profit: float + out_f_gini_profit: float + out_w_percent_hired: float + def setup(self): # 工作人员、企业数量、搜寻企业数量赋值 self.n_worker = self.p.n_worker @@ -26,7 +40,7 @@ class Env(ap.Model): # 工人、企业列表 self.a_lst_worker = ap.AgentList(self) self.a_lst_firm = ap.AgentList(self) - self.e_revenue = 119.3 + self.e_revenue = 1193e+7 # 在工人列表中添加工人 for i in range(self.n_worker): @@ -52,15 +66,103 @@ class Env(ap.Model): # 第二步, firm 去选 worker self.a_lst_firm.select_worker() - if self.t == 100: + self.a_lst_firm.update_yields() + + self.provide_logit_share() + + self.a_lst_firm.update_s_profit() + + self.create_and_destroy_bankrupt_firms() + + # self.picture_out() + self.update() + + if self.t == 200: self.stop() + # self.picture_out() pass + def update(self): + lst_salary = [] + n_hired = 0 + for w in self.a_lst_worker: + lst_salary.append(w.s_salary) + if w.s_is_hired: + n_hired += 1 + n_workers = len(lst_salary) + self.out_w_avg_salary = sum(lst_salary) / n_workers + self.out_w_gini_salary = self.gini(lst_salary) + + lst_profit = [] + n_w_firm = 0 + for f in self.a_lst_firm: + lst_profit.append(f.s_profit) + if f.s_profit > 0: + n_w_firm += 1 + n_firms = len(lst_profit) + self.out_f_avg_profit = sum(lst_profit) / n_firms + self.out_f_gini_profit = self.gini(lst_profit) + self.out_w_percent_hired = n_hired / n_workers + + self.record('out_w_avg_salary') + self.record('out_w_gini_salary') + self.record('out_f_avg_profit') + self.record('out_f_gini_profit') + self.record('out_w_percent_hired') + + def create_and_destroy_bankrupt_firms(self): + n_bankrupt_firms = 0 + for f in self.a_lst_firm: + if f.s_value < 0: + # 两种方式,第一种是直接淘汰企业(此处设定为清空企业员工,清空企业利润值和价值,相当于重新添加了一个新的企业?) + n_bankrupt_firms += 1 + # for work in f.l_senior_workers: + # work.s_is_hired = False + # for work in f.l_junior_workers: + # work.s_is_hired = False + # f.s_profit = 0 + # f.s_value = 0 + # 第二种方式,末位淘汰制,淘汰所有员工中单位产值(产值/工资)价值最低的 + f.l_all_w = f.l_junior_workers + f.l_senior_workers + for work in f.l_all_w: + work.unit_yield_salary = work.s_yield * 10000 / work.s_salary + f.l_all_w.sort(key=lambda x: x['unit_yield_salary'], reverse=True) + if work == f.l_all_w[-1]: + work.s_is_hired = False + + + # 第二种方式,末位淘汰制,淘汰所有员工中生产价值最低的 + # f.l_junior_workers.sort(key=lambda x: x['s_yield'], reverse=True) + # for work in f.l_junior_workers: + # # f.l_junior_workers.sort(key=lambda x: x['s_yield'], reverse=True) + # if work == f.l_junior_workers[-1]: + # work.s_is_hired = False + + + + # for f in self.a_lst_firm: + # if f.s_profit < 0: # TODO + # n_bankrupt_firms += 1 + # for work in f.l_senior_workers: + # work.s_is_hired = False + # for work in f.l_junior_workers: + # work.s_is_hired = False + # self.a_lst_firm.remove(f) + # del f + # if n_bankrupt_firms > 0: + # for _ in range(n_bankrupt_firms): + # f = FirmAgent(self, self.p.is_RH_ratio >= uniform(0, 1)) + # self.a_lst_firm.append(f) + + assert len(self.a_lst_firm) == self.n_firm, \ + f'current num firm {len(self.a_lst_firm)} != expected num firm {self.n_firm}' + + def provide_lst_random_firms(self, the_worker: WorkerAgent): '''选择企业数量 = 企业总数*百分比 选择企业的列表 = 随机选择的企业的个数 如果员工处于被雇佣的状态: - 如果员工工作的企业在随机选定的企业列表中: + 如果员工工作的企业在随机选定的企业列表中 打开列表中的企业 移除该企业 返回值:移除后,再重新选择随机选择企业 @@ -78,14 +180,59 @@ class Env(ap.Model): # 假如以上都不满足, 直接返回 return ap.AgentList(self, a_lst_select_firms) + def provide_logit_share(self): + fen_mu = 0 + for f in self.a_lst_firm: + fen_mu += math.exp(f.s_a_yield) + for f in self.a_lst_firm: + f.s_revenue = self.e_revenue * math.exp(f.s_a_yield) / fen_mu + + # def picture_out(self, the_worker: WorkerAgent): + # a = self.t + # b = len(the_worker.s_salary) + # plt.plot(a, b, 'ro') + # return plt.show() + + @staticmethod + def gini(x): + if len(x) == 0: + return 0 + if sum(x) == 0: + return 0 + x = np.array(x) + mad = np.abs(np.subtract.outer(x, x)).mean() # Mean absolute difference + r_mad = mad / np.mean(x) # Relative mean absolute difference + return 0.5 * r_mad + if __name__ == '__main__': - dict_para = {'n_worker': 100, - 'n_firm': 20, + dict_para = {'n_worker': 1000, + 'n_firm': 100, 'percent_search': 0.2, 'alpha': 0.5, 'is_RH_ratio': 0.5} my_model = Env(dict_para) - my_model.run() + # + # print(my_model.gini([10000, 0, 0, 0, 0, 0, 0])) + # my_model.run() + # # a = range(0, 101) + # # b = len(WorkerAgent.s_yield) + # # plt.plot(a,b) + # # plt.show() + # plt.show() + parameters = { + 'n_worker': 500, + 'n_firm': 10, + 'percent_search': 0.2, + 'alpha': 0.5, + # 'alpha': ap.Range(0, 1, 0.5), + 'is_RH_ratio': 0.5, + } + sample = ap.Sample(parameters) + # sample = ap.Sample(parameters, n=3) + # + exp = ap.Experiment(Env, sample, iterations=10, record=True) + results = exp.run() + results['variables']['Env'].to_excel('env_data.xlsx', engine='openpyxl') diff --git a/env_data.xlsx b/env_data.xlsx new file mode 100644 index 0000000..2543329 Binary files /dev/null and b/env_data.xlsx differ diff --git a/firm.py b/firm.py index c535e9c..21ff188 100644 --- a/firm.py +++ b/firm.py @@ -22,16 +22,26 @@ class FirmAgent(ap.Agent): initial_f_salary: float s_revenue: float s_profit: float + s_value: float + firing_worker: 'WorkerAgent' l_senior_workers: list l_junior_workers: list l_applied_workers: list + # def __init__(self, model, *args, **kwargs): + # super().__init__(model, args, kwargs) + # self.l_all_workers = None + def setup(self, is_RH): self.c_incentive = uniform(0, 1) # self.s_profit = randint(10, 20) + self.l_senior_workers, self.l_junior_workers = [], [] + self.l_all_workers = [] self.l_applied_workers = [] self.s_IsRH = is_RH self.initial_f_salary = randint(8000, 10000) + self.s_profit = 0 + self.s_value = 0 def apply(self, the_worker): self.l_applied_workers.append(the_worker) @@ -58,7 +68,21 @@ class FirmAgent(ap.Agent): best_worker = the_worker selected_worker = best_worker else: - selected_worker = self.l_applied_workers[0] # TODO + # selected_worker = self.l_applied_workers[0] # TODO + # 加入worker进入到某个企业,企业更新了自己的利润,利润差值作为该名员工能带来的单位利润,排序利润 + # 但是代码中对于员工产出是(0,1)值,需要先更新员工所在列表,然后更新企业产出、利润、工资总额,再用假设利润-上期利润 + # 问题是,当期的估算不能考虑到有员工会在下一期离指的问题,或许考虑换成?max_单位产出成本? + max_unit_yield_salary, p_salary, best_worker= 0.0,0.0, None + for the_worker in self.l_applied_workers: + if the_worker.s_salary == 0: + the_worker.p_salary = self.initial_f_salary + else: + the_worker.p_salary = the_worker.s_salary*(1+self.c_incentive) + the_worker.unit_yield_salary = the_worker.s_yield * 10000 / the_worker.p_salary + if the_worker.unit_yield_salary > max_unit_yield_salary: + max_unit_yield_salary = the_worker.unit_yield_salary + best_worker = the_worker + selected_worker = best_worker # print(f'{self}: my best firm is {best_firm} from {n_firms} firms with utility {max_utility}') # return best_worker # 当企业是想要利用产出最高的员工时,从申请的员工中选出产出最高的员工 @@ -80,18 +104,18 @@ class FirmAgent(ap.Agent): 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 + 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] + self.l_senior_workers = lst_all_worker[:n_senior_worker] if n_junior_worker == 0: self.l_junior_workers = [] else: - self.l_junior_workers = lst_sorted[n_senior_worker:] + self.l_junior_workers = lst_all_worker[n_senior_worker:] - def update_yields(self): # 需要改 + def update_yields(self): n_sw, n_jw = len(self.l_senior_workers), len(self.l_junior_workers) # acc_all_yield = 0 @@ -115,24 +139,19 @@ class FirmAgent(ap.Agent): 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): + def get_sum_salary(self): ''' 计算某公司整体的薪金水平 ''' - l_all_workers = l_senior_workers + l_junior_workers - sum_salary = self.salary + l_all_workers = self.l_senior_workers + self.l_junior_workers + sum_salary = 0.0 for the_worker in l_all_workers: - sum_salary += the_worker.salary - return + sum_salary += the_worker.s_salary + return sum_salary - def s_profit(self): - # ? - self.s_profit = self.logit_share() * self.p.e_revenue - self.sum_salary() - return + def update_s_profit(self): + self.s_profit = self.s_revenue - self.get_sum_salary() + self.s_value += self.s_profit def step(self): pass diff --git a/worker.py b/worker.py index 7a5d89b..1e68677 100644 --- a/worker.py +++ b/worker.py @@ -1,10 +1,12 @@ import math +import random import agentpy as ap from random import uniform, randint # 编程可以自动补充一些东西,减少报错 from typing import TYPE_CHECKING + if TYPE_CHECKING: from firm import FirmAgent @@ -30,6 +32,7 @@ class WorkerAgent(ap.Agent): self.s_work_duration = randint(0, 60) self.c_alpha = alpha self.update_yield() + self.s_salary = 0 # return @@ -47,37 +50,56 @@ class WorkerAgent(ap.Agent): lst_firms = self.model.provide_lst_random_firms(self) n_firms = len(lst_firms) # find the max incentive and profit among all firms - max_incentive, max_profit = 0, 0 + max_incentive, max_value = 0, 0 for f in lst_firms: if f.c_incentive > max_incentive: max_incentive = f.c_incentive - if f.s_profit > max_profit: - max_profit = f.s_profit + if f.s_value > max_value: + max_value = f.s_value # computer the utility for each firm + if max_value == 0: + return random.choice(lst_firms) max_utility, best_firm = 0, None for f in lst_firms: - u = math.pow(f.c_incentive / max_incentive, self.c_alpha) * math.pow(f.s_profit/max_profit, 1-self.c_alpha) - if u > max_utility: - max_utility = u - best_firm = f + if self.s_salary < f.s_profit * 1 / 10: + u = math.pow(f.c_incentive / max_incentive, self.c_alpha) * math.pow(f.s_value / max_value, + 1 - self.c_alpha) + if u > max_utility: + max_utility = u + best_firm = f + # if self.s_salary < best_firm.s_profit * 5 / 100: + best_firm.apply(self) + + # print(f'{self}: my best firm is {best_firm} from {n_firms} firms with utility {max_utility}') # 选出能够给自己带来最好的效用的企业,并输出/返回 - best_firm.apply(self) - return best_firm + # best_firm.apply(self) + # return best_firm + # self.update_wd_by_is_hired() def update_wd_by_is_hired(self): - if self.s_is_hired == 1: + if self.s_is_hired: self.s_work_duration += 1 self.update_yield() - self.update_salary() + self.update_salary(self.working_firm) def update_salary(self, the_firm: 'FirmAgent'): + if self.s_salary == 0: self.s_salary = the_firm.initial_f_salary pass else: - self.s_salary = self.s_salary * (1 + the_firm.c_incentive) - pass + if self.s_salary <= the_firm.s_profit*1/10: + if self.s_salary * (1 + the_firm.c_incentive) <= the_firm.s_profit*1/10: + self.s_salary = self.s_salary * (1 + the_firm.c_incentive) + pass + else: + self.s_salary = the_firm.s_profit*1/10 + pass + pass + else: + self.s_salary = the_firm.s_profit*1/10 + def update_yield(self): self.s_yield = 2 / (1 + math.exp(-0.01 * self.s_work_duration * self.c_effort)) - 1 @@ -85,9 +107,10 @@ class WorkerAgent(ap.Agent): def update_working_firm_is_hired(self, f: 'FirmAgent'): self.s_is_hired = True self.working_firm = f + self.update_wd_by_is_hired() def step(self): self.update_wd_by_is_hired() ''' 是否更换公司成功的状态转换? - ''' \ No newline at end of file + '''