回溯法排列樹-最佳排程(最短時間完成)
阿新 • • 發佈:2019-02-15
寶寶懷著無比激動的心情寫下這篇文章,,因為本人實在太 c a i 了。C++裡類的成員函式在
類外面定義時忘記加上 " 類名 " + " : : "了。。。。。。
問題描述:
假設有n個任務由k個可並行工作的機器完成。完成任務i 需要的時為Ti 。試設計一個演算法找出完成這n個任務的最佳排程,使完成全部任務的時間最早。
演算法設計:
對於給定的整數n和k,以及完成任務i需要的時間Ti ,i=1~n。計算完成這n個任務的最佳排程。
這個問題用回溯法解決,一般來說回溯法都有一個“解空間樹”。
先提示一下是一棵深度為N的k叉樹。
#include <iostream> using namespace std; const int N=7; const int k=3; //假設有 N=7 個任務由 k=3 個機器並行完成 class BestCharge { friend int mBCharge(int *); private: int *len; //機器時間序列 // int N, //任務數 // k, //機器數 int best; //最短時間 int *t; //任務的時間 int *x; //當前路徑 x[N] int *bestx; //最優的路徑,時間最短 int comp(); void Backtrack(int dep); }; int BestCharge::comp() { int tmp=0; for(int i=0; i<k; i++) { if(len[i]>tmp) tmp=len[i]; } return tmp; } void BestCharge::Backtrack(int dep) { if(dep==N) { int tmp=comp(); if(tmp<best) { best=tmp; for(int i=0; i<N; i++) { bestx[i]=x[i]; } } return; } for(int i=0; i<k; i++) { len[i]+=t[dep]; x[dep]=i+1; if(len[i]<best) Backtrack(dep+1); len[i]-=t[dep]; } } int mBCharge(int *t) { BestCharge BC; // BC.N=7; // BC.M=3; BC.best=99999; BC.t=t; BC.x=new int[N]; BC.bestx=new int[N]; BC.len=new int[k]; for(int i=0; i<N; i++) { BC.x[i]=0; BC.bestx[i]=0; } for(int i=0; i<k; i++) { BC.len[i]=0; } BC.Backtrack(0); cout<<"各個任務執行的執行機器號如下"<<endl; for(int i=0; i<N; i++) { cout<<BC.bestx[i]<<" "; } cout<<endl; return BC.best; } int main() { int *t=new int[N]; cout<<"輸入任務的時間"<<endl; while(1) { for(int i=0; i<N; i++) { cin>>t[i]; } int gt=mBCharge(t); cout<<"由k="<<k<<"個機器並行運算上述時間的任務最短時間如下:"<<endl; cout<<gt<<endl; } return 0; }
執行結果如下:
程式碼中temp為區域性最優值,best為全域性最優值。其實 temp 就是一同到達樹葉處的3個解向量 x[ i ] 的最優值。best 是所有到達樹葉路徑的最佳值(時間最短)。
當然 best 取值最大對應的那組 x[ i ] (樹的路徑) 就是 best[ i ] 。
上面說到的本題解空間樹N層k叉的樹(應該是排列樹)的樣子,