发布于2022-08-07 20:49 阅读(1033) 评论(0) 点赞(16) 收藏(3)
问题重述:
问题一解题思路(其他思路在链接里)
第一步:根据附件的订单信息,提取每个订单的货品种类数存入列表df_pv_list中,提取每个订单的编号存入列表orderno_list中,这两个列表中的元素个数一致,且每个订单编号对应的货品种类数在两个列表中的索引一致。例如,列表df_pv_list的第一个元素df_pv_list[0] =’D0001’对应的货品种类数,应为列表orderno_list的第一个元素orderno_list[0]=19种,即两个列表的索引值相互关联或者说完全一一对应。
第二步:根据附件的订单信息,创建一个‘键’由订单号组成,‘值’由订单号对应的的货品种类列表组成的字典dic。
第三步:从列表df_pv_list中获取一个最大值,即max_values = max(df_pv_list),通过index()方法得到max_values对应的索引值,即index_values = df_pv_list.index(max_values),由于列表df_pv_list与列表orderno_list的索引值相对应,可以得到对应的订单编号orderno_max = orderno_list[index_values]。由订单编号orderno_max从字典dic中获取该订单编号对应的货品种类依次存入batch_s列表中,并统计其中货品种类个数n。
第四步:用pop()方法将max_values从列表df_pv_list中移除,即df_pv_list.pop(index_values),由于在列表df_pv_list中max_values可能不止一个,为了保证列表df_pv_list和列表orderno_list元素严格一一对应,此处移除只能用pop()方法,根据索引值去移除元素。再将订单编号orderno_max从列表orderno_list中移除,即orderno_list.remove(orderno_max),此处移除操作可以使用remove()方法,因为列表orderno_list中的元素唯一,可以根据值去移除。
第五步:使用循环逐个从列表orderno_list取出订单编号,将取出来的订单编号作为‘键’从字典dic中得到每个订单对应的货品种类列表,再嵌套循环将每个订单对应的货品种类列表里的每个元素与列表batch_s里的每个元素相比较,设置计数器count,表示每个订单对应的货品种类与列表batch_s里的货品种类相同的件数。如果有相等的元素对count进行加1操作。将所有count值存入列表num_com中,注意:列表df_pv_list,列表orderno_list与列表num_com的数据是严格一一对应的,即相同索引从三个列表取的值是一一对应的。
第六步:判断n是否小于200,若是,则获取最大货品相同的件数max_num_com = max(num_com),获取对应的索引max_num_com_index = num_comt.index(max_num_com),获取对应的订单编号orderno_m = orderno_list[max_num_com_index],将获取的订单编号作为‘键’从字典dic中得到每个订单对应的货品种类列表,求其列表长度得到货品种类数num,用货品种类数num减去列表num_com对应的货品相同件数得到不相同件数,即num_none = num - num_com[max_num_com_index],并将该货品列表里的每个元素与batch_s列表中的元素一一比较,将不同的元素加入进batch_s列表中,再重新统计batch_s列表中的货品种数n。
第七步:创建批次列表batch_list(在第四步,执行移除操作之前应将订单orderno_max添加到该列表中)。将max_values赋给n,比较n是否小于200,若小于,将订单编号存入列表batch_list中,即batch_list.append(orderno_m),执行n =n +num_none操作。再将列表df_pv_list中对应的值移除,即df_pv_list.pop(max_num_com_index),将列表orderno_list中对应的值移除,即orderno_list.remove(orderno_m),将列表num_com设置为空;重复第五步至第七步操作直到n大于等于200;若大于,批次操作完成,打印出batch_list列表信息,将列表num_com设置为空,将列表batch_s设置为空,重复执行第三步至第七步操作。每次重复执行第三步至第七步操作时,都需判断列表df_pv_list和列表orderno_list列表是否为空。若为空,则所有订单都已处理完成,将保存在列表batch_list中的数据依批次打印出来即可,再将其输出至result1.csv文件中。否则继续执行重复操作。
分批算法Python实现:
创建每个订单的货品种类数量列表df_pv_list
创建每个订单编号列表orderno_list
创建每个订单与之对应的货品种类列表的字典dic
创建每批次列表batch_list
创建总批次列表sum_batch_list
创建每批次货品种类数列表batch_s
创建总批次货品种类数列表sum_batch_s
创建订单的货品种类的相同数列表num_com
4、主程序为利用for循环调用以上三个方法,每循环1次应得到1个批次结果,将每次循环得到的结果存入sun_bacth_list列表中,最后将最终结果转换为DataFrame结构数据,输入到result1.csv文件中。应有判断语句,判断orderno_list列表是否为空,若为空,则结束程序;否则,继续执行。、
python代码如下:
- '''
- 设计分批算法:将当日订单分为多个批次。要求每个批次的订单所含货品种类数均不
- 超过 ,且批次越少越好(相应转运次数也越少,效率越高)。针对附件 1 中的订单
- 信息,应用你们的算法,计算当货架数量 时最少的批次数,给出每批订单数
- 量、货品种类数、分批方案等结果,并将完整原始分批方案按指定格式输出到文件
- result1.csv 中
- '''
-
- import pandas as pd
-
- #将数据读取进来
- df = pd.read_csv(r'D:\Pycharm\pythonProject\data.csv')
- #将原始数据csv文件处理一下,生存OrderNoSum.csv(已放入了附件中),用来获取每个订单编号
- df1 = pd.read_csv(r'D:\Pycharm\pythonProject\OrderNoSum.csv')
- orderno_list = []
- for i in df1['OrderNo'].values:
- orderno_list.append(i)
- #统计每个订单的货品种类数量
- df_pv = df.groupby('OrderNo')['ItemNo'].count()
- #将每个订单的货品种类数量存入列表中
- df_pv_list=[] #923个值
- for i in df_pv.values:
- df_pv_list.append(i)
- #获取每个订单货品的编号与其种类数量相对
- itemno_list = df['ItemNo'].values
- #将每个订单的货品种类改成键值对的形式
- dic = {}
- sum_x = 0
- dic.setdefault('{}'.format(orderno_list[0]),'{}'.format(list(itemno_list[0:df_pv_list[0]])))
- for i in range(1,923):
- sum_x = sum_x + df_pv_list[i-1]
- dic.setdefault('{}'.format(orderno_list[i]),'{}'.format(list(itemno_list[sum_x:(sum_x+df_pv_list[i])])))
- #每批次订单所含货品种类数列表
- def getMax_per_batch_info(n):
- if df_pv_list == []:
- print('df_pv_list为空,数据已全部处理。')
- if orderno_list == []:
- print('orderno_list为空,订单已全部处理。')
- return
-
- #获取货品种类数最大的值
- if batch_s == []:
- max_values = max(df_pv_list)
- #df_pv_list.remove(max_values)
- # #获取货品种类数最大的值的索引
- index_values = df_pv_list.index(max_values)
- # #获取订单编号
- orderno_max = orderno_list[index_values]
- #将订单编号放入批次列表中
- batch_list.append(orderno_max)
- # #从dic中获取订单对应的货品
- item_list_max = eval(dic[orderno_max])
- #将货品加入每批次订单所含货品种类数列表
- for i in item_list_max:
- if i in batch_s:
- n=n
- else:
- batch_s.append(i)
- n=n+1
- df_pv_list.pop(index_values)
- orderno_list.remove(orderno_max)
-
- else:
- n = n
- return [batch_s,n]
- def get_num_com(i_l_m):
- for x in orderno_list:
- count = 0
- for j in eval(dic[x]):
- for i in i_l_m:
- if j == i:
- count = count + 1
- break
- num_com.append(count)
- return num_com
-
- def get_batch_info(n,num_com):
- while n < N:
- max_num_com = max(num_com)
- #获取最大重叠率的索引
- max_num_com_index = num_com.index(max_num_com)
- #获取最大相同种类数的的订单编号
- orderno_m = orderno_list[max_num_com_index]
- num = len(eval(dic[orderno_m]))
- #非重叠货品种类数量
- num_com_num = num_com[max_num_com_index]
- num_none = num - num_com[max_num_com_index]
- #批次总的货品种类数(不能大于200)
- n = n + num_none
- #print(n)
- while n > N:
- #print('n>N')
- orderno_list_copy = orderno_list[:]
- while True:
- n = n - num_none
- orderno_list_copy.remove(orderno_m)
- num_com.pop(max_num_com_index)
- if num_com == []:
- break
- max_num_com = max(num_com)
- max_num_com_index = num_com.index(max_num_com)
- orderno_m = orderno_list_copy[max_num_com_index]
- num = len(eval(dic[orderno_m]))
- num_com_num = num_com[max_num_com_index]
- num_none = num - num_com[max_num_com_index]
- n = n + num_none
- if n>N:
- orderno_list_copy = orderno_list_copy[:]
- continue
- else:
- break
- break
- if num_com == []:
- break
- else:
- # 将货品加入列表中
- for i in eval(dic[orderno_m]):
- if i in batch_s:
- continue
- else:
- batch_s.append(i)
- # 将订单编号放入批次列表中
- batch_list.append(orderno_m)
-
- df_pv_list.pop(max_num_com_index)
- orderno_list.remove(orderno_m)
- break
- return n
-
-
-
-
- #主程序
- sum_batch_s =[]
- # 相同货品种类数列表
- num_com = []
- #批次列表
- batch_list = []
- #总的批次列表
- sum_batch_list = []
- N = 200
-
- for i in range(1,80):
- if df_pv_list == []:
- if orderno_list == []:
- break
- # 每批次订单所含货品种类数列表
- batch_list = []
- num_com = []
- batch_s = []
- n=0
- arg_list = getMax_per_batch_info(n)
- if arg_list == None:
- print('数据已全部处理。')
- break
- else:
- b=get_num_com(arg_list[0])
- n = get_batch_info(arg_list[1],b)
-
-
-
- while True:
- num_com = []
- arg_list = getMax_per_batch_info(n)
- if arg_list == None:
- sum_batch_list.append(batch_list)
- sum_batch_s.append(batch_s)
- print('数据已全部处理。')
- break
- else:
- b = get_num_com(arg_list[0])
- n = get_batch_info(arg_list[1], b)
- if n < N:
- continue
- else:
- sum_batch_list.append(batch_list)
- sum_batch_s.append(batch_s)
- break
- print('正在统计最终结果,请稍等片刻。。。。。。。。。。')
-
- OrderNo_list = []
- GroupNo_list = []
- for i in range(0,51):
- for j in sum_batch_list[i]:
- OrderNo_list.append(j)
- GroupNo_list.append(i+1)
-
-
- #保存数据
- result1_dic = {'OrderNo':OrderNo_list,
- 'GroupNo':GroupNo_list}
- result1_df = pd.DataFrame(result1_dic,index=None)
- result1_df.reset_index(drop=True)
- result1_df.to_csv(r'D:\Pycharm\pythonProject\result1.csv')
-
- print('第一问给出结果如下:')
-
- for i in range(51):
- print('第{}批订单数为:'.format(i+1),len(sum_batch_list[i]),'货品种类数为:',len(sum_batch_s[i]))
- print('分批方案为:',sum_batch_list[i])
- print('----------------------------------------------------------------')
- print()
-
- print('总批数:',len(sum_batch_s))
- print()
- print('result1.csv文件已生成')
- print('程序到此结束')

