时间表:在任务之间刹车,同时允许更长的任务

时间:2018-10-25 09:24:03

标签: python schedule

我有一个以下问题:我想使用pyschedule库安排一些会议(任务),并在累积的时间过长(超过4个时隙)时允许它们之间进行制动。同时,我想允许任务占用的时间超过最多4个时隙。假设我有1个人参加3次会议:

person = scenario.Resource('person')
meeting1 = scenario.Task('meeting1', 1)
meeting2 = scenario.Task('meeting2', 2)
meeting3 = scenario.Task('meeting3', 5)

然后,所需的解决方案例如是[meeting1, meeting2, break, meeting3]。 我试图做出限制:

MAX_CONSECUTIVE_SLOTS = 4
for slot in range(HORIZON):
    scenario += person[slot:slot + MAX_CONSECUTIVE_SLOTS + 1] <= MAX_CONSECUTIVE_SLOTS

,但这仅在所有会议都不超过MAX_CONSECUTIVE_SLOTS时起作用。我还尝试将这种情况与每个时间片的任务数量结合起来:

meeting1.count = 1
meeting2.count = 1
meeting3.count = 1

for slot in range(HORIZON):
    scenario += (person[slot:slot + MAX_CONSECUTIVE_SLOTS + 1] <= MAX_CONSECUTIVE_SLOTS) or \
        (person['count'][slot:slot + MAX_CONSECUTIVE_SLOTS + 1] <= 1)

但是person['count'][n:m]显然意味着当我需要与该时间片重叠的任务数时,在给定时间片中完成的任务数。

我正在使用mip.solve求解器。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

这是基于timnon's answer on Github的解决方案。它基于stress参数,该参数必须限制为任何人。在较短的会议中,每次会议都会增加与会议长度相等的压力,在较长的会议中会增加等于压力极限的压力。每次休息都会减轻人的压力。

from pyschedule import Scenario, solvers


horizon = 20
stress_limit = 4

S = Scenario('test', horizon=horizon)

meeting1 = S.Task('meeting1', 1, stress=1)
meeting2 = S.Task('meeting2', 2, stress=2)
meeting3 = S.Task('meeting3', 5, stress=stress_limit)
breaks = S.Tasks('break', schedule_cost=0, num=3, stress=-stress_limit)

person = S.Resource('person')
meeting1 += person
meeting2 += person
meeting3 += person
breaks += person

for t in range(horizon + 1):
    S += person['stress'][:t] <= stress_limit
    S += person['stress'][:t] >= 0

S.clear_solution()
S.use_flowtime_objective()

if solvers.mip.solve(S, msg=0, kind='CBC'):
    print(S.solution())
else:
    print('no solution found')

编辑:此解决方案效果很好,但随着用户和会议数量的增加,它开始确实变慢了。