1.問題描述:
有n個機器零件,每個零件必須先由機器a處理,再由機器b處理。零件pi需要機器1,2處理時間為p[i].atime,p[i].btime
如何安排零件加工順序,使第乙個零件從機器1上加工開始到最後乙個零件在機器2上加工完成,所需的總加工時間最短?
2.a機可以連續不間斷開動,b機第i個零件的加工完成時間為:
b_end_time[ i ]=max(b_end_time[ i - 1 ] , a_end_time[ i ]) + p[ i ].btime取決於b機處理完前乙個零件和a機處理完本零件的最晚時間
3.排列樹的概念
回憶遞迴演算法中陣列全排列的內容:
a[n]的全排列 = for(0..n-1)將每個元素swap到a[0]一次 + a[n-1]的全排列在解空間中,每遞迴深入一層,分支數-1 ,到葉結點時,解的數量=n*(n-1)*(n-2)*(n-3).......=n!
4.約束與限界函式
①約束函式禁止 "根本就不可能出現的情況" ,本題中每一種排列方式都可以出現,所以沒有約束函式
②限界函式禁止 "會出現但沒必要再擴充套件的情況". 當目前的b_end_time小於已知的最優解bestn2時,可以試著進行遞迴
因此,最優解bestn2初始值=int_max
分為三個區:全域性變數區/遞迴函式/呼叫遞迴函式的函式
//bps is short of "best process sequence" 最佳加工順序
//找出零件p[n]的乙個最佳加工順序 ,複習陣列的全排列問題
//機器a的加工是可以連續不間斷的
//機器b,第i個零件的開始加工時間=max(b[ i - 1 ] , a[ i ]) +btime[ i ]
//將最後的b_end_time賦給bestn2.
struct product
;vectorp = ,,,,,};
auto m2 = p.size();
int bestn2 = int_max; //記錄一次遞迴結束後的最優值
vectorbestx2(m2, 0); //記錄一次遞迴結束後的最優策略
vectorcx2(m2, 0); //記錄當前策略
int a_end_time; //記錄當前a機器的完成時間
int b_end_time; //記錄當前b機器(總體)的完成時間
void bpsbacktrack(int t)//t表示子問題的首位,首次遞迴時t=0
//每一種加工順序都能得到解,不存在約束條件,只有限界條件
for (int i = t; i < m2; i++) //第一層迴圈m2次,之後每層--1;
//最優值的回溯
a_end_time-= p[cx2[i]].atime;
b_end_time = temp; }}
void bps()
a_end_time = 0; //記錄當前a機器的完成時間
b_end_time = 0;
bpsbacktrack(0);
cout << "最優加工順序: ";
for (int i = 0; i < m2; i++)
cout << endl;
}
演算法 回溯法解決最佳排程問題
問題 假設有 n 個任務由 k 個可並行工作的機器來完成。完成任務 i 需要時間為ti 設計完成這 n 個任務的最佳排程演算法,使得完成全部任務的時間最早。演算法設計 從n個作業中找出有最小完成時間和的作業排程,所以批處理作業排程問題的解空間是一棵排列樹。按照回溯法搜尋排列樹的演算法框架,設開始時t...
演算法 回溯法解決最佳排程問題
問題 假設有 n 個任務由 k 個可並行工作的機器來完成。完成任務 i 需要時間為ti 設計完成這 n 個任務的最佳排程演算法,使得完成全部任務的時間最早。演算法設計 從n個作業中找出有最小完成時間和的作業排程,所以批處理作業排程問題的解空間是一棵排列樹。按照回溯法搜尋排列樹的演算法框架,設開始時t...
回溯法 最佳排程問題
一 題目要求 設有n個任務由k個可並行工作的機器來完成,完成任務i需要時間為。試設計乙個演算法找出完成這n個任務的最佳排程,使完成全部任務的時間最早。二 演算法設計與分析 該演算法可抽象為子集樹回溯演算法,針對特定的任務數和機器數定 空間,對於n個任務和k個機器,解編碼 x1,x2,xn xi表示給...