使用 Pulp 优化商店计划
store schedule optimization with Pulp
我正在尝试使用 PuLP 模块优化商店计划,但我遇到了第 4 个约束的问题
下面将详细说明约束条件
- Store_demand一天的总和不能超过容量(<=容量)
- 每个商店将根据他们的天数分配给工作日(Store_Days)
例如:“S4”应该只安排在三天后
- 应该在 3 天内删除的商店有一个单独的约束“每隔一天”条件来获得一天的差距
EX:“S4”商店
如果第一天安排在 SAT,其他日子将是 MON 和
周三
如果第一天安排在星期日,其他日子将是星期二和星期四
- 应该在2天内掉落的商店在下一次掉落之前应该有两天的差距
EX:“S8”商店
- 如果第一天安排在 SAT,那么另一天将是 TUE
- 如果它的第一天安排在星期日,那么另一天将是星期三
- 如果第一天安排在星期一,那么另一天将是星期四
我得到了一个最优解,虽然这不是我需要的结果,因为输出显示连续两天,所以我想我有一个定位问题
例如:
enter image description here
- 1表示当天掉线
- 0表示不会掉线
我想要显示的结果如下table
商店 ROUTE Carton SAT SUN MON TUE WED THU DROPS
enter image description here
import pulp
import pandas as pd
import numpy as np
from pulp import *
StoreSched = pd.DataFrame(columns = ["Store_Code","Route","Demand"])
Capacity = 5000
route="R1"
days_list=["SAT","SUN","MON", "TUE","WED","THU"]
no_days_list = range(1,7)
Store = ["S1","S2","S3","S4","S5","S6","S7","S8","S9","S10"]
Store_demand = {
"S1":400,
"S2":300,
"S3":250 ,
"S4":200 ,
"S5":300,
"S6":200 ,
"S7":300,
"S8":200 ,
"S9":300,
"S10":300,
}
store_Days = {
"S1":6 ,
"S2":6,
"S3":6 ,
"S4":3,
"S5":3,
"S6":3,
"S7":2,
"S8":2,
"S9":2,
"S10":1 ,
}
prob = LpProblem("store_schedule",LpMaximize)
storeVars = LpVariable.dicts("Days",(no_days_list,Store),0,1,LpInteger)
for d in no_days_list:
# The capacity should not exceeed 1500 in one day
prob += pulp.lpSum([Store_demand[s] * storeVars[d][s] for s in Store]) <= Capacity
for s in Store:
# Every store should be assigned based on its DayNo.
prob += pulp.lpSum(storeVars[d][s] for d in no_days_list) == store_Days[s]
for s in Store:
# one day gap between the assigned dayes for the stores that have three days
if store_Days[s] == 3 :
for d in no_days_list[:-1]:
prob += storeVars[d][s] + storeVars[d+1][s] == 1
for s in Store:
if store_Days[s] == 2 :
for d in no_days_list[:-2]:
prob += storeVars[d][s] + storeVars[d+2][s] == 1
prob.solve()
for vi in prob.variables():
if vi.varValue == 1:
#print(" On "+days_list[int(vi.name.split("_")[1])-1]+" Pharmacy code: "+vi.name.split("_")[2])
code= vi.name.split("_")[2];
#print(code)
day = days_list[int(vi.name.split("_")[1])-1];
#print(day)
if ((StoreSched['Store_Code'] == code).any() == False):
StoreSched = StoreSched.append({'Store_Code': code,"Route":route,"Days":store_Days[code],"Demand":Store_demand[code]}, ignore_index=True)
for index in StoreSched.index:
if StoreSched.loc[index,'Store_Code']== code:
StoreSched.loc[index,day] = 1
StoreSched.fillna(0,inplace=True)
StoreSched
如果您希望天数间隔为 2,请将限制更改为 prob += storeVars[d][s] + storeVars[d+1][s] + storeVars[d+2][s] == 1
。
我正在尝试使用 PuLP 模块优化商店计划,但我遇到了第 4 个约束的问题 下面将详细说明约束条件
- Store_demand一天的总和不能超过容量(<=容量)
- 每个商店将根据他们的天数分配给工作日(Store_Days)
例如:“S4”应该只安排在三天后
- 应该在 3 天内删除的商店有一个单独的约束“每隔一天”条件来获得一天的差距
EX:“S4”商店
如果第一天安排在 SAT,其他日子将是 MON 和 周三
如果第一天安排在星期日,其他日子将是星期二和星期四
- 应该在2天内掉落的商店在下一次掉落之前应该有两天的差距
EX:“S8”商店
- 如果第一天安排在 SAT,那么另一天将是 TUE
- 如果它的第一天安排在星期日,那么另一天将是星期三
- 如果第一天安排在星期一,那么另一天将是星期四
我得到了一个最优解,虽然这不是我需要的结果,因为输出显示连续两天,所以我想我有一个定位问题
例如: enter image description here
- 1表示当天掉线
- 0表示不会掉线
我想要显示的结果如下table 商店 ROUTE Carton SAT SUN MON TUE WED THU DROPS
enter image description here
import pulp
import pandas as pd
import numpy as np
from pulp import *
StoreSched = pd.DataFrame(columns = ["Store_Code","Route","Demand"])
Capacity = 5000
route="R1"
days_list=["SAT","SUN","MON", "TUE","WED","THU"]
no_days_list = range(1,7)
Store = ["S1","S2","S3","S4","S5","S6","S7","S8","S9","S10"]
Store_demand = {
"S1":400,
"S2":300,
"S3":250 ,
"S4":200 ,
"S5":300,
"S6":200 ,
"S7":300,
"S8":200 ,
"S9":300,
"S10":300,
}
store_Days = {
"S1":6 ,
"S2":6,
"S3":6 ,
"S4":3,
"S5":3,
"S6":3,
"S7":2,
"S8":2,
"S9":2,
"S10":1 ,
}
prob = LpProblem("store_schedule",LpMaximize)
storeVars = LpVariable.dicts("Days",(no_days_list,Store),0,1,LpInteger)
for d in no_days_list:
# The capacity should not exceeed 1500 in one day
prob += pulp.lpSum([Store_demand[s] * storeVars[d][s] for s in Store]) <= Capacity
for s in Store:
# Every store should be assigned based on its DayNo.
prob += pulp.lpSum(storeVars[d][s] for d in no_days_list) == store_Days[s]
for s in Store:
# one day gap between the assigned dayes for the stores that have three days
if store_Days[s] == 3 :
for d in no_days_list[:-1]:
prob += storeVars[d][s] + storeVars[d+1][s] == 1
for s in Store:
if store_Days[s] == 2 :
for d in no_days_list[:-2]:
prob += storeVars[d][s] + storeVars[d+2][s] == 1
prob.solve()
for vi in prob.variables():
if vi.varValue == 1:
#print(" On "+days_list[int(vi.name.split("_")[1])-1]+" Pharmacy code: "+vi.name.split("_")[2])
code= vi.name.split("_")[2];
#print(code)
day = days_list[int(vi.name.split("_")[1])-1];
#print(day)
if ((StoreSched['Store_Code'] == code).any() == False):
StoreSched = StoreSched.append({'Store_Code': code,"Route":route,"Days":store_Days[code],"Demand":Store_demand[code]}, ignore_index=True)
for index in StoreSched.index:
if StoreSched.loc[index,'Store_Code']== code:
StoreSched.loc[index,day] = 1
StoreSched.fillna(0,inplace=True)
StoreSched
如果您希望天数间隔为 2,请将限制更改为 prob += storeVars[d][s] + storeVars[d+1][s] + storeVars[d+2][s] == 1
。