繁体   English   中英

如何在纸浆优化中限制变量?

[英]How to cap a variable in Pulp optimization?

我正在尝试使用预测的成本和销售额来优化产品的整体销售额(为期 3 个月)。 我当前的数据如下所示

>     Month |    sales quantity  | discount % | Total inventory
      1     |         12         |    5       |      45
      1     |         23         |    9       |      45
      1     |         40         |    15      |      45
      2     |         23         |    5       |      45

根据预测的销售额,每个月都有一些折扣。 Total inventory是所有月份的库存总和。 我正在尝试使用纸浆最大化整体销售额,但优化结果总是选择每个月的最高sales quantity ,大部分时间超过Total inventory

当总销售额超过Total inventory时,我需要限制sales quantity值(为零)。

保持像lpSum(x[i]*sales_quantity[i] for i in unique_months) < total_inventory的约束会导致不可行的解决方案。 我的一小段代码:

import pulp as lp 

# `data` is a DataFrame contains above data
x = LpVariable.dicts("x", range(0, len(data)), 0, 1, LpBinary) 

prob = lp.LpProblem("test problem", lp.LpMaximize)

# obj function
prob += lpSum(x[i] * data.loc[i, 'sales quantity'] for i in range(0, len(data)))

# constraints
prob += lpSum(x[i] * data.loc[i, 'sales quantity'] for i in range(0, len(data))) >= threshold_inventory_to_clear

# constraints to select each month(without missing any)
for j in list(data['Month'].unique()):
    if j == data['Month'].max():
       break
    sub_idx_current = data[data['Month'] == j].index
    sub_idx_next = data[data['Month'] == j + 1].index
    prob += lpSum(x[idx_current] * data.loc[idx_current, 'Month'] for idx_current in sub_idx_current) \
                        <= lpSum(x[idx_next] * data.loc[idx_next, 'Month'] for idx_next in sub_idx_next)

# Need to replace this constraints with some calling logic
prob += lpSum(x[i]*data.loc[i, 'sales quantity'] for i in range(0, len(data)) < total_inventory

如果我正确理解您的问题,您可以选择每月出售或不出售? 并且您希望最大化您的收入,这样您的销售量不会超过您的库存。 我不确定您是否正在处理多种产品。

如果我正确理解了您的问题,那么以下内容应该可以在 4 个不同的时间段内为单个产品解决问题。

import pulp
import pandas as pd

max_quantity = 45
df = pd.DataFrame({
    "sales_quantity": [12,23,40,23],
    "discount": [5,9,15,5]
})

prob = pulp.LpProblem("MaxSales", pulp.LpMaximize)

X = [pulp.LpVariable('var_'+str(i), 0, 1, pulp.LpBinary) for i, sq in enumerate(df['sales_quantity'])]
prob += pulp.LpAffineExpression({X[i]: (100-df['discount'][i])*df['sales_quantity'][i] 
                                 for i in range(0,len(df))}, name='Objective')
prob += pulp.LpAffineExpression({X[i]: df['sales_quantity'][i] for i in range(0,len(df))})<=max_quantity, "Max Inventory"
prob.solve()
print(prob)
print("Revenue: " + str(pulp.value(prob.objective)))
print([pulp.value(x) for x in X])

Output:

MaxSales:
MAXIMIZE
1140*var_0 + 2093*var_1 + 3400*var_2 + 2185*var_3 + 0
SUBJECT TO
Max_Inventory: 12 var_0 + 23 var_1 + 40 var_2 + 23 var_3 <= 45

VARIABLES
0 <= var_0 <= 1 Integer
0 <= var_1 <= 1 Integer
0 <= var_2 <= 1 Integer
0 <= var_3 <= 1 Integer

Revenue: 3400.0
[0.0, 0.0, 1.0, 0.0]

如果我误解了什么,请告诉我。 我无权发表评论,因此无法事先要求澄清。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM