有一些金额不等的合同需要分配给n个员工,尽可能地实现员工分配到的金额和数量是平均的。

网上找到了实现的算法,原文平均分配,移动欠费催收款数据的分配应用实例 - 李振波 - 博客园

里面给出了三种可行算法

第一种:

倒序贪婪(我称之为倒序贪婪,也不懂该叫什么)

过程大概是这样(把m份数据分配到n个人的头上)

1.1 把待分配的数据m从大到小排序;

1.2 从数据m取出n份做为初始值分配给n个人;

1.3 把这n个人的数据从小到大排序;

1.4 从数据m再取出n份数据累加到n个人的头上

1.5 重复1.3-1.4直至数据分配结束

第二种:

随机贪婪(我称之为随机贪婪,也不懂该叫什么)

过程大概是这样(把m份数据分配到n个人的头上)

1.1 从数据m中随机取出n份做为初始值分配给n个人;

1.2 把n个人的数据从小到大排序;

1.3 从数据m中随机再取出n份数据累加到n个人的头上

1.4 重复1.2-1.3直至数据分配结束

第三种:

先进行几轮倒序贪婪,把大额度的数据排除,余下的数据再进行随机贪婪

该文章作者用asp实现了,并且作者说第三种方法效果最好。我用python实现了,但是我的数据是是第一种方法效果最好,还没找到原因,可能是我的数据量大,没有很多离群的点?目前还不知道原因。

我的python代码

1.先倒序再贪婪

import pymysql
import pandas as pd
import numpy as npdef excuteSQL(excutesql):db = pymysql.connect(host='localhost', user='root', password='admin',database='cuishou')cursor = db.cursor()cursor.execute(excutesql)result = cursor.fetchall()title = [i[0].lower() for i in cursor.description]print('数据获取完毕!')cursor.close()db.close()return result, titledef commitSQL(excutedata):db = pymysql.connect(host='localhost', user='root', password='admin', database='cuishou')cursor = db.cursor()cursor.executemany("insert into fenpei(uid,cid,camt) values(%s,%s,%s)", excutedata)db.commit()cursor.close()db.close()print('数据插入完毕!')if __name__=='__main__':# 取出金额数据result,title = excuteSQL('select * from calllist;')repay_data = pd.DataFrame(list(result),columns=title)# 取出员工数据result,title = excuteSQL('select * from user;')user_data = pd.DataFrame(list(result),columns=title)# 第一步:打乱员工顺序user_data = user_data.sample(frac=1).reset_index(drop=True)user_num=user_data.shape[0]# 第二步:案件金额倒序排序repay_data = repay_data.sort_values(by='repay',ascending=False)repay_data = repay_data.reset_index(drop=True)# repay_data = repay_data[:7]repay_num=repay_data.shape[0]# 第三步:如果案件数量少于员工数量,直接分配if repay_num <= user_num:fenpei_data=pd.DataFrame({'uid': user_data.iloc[:repay_num, 0],'cid': repay_data.iloc[:, 0],'camt': repay_data.iloc[:, 1]})# 第四步:先倒序分配,当分配案件数超过总案件数量的五分之一时,开始随机分配else:# 先分配一轮fenpei_data=pd.DataFrame({'uid': user_data.iloc[:, 0],'cid': repay_data.iloc[:user_num, 0],'camt': repay_data.iloc[:user_num, 1]})i=user_num# 倒序分配while i < (repay_num//2):qiuhe_data = fenpei_data.groupby('uid')['camt'].sum().sort_values()linshi_data = pd.DataFrame({'uid': qiuhe_data.index,'cid': repay_data.iloc[i:i+user_num, 0],'camt': repay_data.iloc[i:i+user_num, 1]})fenpei_data = pd.concat([fenpei_data, linshi_data])i = i+user_num# 将案件随机打乱repay_data = repay_data[i:].sample(frac=1).reset_index(drop=True)repay_num_new=repay_data.shape[0]i=0while i < repay_num_new:# 取user_num和repay_num_new-i之间的较小值 赋值给jj = user_num if user_num < (repay_num_new-i) else (repay_num_new-i)# user现有金额升序排列qiuhe_data = fenpei_data.groupby('uid')['camt'].sum().sort_values()qiuhe_data = qiuhe_data.iloc[:j]# 取出一批案件倒序排列linshi_repay = repay_data[i:i+j].sort_values(by='repay', ascending=False)# 加入到分配数据中linshi_data = pd.DataFrame({'uid': qiuhe_data.index,'cid': linshi_repay['id'],'camt': linshi_repay['repay']})fenpei_data = pd.concat([fenpei_data, linshi_data])i = i+jresult_tuple=[tuple(xi) for xi in fenpei_data.values]commitSQL(result_tuple)

2.全倒序

# 第三步:如果案件数量少于员工数量,直接分配
if repay_num <= user_num:fenpei_data=pd.DataFrame({'uid': user_data.iloc[:repay_num, 0],'cid': repay_data.iloc[:, 0],'camt': repay_data.iloc[:, 1]})else:# 先分配一轮fenpei_data=pd.DataFrame({'uid': user_data.iloc[:, 0],'cid': repay_data.iloc[:user_num, 0],'camt': repay_data.iloc[:user_num, 1]})i=user_numwhile i < repay_num:# 取user_num和repay_num_new-i之间的较小值 赋值给jj = user_num if user_num < (repay_num-i) else (repay_num-i)# user现有金额升序排列qiuhe_data = fenpei_data.groupby('uid')['camt'].sum().sort_values()qiuhe_data = qiuhe_data.iloc[:j]# 取出一批案件倒序排列linshi_repay = repay_data[i:i+j].sort_values(by='repay', ascending=False)# 加入到分配数据中linshi_data = pd.DataFrame({'uid': qiuhe_data.index,'cid': linshi_repay['id'],'camt': linshi_repay['repay']})fenpei_data = pd.concat([fenpei_data, linshi_data])i = i+j

