動態規劃(dynamic programming)是通過組合子問題的解而解決整個問題的。分治演算法是指將問題劃分為一些獨立的子問題,遞迴地求解各子問題,然後合併子問題的解而得到原問題的解。動態規劃適用於子問題不是獨立的情況,也就是各子問題包含公共的子子問題。在這種情況下,若用分治法則會做許多不必要的工作,即重複地求解公共的子子問題。動態規劃對每個子子問題只求解一次,將結果儲存在一張表中,從而避免每次遇到各個子問題時重新計算答案。
動態規劃通常應用於最優化問題。此類問題可能有很多種可行解,每個解有乙個值,我們希望找出乙個具有最優(最大或最小)值的解,稱這樣的解為該問題的乙個最優解(而不是確定的最優解),因為可能存在多個取最優解的值。
動態規劃演算法的設計可分為如下4個步驟:
(1)描述最優解的結構。
(2)遞迴定義最優解的值。
(3)按自底向上的方式計算最優解的值。
(4)由計算出的結果構造乙個最優解。
裝配線排程
colonel汽車公司在有兩條裝配線的工廠內生產汽車。乙個汽車底盤在進入每一條裝配線後,在一些裝配站中會在底盤上安裝部件,然後,完成的汽車在裝配線的末端離開。每一條裝配線上有n個裝配站,編號為j=1,2,…,n。
將裝配線i(i為1或2)的第j個裝配站表示為
。裝配線1的第j個站(
)和裝配線2的第j個站(
)執行相同的功能。然而,這些裝配站是在不同的時間建造的,並且採用了不同的技術,因此,每個站上所需的時間是不同的,即使在兩天不同裝配線相同位置的裝配站上也是這樣。
把在裝配站上所需的裝配時間記為
。底盤進入裝配線i的進入時間為ei,裝配完的汽車離開裝配線i的離開時間為xi。
正常情況下,一旦乙個底盤進入一條裝配線後,它只會經過該條裝配線。在相同的裝配線中,從乙個裝配站到下乙個裝配站所花的時間可以忽略。偶爾會來乙個特別急的訂單,客戶要求盡可能快地製造這些汽車。對這些加急的訂單,底盤仍然依序經過n個裝配站,但工廠經理可以將部分完成的汽車在任何裝配站上從一條裝配線移到另一條裝配線上。把已經通過裝配
站的乙個底盤從裝配線i移走所花的時間為
,其中i=1,2,j=1,2,…,n-1(因為在第n個裝配站後,裝配已經完成)。問題是要確定在裝配線1內選擇哪些站以及在裝配線2內選擇哪些站,以使汽車通過工廠的總時間最小。
解題報告:
步驟1:描述最優解的特徵。
對於裝配線排程問題,乙個問題(找出通過裝配站
的最快路線)最優解包含了子問題(找出通過
或的最快路線)的乙個最優解。稱這個性質為最優子結構,這是是否可以應用動態規劃方法的標誌之一。可以利用子問題的最優解來構造原問題的乙個最優解。
步驟2:乙個遞迴的解。
利用子問題的最優解來遞迴定義乙個最優解的值。選擇在兩條裝配線上通過裝配站j的最快路線問題作為子問題,j=1,2,…,n。
令表示乙個底盤從起點到裝配站的最快可能時間,
為底盤通過工廠的所有路線的最快時間,則
,其中,
。進一步得出:
步驟3:計算最快時間。
整個過程花費時間
。步驟4:構造通過工廠的最快路線。
1 #include 2using
namespace
std;
34 typedef struct
5linecondition;
1213
void fastestway(const linecondition *line, int **&l, int **&f, int &ftotal, int &lend)
1427
else
2832
33if (f[1][i - 1] + line->a[1][i] <= f[0][i - 1] + line->t[0][i - 1] + line->a[1
][i])
3438
else
3943}44
45if (f[0][n - 1] + line->x[0] <= f[1][n - 1] + line->x[1
])46
50else
5155}56
57void printstations(int **l, int lend, int
n)58
6970
for (int i = 0; i < n; ++i)
7174
75delete a;76}
7778
79int main(void)80
91for (int i = 0; i < 2; ++i)
9298}99
100 line.t = new
int *[2
];101
for (int i = 0; i < 2; ++i)
102105
for (int i = 0; i < 2; ++i)
106112
}113
114 line.e = new
int [2
];115 cout << "
請輸入e1,e2:";
116 cin >> line.e[0] >> line.e[1
];117
118 line.x = new
int [2
];119 cout << "
請輸入x1,x2:";
測試結果如下:
演算法分析 動態規劃 裝配線排程
前言 動態規劃的概念 動態規劃 dynamic programming 是通過組合子問題的解而解決整個問題的。分治演算法是指將問題劃分為一些獨立的子問題,遞迴的求解各個問題,然後合併子問題的解而得到原問題的解。例如歸併排序,快速排序都是採用分治演算法思想。本書在第二章介紹歸併排序時,詳細介紹了分治演...
演算法導論 15 1裝配線排程
總共有n個裝配站 底盤進入到裝配線1和裝配線2的時間記錄在二元陣列e 2 上 底盤在裝配線1和裝配線2上每個站的時間記錄在陣列a1 n 和a2 n 上 底盤在每個站上換裝配線的時間記錄在t1 n 1 t2 n 2 上 在最後乙個站時候,不需要換裝配線了,所以陣列只有n 1個資料 底盤離開裝配線的時間...
動態規劃 裝配線排程問題
這個問題是在演算法導論的動態規劃章節有提到,由於問題敘述起來太繁雜就直接省略。命名規則與書上的偽 是一致的,只是用c 具體語言實現了而已。動態規劃問題 裝配線排程問題 pragma once class asl include alspro.h include include using names...