使用 Pulp 优化商店计划

问题描述

我正在尝试使用 PuLP 模块优化商店时间表,但我遇到了第 4 个约束的问题 下面将详细说明约束条件

  1. Store_demand 的总和不应超过一天的容量(
  2. 每个商店将根据其天数(Store_Days)分配工作日

例如:“S4”只能在三天内安排

  1. 应该在 3 天内删除的商店有一个单独的约束“每隔一天”条件以获得一天的间隔

EX:“S4”商店

  • 如果第一天是在 SAT 上安排的,那么其他日子将是 MON 和 周三

  • 如果第一天被安排在星期日,那么其他日子将是周二和周四

  1. 应该在 2 天内下降的商店在下一次下降之前应该有两天的间隔

例如:“S8”商店

  • 如果第一天安排在 SAT,那么前一天将是 TUE
  • 如果它的第一天安排在星期日,那么前一天将是星期三
  • 如果第一天安排在星期一,那么前一天就是星期四

我得到了一个最佳解决方案,虽然这不是我需要的结果,因为输出显示连续两天,所以我想我有一个定位问题

例如: enter image description here

我想显示的结果如下表 Store 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),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