2017-04-18 69 views
-2

高級目標

我有5的持續時間可以時間點0和10 此外之間啓動一個任務,我在間隔[2斷裂,4),和[6,7]在地平線[0,10)。如何使蟒循環邏輯更快

每當任務在特定時間點開始時,它應該檢查休息時間並延長持續時間,以便完成其實際持續時間。例如,如果任務在時間點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

這個問題太籠統了,更像是一個需要完成的作業問題。您可以通過添加您嘗試的方法來改進它。此外,您應該關注您所面對的問題的具體部分。 – Gijs

+0

嗨,它不是一個家庭作業問題。這是調度應用程序的一小部分。我盡我所能改善它。此前,它過去需要一個小時,我通過減少不必要的步驟將其減少到15分鐘。我只是想知道專家意見是否可以改進。讓我知道我可以添加什麼,以便您可以自己看到問題 – ASK

+0

嘗試使這更具體。例如,您顯示的函數具有持續時間1380,但您的文本只顯示5.該函數循環到86400,但這不在任何地方解釋。也可以嘗試添加一些評論功能,以幫助我們理解你在嘗試什麼。根據您的建議更新 – Dan

回答

0

微型優化是將t解壓縮到變量以避免重複查找。例如:

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個查找與單個拆包

+0

好的。謝謝Brian。我更新了它。 – ASK

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)。你需要測試/調整你的真實應用程序顯然。如果您對其工作原理有任何疑問,請告知我們。祝你好運!

+0

你的聲明說「任何持續時間 - >延遲」是不正確的。只有持續時間落入無效時間範圍內,纔會延遲。假設它是一臺機器,我們只能在有效的時間內在機器上進行處理。機器將在休息時間下降。所以這項工作需要額外的時間來處理機器不可用的情況。如果機器在給定的時間內可用,則不會有任何延遲。您可以通過將代碼中的original_task_duration更改爲2來檢查此問題。由於第一次突破從2開始,所以當我們從0開始時,任務不會被延遲。 – ASK