==============
版权声明:由于公众号后台规则问题,本文暂时无法设置原创标记,但仍属原创内容,微信公众号“Python小屋”坚持只发原创技术文章。
=============
=============
问题描述:
在某些社会或经济活动中,多人(或公司、国家)结盟合作时通常能比单独活动时获得更大的收益,产生1+1>2的协同效应。同时也很显然,合理的利益分配方案对于这样的联盟能够长久持续是非常重要的。Shapley值是由美国经济学家L.S.Shapley在1953年提出的用于多人合作时利益分配的算法,该方法体现了各成员对联盟集体总收益的贡献程度,根据贡献大小进行利益分配,避免了平均主义,更加公平、合理。
某工厂马上就要下班的时候,突然来了一车零件需要在半小时内完成卸货,时间紧任务重,于是值班组长紧急安排张、刘、赵三个人加班卸货。这一车零件共有600个,半小时张一个人干活的话能卸100个、刘一个人干活的话能卸120个、赵一个人干活的话能卸50个;如果张、刘一起干活的话能卸260个,张、赵一起干活的话能卸350个,刘、赵一起干活的话能卸330个;三个人一起干活正好可以卸完600个。为了奖励三个人,组长给了2000块钱,如果按贡献大小分配的话每个人应该拿多少奖金呢?
假设张率先发起合作的邀请,先邀请刘加入再邀请赵加入,此时刘的贡献(即刘加入前后团队卸货能力的差)为260-100=160,赵的贡献为600-260=340;如果张先邀请赵再邀请刘,此时赵的贡献为350-100=250,刘的贡献为600-350=250。重复上面的过程,计算每个人率先发出邀请以及不同邀请顺序中每个人的贡献,得到下面的矩阵,左边一列表示不同发起人和邀请顺序。
张 刘 赵
张刘赵 100 160 340
张赵刘 100 250 250
刘张赵 140 120 340
刘赵张 270 120 210
赵张刘 300 250 50
赵刘张 270 280 50
然后对矩阵计算纵向平均值得到每个人的Shapley值,根据每个人Shapley值占比来计算和分配奖金。按照这个规则,得到张、刘、赵三人的Shapley值分别为196.66666667、196.66666667、206.66666667,按占比分配2000奖金的话三人分别得到655.56、655.56、688.89。
函数func()接收一个字典data和一个整数money作为参数,data字典中存放了不同组合的卸货能力,money表示总奖金,要求返回一个字典表示每个人应得奖金数量(人名顺序和data中相同),奖金数额保留2位小数,忽略因为四舍五入产生的误差,剩余的几分钱交工,多发的几分钱由组长补上。
参考代码:
运行结果: