我有一个持续时间为5的任务,可以在时间点0到10之间开始 此外,我在地平线[0,10]中间隔[2,4]和[6,7]中断。
每当任务在特定时间点开始时,它应检查中断时间并延长持续时间以使其完成实际持续时间。例如,如果任务从时间点1开始,理想情况下应该在时间点6完成。但是由于2,3和6的中断,它应该延长到9以完成任务。这意味着,持续时间= 5 + 3 = 8。
以下是考虑休息时间在每个时间点的任务持续时间 [8,8,-1,-1,6,6,-1,5,5,5] 我使用-1来禁止它作为休息时间点的起点。 以上示例是为了您理解我尝试建立和编写的逻辑。
我可以通过定义如下函数来解决这个问题。对于上述小数据,它运作良好。但是,如果我的视野更长,说86400(两分钟,分钟),我的休息时间更长(比如每天4小时休息2次),那么我的循环时间会更长。
Invalid_Timings2 = [
(0, 8640, 10080),
(0, 18720, 20160),
(0, 28800, 30240),
...
(44, 59040, 60480),
(44, 69120, 70560),
(44, 79200, 80640)
]
def Duration_Pre_Compute_Task_Split(Invalid_Timings2):
Duration1 = []
original_task_duration = 1380 # My task duration is 1380 minutes
for h in xrange(0, 86400): # task can start anywhere between 0 to 86400 minutes
dur = original_task_duration
k=0
for t in Invalid_Timings2: # break timings given at the end [(0,480,600), (0,960, 1200) etc..]
# current time point h should be outside break range
# also new duration calculated should not fall into next break range similar to the case explained with small data.
# If it falls, this break time should be added to the calculated duration
if t[1] - dur <= h <= t[1]+ dur and h not in range(t[1], t[2]) and h < t[2]:
k = 1
dur += t[2] - t[1]
if k != 0: #if k=1 means h is not in break range, task cannot start during break range
Duration1.append((h,dur)) # for each time point, final calculated duration is appended.
return Duration1
我的问题是关于表现。如果我的视野更长并且休息次数按地平线增加,则此计算时间呈指数增长。
如何改进此功能以缩短计算时间?
答案 0 :(得分:0)
微优化将解包t
到变量以避免重复查找。 e.g:
for t in Invalid_Timings2:
t0, t1, t2 = t
if t1 - dur <= h <= t1 + dur and h not in range(t1, t1 + t2) and t0==10 and h < t1 + t2:
k = 1
dur += t2
这将使用单个解包
替换9次查找答案 1 :(得分:0)
您的性能问题来自非常大的嵌套循环(h
,然后是t
),核心处有半复杂逻辑(if
语句,包含元素查找,计算,范围创建等等。)。
这是一种摆脱循环和if
语句的方法:
def Duration_Pre_Compute_Task_Split(Invalid_Timings2):
original_task_duration = 5
# start with list assuming no delays
Duration1 = [original_task_duration] * 10
# work backward, updating all durations based on each invalid timing
for t in reversed(Invalid_Timings2):
# unpack once (thanks Brian)
t0, stt, end = t
delay = end - stt
# any duration between stt/end -> invalid
Duration1[stt:end] = [-1] * delay
# any duration before stt -> delayed
# (everything from 0 to stt is the same, so just use the first element)
Duration1[:stt] = [Duration1[0] + delay] * stt
return Duration1
这适用于您的高级示例(0-10)。您显然需要针对您的实际应用进行测试/调整。如果您对其工作原理有任何疑问,请与我们联系。祝你好运!