如何在纸浆约束的for循环中放置任意数量的连续变量?

how to put any number of consecutive variables in a for loop for pulp constraint?

我需要帮助来解决这个编码问题。我有一个非常简单的纸浆调度问题。它有一个解决方案,但该解决方案缺少 2 个我什至不知道如何开始的约束。这个post,我就是喜欢攻略一个。如果有人可以指出方向或其他示例,至少我可以阅读更多相关信息。我确实研究了 itertool,但我认为这不会有帮助,因为它需要 if--elif 条件,我知道这对于 Lineear 优化是不可能的。这是代码:

import pulp

Days= ["Monday"]
Employees =["Paul", "Beth", "Tom"]
Hours = ["9am - 10am", "10am - 11am", "11am - 12pm", "12pm - 1pm", "1pm - 2pm", "2pm - 3pm", "3pm - 4pm", "4pm - 5pm", "5pm - 6pm",  "6pm - 7pm", "7pm - 8pm", "8pm - 9pm" ]

prob=pulp.LpProblem("Hours maximizing problem", pulp.LpMaximize)

avail = pulp.LpVariable.dicts("var", ((employee, day, hour) for employee in Employees for day in Days for hour in Hours), cat="Binary")

# each employee has their desire working # of hours. #
prob += pulp.lpSum(avail['Paul', day, hour] for day in Days for hour in Hours)== 2
prob += pulp.lpSum(avail['Beth', day, hour] for day in Days for hour in Hours)<= 5
prob += pulp.lpSum(avail['Tom', day, hour] for day in Days for hour in Hours)<= 5

#each hour only needs one person
for hour in Hours:
    for day in Days:
        for employee in Employees:
            prob += pulp.lpSum(avail[employee, day, hour] for employee in Employees)==1


prob += 0, "Objective Function"
prob.writeLP("add to 2.lp")
prob.solve()
print (prob)

缺少的约束是所有工作时间必须连续。例如:汤姆,星期一下午 4 点到晚上 9 点工作,或 5 小时的任意组合,但它需要在一起,而不是早上 1 小时(例如),下午 4 小时。

如有任何帮助,我们将不胜感激。

您可以引入二进制变量来跟踪某个特定小时内是否有班次started/ended,并引入一个限制条件,即每天只能有一个班次开始:

import pulp

Days= ["Monday"]
Employees =["Paul", "Beth", "Tom"]
Hours = [9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

prob=pulp.LpProblem("Hours maximizing problem", pulp.LpMaximize)

avail = pulp.LpVariable.dicts("var", ((employee, day, hour) for employee in Employees for day in Days for hour in Hours), cat="Binary")

startShift = pulp.LpVariable.dicts("start", ((employee, day, hour) for employee in Employees for day in Days for hour in Hours), cat="Binary")
endShift = pulp.LpVariable.dicts("end", ((employee, day, hour) for employee in Employees for day in Days for hour in Hours), cat="Binary")

# each employee has their desire working # of hours. #
prob += pulp.lpSum(avail['Paul', day, hour] for day in Days for hour in Hours)== 2
prob += pulp.lpSum(avail['Beth', day, hour] for day in Days for hour in Hours)<= 5
prob += pulp.lpSum(avail['Tom', day, hour] for day in Days for hour in Hours)<= 5

#each hour only needs one person
for hour in Hours:
    for day in Days:
        prob += pulp.lpSum(avail[employee, day, hour] for employee in Employees)==1

        for employee in Employees:
            if hour == Hours[0]:
                # to be working in the first hour of the day, avail==1
                # they must have started their shift, startShift==1
                prob += avail[employee, day, hour] == startShift[employee, day, hour]
            else:
                # to be working in any other hour of the day, they either
                # have to already be part through their shift; avail[e, d, h-1]
                # or they have to have started their shift in this hour; startShift[e, d, h]
                # also, if they just ended their shift, they are no longer working; endShift[e, d, h-1]
                prob += avail[employee, day, hour] == avail[employee, day, hour-1] + startShift[employee, day, hour] - endShift[employee, day, hour-1]

# each employee must have onlhy a single shift
for employee in Employees:
    for day in Days:
        prob += pulp.lpSum([startShift[employee, day, hour] for hour in Hours]) == 1
        prob += pulp.lpSum([endShift[employee, day, hour] for hour in Hours]) == 1


prob += 0, "Objective Function"
prob.writeLP("add to 2.lp")
prob.solve()
print (prob)

for v in prob.variables():
    print (v.name, "=", v.varValue)

print('Status:',pulp.LpStatus[prob.status])