基于Python的ERP系统中主⽣产计划(MPS)的计算
⼀、⽬的
1、深⼊理解、掌握主⽣产计划理论。
2、综合运⽤主⽣产计划理论和程序设计技术,设计适合表⽰主⽣产计划参数及计划结果的数据结构,并使⽤程序设计语⾔实现。
3、综合运⽤主⽣产计划理论和程序设计技术,设计主⽣产计划计算的算法,并使⽤程序设计语⾔实现。
4、设计并实现主⽣产计划结果显⽰形式。
5、对于给定的主⽣产计划参数实例,制定可⾏的主⽣产计划。
⼆、内容
1、设计并实现适合存储主⽣产计划参数及计算结果的数据结构。
2、设计并实现主⽣产计划计算的算法。
3、设计并实现主⽣产计划结果显⽰形式。
4、根据数据⽂件的说明完成数据⽂件的解析,读取计算主⽣产计划的相关参数,根据读⼊的参数完成主⽣产计划的计算,并显⽰(如
表、图等,也可以输出到Excel中)计算结果
三、存储相关参数的⽂件及说明
period.dat:时段数据⽂件。⽂件可能包含若⼲⾏。每⾏对应⼀种物料。每⾏的格式如下:
物料名称 计划展望期时间跨度(包含过去时段,⽤时段0表⽰过去时段,时段1为当前计划的第⼀个时段) 需求时界 计划时界例如
X 11 3 7
表⽰物料X的计划展望期为11个时段(包含过去时段,即实际需要计算的计划展望期为10个时段,可结合课件或教材的MPS表格理解),时段3和时段4的交界为需求时界,时段7和8的交界为计划时界
matinfo.dat:物料信息⽂件。⽂件可能包含若⼲⾏。每⾏对应⼀种物料。每⾏的格式如下:
物料名称 批量⼤⼩ 安全库存 提前期
例如
X 10 5 1
表⽰物料X的批量⼤⼩为10,安全库存量为5,提前期为1个时段
prediction.dat:预测量数据⽂件。⽂件可能包含若⼲⾏。每⾏对应⼀种物料。每⾏的格式如下:
物料名称 过去时段预测量 时段1预测量 ... 时段n预测量
例如
X 0 25 20 35 20 25 20 20 30 30 25
表⽰物料X在过去时段、时段1、...、时段10中,各个时段的预测量。时段的数量可由period.dat⽂件中该物料的第⼀个字段得到。
对于本例来说,period.dat中X物料的第⼀个字段为11,所以⼀共11个时段,分别是:过去时段、时段1、时段2、...、时段10
order.dat:订单量数据⽂件。⽂件可能包含若⼲⾏。每⾏对应⼀种物料。每⾏的格式如下:
物料名称 过去时段订单量 时段1订单量 ... 时段n订单量
例如
X 0 32 26 25 33 20 25 30 25 35 20
表⽰物料X在过去时段、时段1、...、时段10中,各个时段的订单量。时段的数量可由period.dat⽂件中该物料的第⼀个字段得到。
对于本例来说,period.dat中X物料的第⼀个字段为11,所以⼀共11个时段,分别是:过去时段、时段1、时段2、...、时段10
ScheduledReceipts.dat:计划接收量数据⽂件。⽂件可能包含若⼲⾏。每⾏对应⼀种物料。每⾏的格式如下:
物料名称 过去时段计划接收量 时段1计划接收量 ... 时段n计划接收量
例如
X 0 20 0 0 0 0 0 0 0 0 0
表⽰物料X在过去时段、时段1、...、时段10中,各个时段的计划接收量。时段的数量可由period.dat⽂件中该物料的第⼀个字段得到。
对于本例来说,period.dat中X物料的第⼀个字段为11,所以⼀共11个时段,分别是:过去时段、时段1、时段2、...、时段10
PrevInventory.dat:过去时段可⽤库存。⽂件可能包含若⼲⾏。每⾏对应⼀种物料。每⾏的格式如下:
物料名称 过去时段可⽤库存
例如
X 10
表⽰物料X在过去时段的可⽤库存为10
四、相关理论知识
1. ⽑需求量的计算:当在需求时段,⽑需求量 = 订单量,当在计划阶段, ⽑需求量 = max(订单量,预测量),当在预测阶段,⽑需
求 = 预测量。
2. 净需求的计算:如果PAB初值 >= 安全库存,净需求 = 0 ;如果PAB初值 < 安全库存量,净需求 = 安全库存量 – PAB初值。
3. PAB的计算:PAB(预计可⽤库存) = 前⼀时段预计可⽤库存 + 本时段计划接收量 – 本时段⽑需求量。
4. 计划产出量的计算:当N是⼀个⼤于或等于1的整数时、当N * ⽣产批量 >= 净需求量 > (N-1) * ⽣产批量时、计划产出量 = N * ⽣
产批量。
5. 计划投⼊量的计算:将计划产出量的所有数据提前⼀个时段,得到相应的计划投⼊量。
6. 可供销售量(ATP)的计算:ATP = 本时段计划产出量 + 本时段计划接收量 – 下⼀次出现计划产出量之前各时段的订单量之和。
7. 读取数据⽂件的⽅法:
def ReadMatInfo(filepath):
with open(filepath,"r") as f:
contents = f.read()
tmp=contents.split(' ',-1)
return tmp
8. 写⼊到Excel使⽤的模块:import xlsxwriter
关键代码:
workbook = xlsxwriter.Workbook("/xxxx.xlsx")
worksheet = workbook.add_worksheet(name="xxx")
worksheet.write_row("xx",xxxx)
worksheet.write_column("xx",xxxx)
workbook.close()
五、源代码
#批量⼤⼩
#安全库存
#提前期
#数据⽂件(period.dat)
#各时段订单量(order.dat)
#各时段预测量(prediction.dat)
#各时段计划接收量(ScheduleReceipts.adt)
#过去时段的预计可⽤库存(PrevInventory.dat)
#1.计算所有时段⽑需求量
#2.按照从时段1到时段n的顺序计算n个时段⽑需求量
#3.以此计算该阶段净需求、计划产出量及预计可⽤库存
#4.依次计算所有时段计划投⼊量
#5.依次计算所有时段可供销售量
#by Jiefeng_Lin
#by Jiefeng_Lin
import xlsxwriter
#读取⽂件函数
def ReadMatInfo(filepath):
with open(filepath,"r") as f:
contents = f.read()
tmp=contents.split(' ',-1)
return tmp
# 从⽂件现有初始预计可⽤库存量
now_stock = []
now_stock.insert(0,int(ReadMatInfo('./data_files/PrevInventory.dat')[1]))
# 从⽂件读取安全库存量
safe_stock = int(ReadMatInfo('./data_files/matinfo.dat')[2])
# 从⽂件批量⼤⼩
product_batch = int(ReadMatInfo('./data_files/matinfo.dat')[1])
# 从⽂件读取提前期
pre_date = int(ReadMatInfo('./data_files/matinfo.dat')[3])
#从⽂件读取总时段
total_period = int(ReadMatInfo('./data_files/period.dat')[1])
#从⽂件读取需求时界
require_period = int(ReadMatInfo('./data_files/period.dat')[2])
#从⽂件读取计划时界
plan_period = int(ReadMatInfo('./data_files/period.dat')[3])
# 从⽂件读取预测量
pre= []
for i in range(total_period):
pre.insert(i,int(ReadMatInfo('./data_files/prediction.dat')[i+1]))
# 从⽂件读取订单量
order = []
for i in range(total_period):
order.insert(i,int(ReadMatInfo('./data_files/order.dat')[i+1]))
#从⽂件读取计划接收量
schedule_receipt = []
for i in range(total_period):
schedule_receipt.insert(i,int(ReadMatInfo('./data_files/ScheduledReceipts.dat')[i+1]))
#定义净需求量数组
neet_reqiire = []
neet_reqiire.insert(0,0)
#定义⽑需求量数组
gross_require = []
#定义可供销售量数组
ATP = []
ATP.insert(0,0)
#定义计划产出量数组
plan_production = []
plan_production.insert(0,0)
#定义计划投⼊量数组
plan_release = []
plan_release.insert(total_period-1,0)
#计算⽑需求量
for i in range(total_period):
#当在需求时段,⽑需求=订单量
if i <= require_period:
gross_require.insert(i,order[i])
#当在计划阶段,⽑需求=max(订单量,预测量)
if i > require_period and i <= plan_period:
gross_require.insert(i,max(order[i],pre[i]))
#在预测阶段,⽑需求=预测量
if i > plan_period and i < total_period:
gross_require.insert(i,pre[i])
#定义批量⼤⼩增量的函数
def calculate_increse_of_product_batch(n):
#n是⼤于或等于1的整数
if n == 0:
return 0
else:
for i in range(1,11):
#当 i*⽣产批量 >= 净需求量 > (i-1)*⽣产批量的时候,满⾜计划产出量计算要求
if (i-1)*product_batch < n and i*product_batch >= n:
return i * product_batch
#计划产出量 = i * ⽣产批量
#计算净需求量
for i in range(1,total_period):
#净需求 = 本时段⽑需求量 + 安全库存 - 前时段可⽤库存 - 计划接收量
neet_reqiire.insert(i,gross_require[i] + safe_stock - now_stock[i-1] - schedule_receipt[i])
#计划产出直接应⽤上⾯的函数
plan_production.insert(i, calculate_increse_of_product_batch(neet_reqiire[i]))
#预计可⽤库存 = 前时段预计可⽤库存 + 预计接收量 + 计划产出量 - ⽑需求
now_stock.insert(i, now_stock[i - 1] + schedule_receipt[i] + plan_production[i] - gross_require[i])
#计算计划投⼊量
for i in range(total_period-1):
#本时段计划投⼊量 = 下时段计划产出量
plan_release.insert(i,plan_production[i+1])
#计算可供销售量ATP
for i in range(total_period-1):
#ATP = 本时段计划产出量 + 本时段计划接收量 + 上时段预计可⽤库存 - 本时段订单量
if i==1:
ATP.insert(i,plan_production[i]+schedule_receipt[i]+now_stock[i-1]-order[i])
#ATP = 本时段计划产出量 + 本时段计划接收量 - 本时段订单量
else:
ATP.insert(i,plan_production[i]+schedule_receipt[i]-order[i])
#将数据写⼊到Excel并创建表格
#创建excel⽂档
print("正在进⾏excel录⼊中")
workbook = xlsxwriter.Workbook("/Users/jayphone/Desktop/calculation_of_MPS.xlsx")
#创建⼀个sheet
worksheet = workbook.add_worksheet(name="calculation_of_MPS")
#确定横轴纵轴属性
calculation_item = ['预测量','订单量','⽑需求量','计划接收量','预计可⽤库存','净需求量','计划产出量','计划投⼊量','可供销售量'] headline=['时区/计算类别','过去时段','1','2','3','4','5','6','7','8','9','10']
#写⼊到表格中
worksheet.write_row("A1",headline)
python怎么读取dat文件worksheet.write_column("A2",calculation_item)
worksheet.write_row("B2",pre)
worksheet.write_row("B3",order)
worksheet.write_row("B4",gross_require)
worksheet.write_row("B5",schedule_receipt)
worksheet.write_row("B6",now_stock)
worksheet.write_row("B7",neet_reqiire)