Python线性规划求解单品补货量和定价策略
import pandas as pd
import numpy as np
from scipy.optimize import linprog
# 读取数据
df1 = pd.read_excel('附件1.xlsx')
df2 = pd.read_excel('附件2.xlsx')
df3 = pd.read_excel('附件3.xlsx')
df4 = pd.read_excel('附件4.xlsx')
print(df1.columns)
print(df2.columns)
print(df3.columns)
print(df4.columns)
# 获取可售单品种类数
n = df2['单品编码'].nunique()
# 构建目标函数系数
profit_coefficient = []
for i in range(n):
code = df2['单品编码'].unique()[i]
# 检查df4中是否存在与df2中的单品编码相匹配的小分类编码
if code in df4['小分类编码'].unique():
loss_rate = df4[df4['小分类编码'] == code]['平均损耗率(%)_小分类编码_不同值'].values[0] / 100
else:
loss_rate = 0
wholesale_price = df3[df3['单品编码'] == code]['批发价格(元/千克)'].values[0]
profit_coefficient.append((1 - loss_rate) * wholesale_price)
# 构建约束条件
A_eq = np.ones((1, n))
b_eq = np.array([27])
A_ub = np.ones((2, n))
b_ub = np.array([33, 2.5 * n])
for i in range(n):
code = df2['单品编码'].unique()[i]
sales_volume = df2[df2['单品编码'] == code]['销量(千克)'].sum()
# 检查df4中是否存在与df2中的单品编码相匹配的小分类编码
if code in df4['小分类编码'].unique():
loss_rate = df4[df4['小分类编码'] == code]['平均损耗率(%)_小分类编码_不同值'].values[0] / 100
else:
loss_rate = 0
A_ub = np.vstack((A_ub, [1 - loss_rate] * n))
b_ub = np.append(b_ub, sales_volume)
# 求解线性规划模型
res = linprog(-np.array(profit_coefficient), A_ub=A_ub, b_ub=b_ub, A_eq=A_eq, b_eq=b_eq)
# 提取最优解
x = res.x
# 输出单品补货量和定价策略
for i in range(n):
code = df2['单品编码'].unique()[i]
replenishment_quantity = x[i]
wholesale_price = df3[df3['单品编码'] == code]['批发价格(元/千克)'].values[0]
print(f'单品编码: {code}, 补货量: {replenishment_quantity}, 定价策略: {wholesale_price * (1 + res.fun / replenishment_quantity)}')
代码解释:
- 导入库: 导入pandas库用于数据处理,numpy库用于数值计算,scipy.optimize.linprog用于求解线性规划问题。
- 读取数据: 使用pandas的read_excel函数读取四个Excel文件中的数据。
- 获取可售单品种类数: 使用nunique()函数获取df2中'单品编码'列的不重复值的数量,即可售单品种类数。
- 构建目标函数系数: 遍历每个单品,根据损耗率和批发价格计算利润系数。
- 构建约束条件: 根据总重量、单品最大重量和销量等限制条件,构建线性规划模型的约束条件矩阵和向量。
- 求解线性规划模型: 使用scipy.optimize.linprog函数求解线性规划模型,得到最优解。
- 提取最优解: 从求解结果中提取最优解,即每个单品的补货量。
- 输出单品补货量和定价策略: 遍历每个单品,输出其补货量和定价策略。
IndexError错误处理:
代码中添加了判断语句 if code in df4['小分类编码'].unique():,用于检查df4中是否存在与df2中当前单品编码相匹配的小分类编码。如果不存在,则将损耗率设为0,避免了IndexError错误的发生。
原文地址: https://www.cveoy.top/t/topic/egc8 著作权归作者所有。请勿转载和采集!