Bài tốn: Một người phục vụ phải phục vụ cho n khách hàng. Khách hàng thứ i cần phục vụ trong thời gian t[i] , 1 i n. Ta muốn tổng thời gian chờ đợi và thời gian được phục vụ của tất cả các khách hàng (gọi là thời gian hệ thống) là nhỏ nhất. Vấn đề là tìm một trình tự phục vụ khách hàng (gọi là lịch phục vụ) đạt được mục đích đặt ra.
Ví dụ: Giả sử cĩ 3 khách hàng với t[1]=5, t[2]=10, t[3]=3. Khi đĩ cĩ thể cĩ 6 lịch phục vụ như sau: Thứ tự Tổng thời gian hệ thống T 1 2 3: 5+(5+10)+(5+10+3) =38 1 3 2: 5+(5+3)+(5+3+10) =31 2 1 3: 10+(10+5)+(10+5+3) =43 2 3 1: 10+(10+3)+(10+3+5) =41 3 1 2: 3+(3+5)+(3+5+10) =29 tối ưu 3 2 1: 3+(3+10)+(3+10+5) =34
Trong trường hợp thứ nhất khách hàng 1 được phục vụ ngay, khách hàng 2 chờ trong khi khách hàng 1 được phục vụ và đến lượt được phục vụ, khách hàng 3 chờ trong khi hai khách hàng trước được phục vụ và đến lượt được phục vụ, do đĩ T=38.
khách hàng i , i1 2,…, im ta thêm khách hàng j. Tại thời điểm này T sẽ tăng thêm một lượng là t[i ]+t[i1 2]+…+t[im]+t[j]
Để tối thiểu T ta chỉ cần làm tối thiểu t[j]. Vì thế, ở mỗi bước ta sẽ thêm vào cuối lịch khách hàng địi hỏi ít thời gian phục vụ nhất trong các khách hàng cịn lại. Ta cĩ mơ tả sau
void Lichpv; // C là tập khách hàng, C={1,2, …,n}, L là lịch phục vụ} i=1; While C { x= khách hàng trong C cĩ tx nhỏ nhất; L[i]=x; i=i+1; C=C\{x} }
Chứng minh tính đúng đắn của thuật tốn:
Giả sử I=(i1, i2, …, i ) là một hốn vị của các số nguyên (1, 2, …, ). Nếu các khách n n
hàng được phục vụ theo thứ tự I thì tổng thời gian hệ thống tương ứng là T(I) = t[i1]+( t[i1]+t[i2)]+…+( t[i ]+…+t[in]) 1
= n.t[i1]+(n-1)t[i2]+…+t[in] =
n k k i t k n 1 ] [ ) 1 (
Giả sử trong I tìm được hai chỉ số a và sao cho b a < b và t[i ] > t[ia b], nĩi cách khác là
khách hàng thứ được phục vụ trước khách hàng thứ trong khi khách hàng thứ cần ít a b b
thời gian phục vụ hơn khách hàng thứ . Nếu ta thay đổi vị trí của hai khách hàng này thì a
được một thứ tự mới I’ nhận được từ I bằng cách đổi chỗ ia và ib. Thứ tự mới này tốt hơn vì
T(I’) = (n a- +1)t[ia]+(n b- +1)t[ib] +
n b a k k k i t k n , 1 ] [ ) 1 (
từ đĩ T(I’)-T(I) = (b-a)(t[i ]-t[ia b]) > 0.
Do đĩ ta cĩ thể cải thiện một lịch bất kỳ mà trong đĩ cĩ khách hàng được phục vụ trước một khách hàng khác cần ít thời gian phục vụ hơn.
Lịch duy nhất khơng thể cải tiến được là lịch thu được khi sắp thứ tự các khách hàng khơng giảm theo thời gian phục vụ. Các lịch này là tương đương nhau và đều là tối ưu.
b. Lịch phục vụ cĩ thời hạn.
Bài tốn: Cĩ một tập n cơng việc cần thực hiện, mỗi cơng việc được thực hiện trong
một đơn vị thời gian. Tại một thời điểm t = 1, 2, … chỉ cĩ thể thực hiện được đúng một cơng việc.
Cơng việc i, 1 i n mang lại một giá trị g chỉ khi nĩ được thực hiện khơng sau thời i điểm d[i].
Tìm lịch thực hiện các cơng việc sao cho tổng giá trị thu được là lớn nhất. Ví dụ: với =4 và các giá trị saun
i 1 2 3 4
gi 50 10 15 30
d[i] 2 1 2 1
cĩ một vài lịch thực hiện và các giá trị mang lại như sau Lịch Giá trị
1, 3 65 2, 1 60 3, 1 65
4, 1 80 tối ưu
dãy 3, 2 chẳng hạn khơng được xét vì khi đĩ cơng việc 2 khơng được thực hiện đúng thời hạn.
Ta gọi một tập S các cơng việc là cĩ triển vọng nếu tồn tại ít nhất một cách sắp xếp các cơng việc trong tập S thành dãy sao cho tất cả các cơng việc trong dãy được thực hiện trong thời hạn của nĩ, ta cũng gọi dãy này là dãy cĩ triển vọng. Khi đĩ một thuật tốn tham lam hiển nhiên là xây dựng tập các cơng việc cĩ triển vọng theo từng bước, ở mỗi bước thêm
vào tập này cơng việc cĩ giá trị lớn nhất chưa xét sao cho tập các cơng việc vẫn cịn cĩ triển vọng.
Ở ví dụ trên đầu tiên ta chọn cơng việc 1, sau đĩ chọn cơng việc 4: tập hợp {1, 4} cĩ triển vọng vì cĩ thể thực hiện theo thứ tự 4, 1. Tiếp theo ta thử tập {1,3,4} khơng cĩ triển vọng và loại cơng việc 3 ra. Cuối cùng thử {1,2,4} cũng khơng cĩ triển vọng nên loại cơng việc 2 ra. Lời giải trong trường hợp này là {1,4} mà cĩ thể thực hiện theo thứ tự 4, 1 là tối ưu.
Bây giờ ta sẽ chứng minh rằng thuật tốn luơn tìm được một lịch tối ưu và tìm một cách cài đặt thuật tốn hiệu quả.
Giả sử J là một tập k cơng việc. Để kiểm tra J cĩ triển vọng hay khơng dường như ta phải thử tất cả các hốn vị của các cơng việc trong J. Việc thử như vậy khá phức tạp và mất nhiều thời gian. Ta sẽ xem xét một cách làm khác dựa vào bổ đề sau:
Bổ đề 1: Giả sử J là một tập k cơng việc. Và giả sử S=(s1, s2,…, s ) là một hốn vị của k các cơng việc này sao cho d[s1] d[s2] …. d[s ]. Khi k đĩ tập J là cĩ triển vọng khi và chỉ khi dãy S cĩ triển vọng.
Chứng minh: Ta chỉ cần chứng minh nếu J cĩ triển vọng thì S cĩ triển vọng.
Nếu J cĩ triển vọng thì cĩ một dãy R=(r1, r2,…, rk) sao cho d[ri] i, 1 i k. Giả sử R khác S. Giả sử m là chỉ số nhỏ nhất sao cho sm khác r , và p m được xác định sao cho rp=sm, rõ ràng p>m. Ta cĩ: d[rm] d[sm] theo tính chất của S và cách xác định m, suy ra d[rm] d[r ]. p Do đĩ cơng việc rm cĩ thể thực hiện muộn hơn rptrong lịch R. Trong R cĩ thể đổi chỗ hai cơng việc rm và rp ta được một dãy mới vẫn cĩ triển vọng, dãy này trùng với S ít nhất ở các vị trí 1, 2, …, m. Tiếp tục như vậy ta được một loạt dãy cĩ triển vọng, mỗi dãy lại cĩ thêm ít nhất một vị trí cĩ cơng việc trùng với cơng việc trong S. Sau k 1 bước như vậy ta thu được - dãy S. Vậy S là dãy cĩ triển vọng.
Dựa vào bổ đ để xác định một tập là cĩ triển vọng ta chỉ cần kiểm tra một dãy sắp thứ ề, tự tăng theo thời hạn cĩ triển vọng hay khơng là đủ.
Trong mơ tả thuật tốn sau đây ta giả thiết rằng các cơng việc được đánh số sao cho g1>g2 >…> gnvà d[i] > 0 với i=1,…,n
void LichTH;
d[0]=0; j[0]=0; // phần tử cầm canh k=1; j[1]=1; // luơn chọn cơng việc 1
For (i=2;i<=n;i++) { // Lặp tham lam theo thứ tự giảm của g r=k;
While (d[j[r]] > max(d[i],r)) { r--; }
If (d[j[r]] <= d[i] && d[i]>r) { // tìm vị trí để xếp lịch cho cơng việc i For (m=k;m>=r+1;m--) {
j[m+1]=j[m]; // dời các cơng việc về phía sau j[r+1]=i; // chèn vào cơng việc mới chọn }
k=k+1; } }
Return k, j[1..k];
// k là số cơng việc được chọn, j là trình tự thực hiện các cơng việc
Thuật tốn này tại mỗi thời điểm vừa chọn cơng việc thích hợp vừa chèn cơng việc đĩ vào vị trí thích hợp trong lịch thực hiện.
Chứng minh tính tối ưu của thuật tốn:
Giả sử thuật tốn tham lam chọn thực hiện tập I các cơng việc trong khi thực tế tập J là tối ưu, J khác I. Xét 2 dãy cĩ triển vọng SI và SJ ứng với 2 tập cơng việc này. Bằng cách thay đổi một cách thích hợp các cơng việc trong SI và SJ ta cĩ thể nhận được hai dãy S’I và S’J sao cho mỗi cơng việc chung của cả hai dãy được thực hiện ở cùng thời điểm trong hai dãy. Như vậy trong mỗi dãy cĩ thể cĩ khoảng trống. Rõ ràng S’ và S’I J là hai dãy khác nhau vì I khác J. Xét một thời điểm tuỳ ý mà tại đĩ cơng việc trong S’ khác với cơng việc trong I S’J.
Nếâu một cơng việc a nào đĩ cĩ trong S’ , tương ứng trong S’ là khoảng trống, tức là I J cơng việc a khơng cĩ trong S’J, lúc đĩ tập J {a} là cĩ triển vọng và tốt hơn J. Điều này là
khơng thể vì J là tối ưu theo giả thiết.
cơng việc b khơng cĩ trong S’I, lúc đĩ tập I {b} là cĩ triển vọng và vì thuật tốn là tham lam nên nĩ sẽ bổ sung cơng việc b vào I. Thuật tốn đã khơng làm như vậy nên tình huống này cũng khơng xảy ra.
Tình huống duy nhất cĩ thể là một cơng việc a nào đĩ cĩ trong S’ , tương ứng trong S’I J là cơng việc b khác a. Suy ra a khơng cĩ trong J, và b khơng cĩ trong I. Khi đĩ