我有一个以下问题:我想使用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
求解器。任何帮助将不胜感激。
答案 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')
编辑:此解决方案效果很好,但随着用户和会议数量的增加,它开始确实变慢了。