部分运行结果:
第1批订单数为: 22 货品种类数为: 200
分批方案为: ['D0148', 'D0613', 'D0674', 'D0246', 'D0726', 'D0337', 'D0497', 'D0581', 'D0601', 'D0391', 'D0352', 'D0630', 'D0747', 'D0912', 'D0294', 'D0496', 'D0423', 'D0539', 'D0776', 'D0384', 'D0903', 'D0210']
----------------------------------------------------------------
第2批订单数为: 8 货品种类数为: 200
分批方案为: ['D0189', 'D0233', 'D0149', 'D0164', 'D0211', 'D0270', 'D0036', 'D0106']
----------------------------------------------------------------
第3批订单数为: 20 货品种类数为: 200
分批方案为: ['D0174', 'D0089', 'D0218', 'D0580', 'D0466', 'D0426', 'D0281', 'D0443', 'D0403', 'D0513', 'D0375', 'D0784', 'D0868', 'D0906', 'D0488', 'D0764', 'D0861', 'D0490', 'D0234', 'D0646']
----------------------------------------------------------------
第4批订单数为: 20 货品种类数为: 200
分批方案为: ['D0145', 'D0409', 'D0468', 'D0190', 'D0320', 'D0670', 'D0505', 'D0882', 'D0474', 'D0413', 'D0591', 'D0540', 'D0498', 'D0572', 'D0825', 'D0486', 'D0612', 'D0433', 'D0401', 'D0116']
----------------------------------------------------------------
第5批订单数为: 10 货品种类数为: 200
分批方案为: ['D0203', 'D0708', 'D0412', 'D0187', 'D0769', 'D0117', 'D0717', 'D0232', 'D0766', 'D0102']
----------------------------------------------------------------
第6批订单数为: 13 货品种类数为: 200
分批方案为: ['D0028', 'D0046', 'D0707', 'D0815', 'D0259', 'D0898', 'D0870', 'D0173', 'D0705', 'D0219', 'D0178', 'D0381', 'D0354']
----------------------------------------------------------------
第7批订单数为: 6 货品种类数为: 200
分批方案为: ['D0283', 'D0458', 'D0006', 'D0744', 'D0553', 'D0063']
----------------------------------------------------------------
第8批订单数为: 30 货品种类数为: 200
分批方案为: ['D0133', 'D0767', 'D0481', 'D0741', 'D0060', 'D0194', 'D0678', 'D0340', 'D0142', 'D0147', 'D0397', 'D0792', 'D0891', 'D0894', 'D0475', 'D0899', 'D0386', 'D0851', 'D0830', 'D0399', 'D0878', 'D0166', 'D0460', 'D0544', 'D0042', 'D0019', 'D0043', 'D0550', 'D0800', 'D0078']
----------------------------------------------------------------
注意:代码里面的data.csv文件为官网上题目里的附带文件,我改成了data,csv名字;OrderNoSum.csv文件是经过data.csv文件处理的文件,将它与data.csv放在同一目录下。
第1问至第3问相关文件和源码放这了:
链接:https://pan.baidu.com/s/11UBm1LPLgAANu-nixi9KEQ
提取码:4859
答案不一定准确,有错误或者不恰当的地方请指出!一起学习进步!!
原文链接:https://blog.csdn.net/m0_57903984/article/details/124865827
作者:hehrie83489
链接:https://www.pythonheidong.com/blog/article/1645181/08364fc4d63e05b604de/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!