3.全贪婪

# 第三步:如果案件数量少于员工数量,直接分配
if repay_num <= user_num:fenpei_data=pd.DataFrame({'uid': user_data.iloc[:repay_num, 0],'cid': repay_data.iloc[:, 0],'camt': repay_data.iloc[:, 1]})else:# 先分配一轮fenpei_data=pd.DataFrame({'uid': user_data.iloc[:, 0],'cid': repay_data.iloc[:user_num, 0],'camt': repay_data.iloc[:user_num, 1]})i=user_num# 倒序分配while i < repay_num:j = user_num if user_num < (repay_num-i) else (repay_num-i)qiuhe_data = fenpei_data.groupby('uid')['camt'].sum().sort_values()qiuhe_data = qiuhe_data.iloc[:j]linshi_repay = repay_data[i:i + j].sort_values(by='repay', ascending=False)# 加入到分配数据中linshi_data = pd.DataFrame({'uid': qiuhe_data.index,'cid': linshi_repay['id'],'camt': linshi_repay['repay']})fenpei_data = pd.concat([fenpei_data, linshi_data])i = i + j

金额平均分配算法 python实现相关推荐

  1. Java实现平均分配算法(附代码)

    最近公司有业务需求:要求实现批量分配操作,详情如下: 选择多个客户 选择多个员工 给每个员工分配客户 要求分配的客户数量尽量平均 选择的员工数大于选择的客户数时,一个员工分配一个客户,不够的就不分配 ...

  2. java 平均分配算法_java 分配算法

    /* * 随机分配 */ public Map allotOfRandom(List users,List tasks){ Map allot=new ConcurrentHashMap(); //保 ...

  3. php红包平均分配,红包平均分配算法

    直接上代码 import java.util.Iterator; import java.util.TreeSet; public class Hongbao { private final int[ ...

  4. java 平均分配算法_「角平分线」Java 计算角平分线 - seo实验室

    角平分线 有三个点,计算出角平分线.首先要算出两个点之间的方位角,根据方位角算出夹角.下面以角平分线长度是20示例计算. double dStartAngle = Math.atan2(mdE1 - ...

  5. python分配红包程序_Python版微信红包分配算法

    Python版微信红包分配算法 发布于 2015-05-08 10:54:23 | 151 次阅读 | 评论: 0 | 来源: 网友投递 Python编程语言Python 是一种面向对象.解释型计算机 ...

  6. 最全微信红包分配算法,不只是二倍均值那么简单

    最全微信红包分配算法!不只是二倍均值那么简单! 一.序言 本文要解决什么问题? 抢红包的顺序对红包收益有无影响? 抢红包的顺序对当运气王的概率有无影响? 红包接龙游戏每次都是先抢好还是后抢好? 红包接 ...

  7. Python:实现average absolute deviation平均绝对偏差算法(附完整源码)

    Python:实现average absolute deviation平均绝对偏差算法 def average_absolute_deviation(nums: list[int]) -> fl ...

  8. python文件处理:每隔一定数目删除;文件重命名;删除多余xml文件;将文件夹线所有文件平均分配到其他文件夹

    # -*- coding:utf-8 -*-''' fileName: createTime: modifyTime: description:written by donghao '''import ...

  9. 传统图像增强算法python实现

    本文参照:图像增强综述 - FANG_YANG - 博客园 (cnblogs.com)对传统图像增强方法做了总结,并把相关代码由matlab转成了python. 1. 像素级方法 1.1图像反转 图像 ...

最新文章

  1. R语言dplyr包mutate_all函数一次性处理所有的数据列的内容(使用统一的函数)实战
  2. python编码问题总结
  3. Scala集合的常用方法:sum/max/min/product
  4. 美国将对所有墨西哥输美商品加征关税,为何日本股市反而大跌?
  5. Spark Worker源码
  6. Pitch,Yaw,Roll的概念
  7. Python学生成绩处理专业版
  8. media query学习笔记
  9. 问道linux一键端,问道手游源码打包一键端搭建_附教程
  10. html——链接跳转
  11. 固态硬盘启动计算机时间,固态硬盘如何做到10秒快速开机
  12. 个人空间岁末大回报活动12月23日获奖名单
  13. css特殊符号编码大全
  14. 微软扩大与Meta的AI合作,强强联合,友商岌岌可危?
  15. 手机连上蓝牙耳机没有声音
  16. 数据分析漏斗模型浅谈
  17. linux重要的文件操作
  18. Dubbo Wrapper
  19. postman 获取接口参数_postman 接口参数化操作
  20. TiDB 在金融行业关键业务场景的实践(下篇)

热门文章

  1. 无监督学习-自编码器-补充|深度学习(李宏毅)(二十)
  2. Zotero+OneDrive多平台在线同步完美解决方案(一):安装配置、云端同步文献数据
  3. mysql vchar 最大长度_mysql VARCHAR的最大长度到底是多少
  4. 180122 逆向-Frida在Windows下的使用
  5. gif一键抠图 在线_5个一键抠图高效率工具
  6. android开发常用app有哪些,【推荐收藏】安卓开发中必备的那些神器APP
  7. 2020芝加哥计算机博士生录取,2020年芝加哥大学博士面试后多久知道结果
  8. VS2022配置OpenCV 4.3.0报错解决办法
  9. GPS传感器数据帧格式
  10. QQ斗地主终于出S60V5版本了!