Python基于回溯法子集樹(shù)模板解決最佳作業(yè)調(diào)度問(wèn)題示例
本文實(shí)例講述了Python基于回溯法子集樹(shù)模板解決最佳作業(yè)調(diào)度問(wèn)題。分享給大家供大家參考,具體如下:
問(wèn)題
給定 n 個(gè)作業(yè),每一個(gè)作業(yè)都有兩項(xiàng)子任務(wù)需要分別在兩臺(tái)機(jī)器上完成。每一個(gè)作業(yè)必須先由機(jī)器1 處理,然后由機(jī)器2處理。
試設(shè)計(jì)一個(gè)算法找出完成這n個(gè)任務(wù)的最佳調(diào)度,使其機(jī)器2完成各作業(yè)時(shí)間之和達(dá)到最小。
分析:
看一個(gè)具體的例子:
tji 機(jī)器1 機(jī)器2
作業(yè)1 2 1
作業(yè)2 3 1
作業(yè)3 2 3
最優(yōu)調(diào)度順序:1 3 2
處理時(shí)間:18
這3個(gè)作業(yè)的6種可能的調(diào)度方案是1,2,3;1,3,2;2,1,3;2,3,1;3,1,2;3,2,1;
它們所相應(yīng)的完成時(shí)間和分別是19,18,20,21,19,19。易見(jiàn),最佳調(diào)度方案是1,3,2,其完成時(shí)間和為18。
以1,2,3為例:
作業(yè)1在機(jī)器1上完成的時(shí)間為2,在機(jī)器2上完成的時(shí)間為3
作業(yè)2在機(jī)器1上完成的時(shí)間為5,在機(jī)器2上完成的時(shí)間為6
作業(yè)3在機(jī)器1上完成的時(shí)間為7,在機(jī)器2上完成的時(shí)間為10
3+6+10 = 19
1,3,2
作業(yè)1在機(jī)器1上完成的時(shí)間為2, 在機(jī)器2上完成的時(shí)間為3
作業(yè)3在機(jī)器1上完成的時(shí)間為4,在機(jī)器2上完成的時(shí)間為7
作業(yè)2在機(jī)器1上完成的時(shí)間為7,在機(jī)器2上完成的時(shí)間為8
3+7+8 = 18
解編碼:(X1,X2,...,Xn),Xi表示順序i執(zhí)行的任務(wù)編號(hào)。所以,一個(gè)解就是任務(wù)編號(hào)的一個(gè)排列。
解空間:{(X1,X2,...,Xn)| Xi屬于S,i=1,2,...,n},S={1,2,...,n}。所以,解空間就是任務(wù)編號(hào)的全排列。
講道理,要套用回溯法的全排列模板。
不過(guò),有了前面兩個(gè)例子做鋪墊,這里套用回溯法的子集樹(shù)模板。
代碼
''' 最佳作業(yè)調(diào)度問(wèn)題 tji 機(jī)器1 機(jī)器2 作業(yè)1 2 1 作業(yè)2 3 1 作業(yè)3 2 3 ''' n = 3 # 作業(yè)數(shù) # n個(gè)作業(yè)分別在兩臺(tái)機(jī)器需要的時(shí)間 t = [[2,1], [3,1], [2,3]] x = [0]*n # 一個(gè)解(n元數(shù)組,xi∈J) X = [] # 一組解 best_x = [] # 最佳解(一個(gè)調(diào)度) best_t = 0 # 機(jī)器2最小時(shí)間和 # 沖突檢測(cè) def conflict(k): global n, x, X, t, best_t # 部分解內(nèi)的作業(yè)編號(hào)x[k]不能超過(guò)1 if x[:k+1].count(x[k]) > 1: return True # 部分解的機(jī)器2執(zhí)行各作業(yè)完成時(shí)間之和未有超過(guò) best_t #total_t = sum([sum([y[0] for y in t][:i+1]) + t[i][1] for i in range(k+1)]) j2_t = [] s = 0 for i in range(k+1): s += t[x[i]][0] j2_t.append(s + t[x[i]][1]) total_t = sum(j2_t) if total_t > best_t > 0: return True return False # 無(wú)沖突 # 最佳作業(yè)調(diào)度問(wèn)題 def dispatch(k): # 到達(dá)第k個(gè)元素 global n, x, X, t, best_t, best_x if k == n: # 超出最尾的元素 #print(x) #X.append(x[:]) # 保存(一個(gè)解) # 根據(jù)解x計(jì)算機(jī)器2執(zhí)行各作業(yè)完成時(shí)間之和 j2_t = [] s = 0 for i in range(n): s += t[x[i]][0] j2_t.append(s + t[x[i]][1]) total_t = sum(j2_t) if best_t == 0 or total_t < best_t: best_t = total_t best_x = x[:] else: for i in range(n): # 遍歷第k個(gè)元素的狀態(tài)空間,機(jī)器編號(hào)0~n-1,其它的事情交給剪枝函數(shù) x[k] = i if not conflict(k): # 剪枝 dispatch(k+1) # 測(cè)試 dispatch(0) print(best_x) # [0, 2, 1] print(best_t) # 18
效果圖
更多關(guān)于Python相關(guān)內(nèi)容可查看本站專題:《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python Socket編程技巧總結(jié)》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》、《Python入門與進(jìn)階經(jīng)典教程》及《Python文件與目錄操作技巧匯總》
希望本文所述對(duì)大家Python程序設(shè)計(jì)有所幫助。
相關(guān)文章
opencv python 基于KNN的手寫(xiě)體識(shí)別的實(shí)例
這篇文章主要介紹了opencv python 基于KNN的手寫(xiě)體識(shí)別的實(shí)例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08Python實(shí)現(xiàn)的密碼強(qiáng)度檢測(cè)器示例
這篇文章主要介紹了Python實(shí)現(xiàn)的密碼強(qiáng)度檢測(cè)器,結(jié)合實(shí)例形式分析了Python密碼強(qiáng)度檢測(cè)的原理與實(shí)現(xiàn)方法,涉及Python字符串運(yùn)算與轉(zhuǎn)換、判斷等相關(guān)操作技巧,需要的朋友可以參考下2017-08-08