问题重述:
题
分拣系统优化问题
5
个订单,订单的信息如表
1
(原始数据文件格式见附件
1
格式说明)
1
:订单信息示例
×
2, P0002
×
1, P0003
×
1, P0004
×
1
×
1, P0004
×
1, P0005
×
1, P0006
×
3
×
1, P0003
×
1, P0005
×
1, P0007
×
1
×
1, P0004
×
1, P0006
×
1, P0008
×
3
×
1, P0003
×
2, P0004
×
1, P0007
×
1
5
个订单共包含
8
种
26
件货品,分别为
4
件
P0001
、
2
件
P0002
、
5
件
、
4
件
P0004
、
2
件
P0005
、
4
件
P0006
、
2
件
P0007
和
3
件
P0008
。转运工将这些货
8
个货架上。分拣工根据任务单上的订单信息,依次分拣出每一个订单的货
设计分批算法
:将当日订单分为多个批次。要求每个批次的订单所含货品种类数均不
1
中的订单
中,格式要求见附件
2
。
问题一解题思路(其他思路在链接里)
第一步:根据附件的订单信息,提取每个订单的货品种类数存入列表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
- 定义getMax_per_batch_info(n)方法,有1个形参,用来传入每批货品种类的值n。该方法的功能为经计算后返回列表batch_s货品种类数和batch_s货品列表,共返回两个值。
- 定义get_num_com(i_l_m)方法,有1个形参,分别以getMax_per_bath_info()方法返回的batch_s值作为实参传入。该方法功能为计算其他订单与batch_s列表中货品种类相同的件数,并将其结果存入num_com列表中。
- 定义get_bath_info(n,num_com)方法,有2个形参,将getMax_per_batch_info(n)方法的返回值n作为实参传入。该方法有2个while循环,判断n是否小于200,若小于,则将最大相同件数订单的货品种类不存在于batch_s列表中货品种类依次存入batch_s列表中,判断batch_s列表长度是否大于200,若大于,跳出循环;若小于,则继续调用getMax_per_batch_info(n)方法和get_num_com(i_l_m)方法;直至列表batch_s中货品种类数等于200,循环结束。输出批次信息并保存至batch_list列表中,并将已经处理的订单从列表orderno_list列表中移除。
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/1NZcem6rJjoU-lPMU_QSfqw
提取码:8833
答案不一定准确,有错误或者不恰当的地方请指出!一起学习进步!!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/34592.html