Thuật toán Johnson
Bài toán gia công trên hai máy và thuật toán JohnsonNguyễn Công HiệpĐối với những bạn yêu thích lậptrình tin học thì có lẽ bài toán tìm lịch gia công trên 2 máy là một bài toánquen thuộc bởi nó khá phổ biến trong các tài liệu tham khảo và đề thi tin học.Tôi xin trích dẫn tóm tắt lại đề toán như sau: Có n chi tiết máy D1, D2, .,Dn cần phải được lần lượt gia công trên 2 máy A, B. Thời gian gia công chi tiếtDi trên máy A là ai, trên máy B là bi (i =1,2, ., n). Hãy tìm lịch (trình tự gia công) các chi tiết trên hai máy sao choviệc hoàn thành gia công tất cả các chi tiết là sớm nhất có thể được. Giả thiếtrằng, trình tự gia công các chi tiết trên hai máy là như nhau và các chi tiếtđược làm trên máy A rồi đến máy B.Một thuật toán hết sức nổi tiếngđể giải bài toán trên đó là thuật toán Johnson. Thuật toán gồm các bước nhưsau: + Chia các chi tiết thành 2 nhóm: Nhóm N1 gồm các chitiết Di thoả mãn ai < bi và nhóm N2gồm các chi tiết Di thoả mãn ai > bi. Cácchi tiết Di thoả mãn ai = bi xếp vào nhóm nàocũng được.+ Sắp xếp các chi tiết trong N1 theo chiều tăng của cácai và sắp xếp các chi tiết trong N2 theo chiều giảm củacác bi.+ Nối N2 vào đuôi N1. Dãy thu được (đọc từtrái sang phải) sẽ là lịch gia công tối ưu.Như vậy với ví dụ sau:Bước 1: Ta có:N1 = {3, 5}; N2 = {1, 2, 4}.Bước 2: Sau khisắp xếp thì N1 = {3, 5}; N2= {2, 4, 1}; Bước 3: Lịchgia công là: 3 -> 5 -> 2 -> 4 ->1. Thuật toán Johnson đã được chứng minhvà cách làm trên sẽ cho ta được lịch gia công tối ưu thoả mãn yêu cầu đề bài.Tuy nhiên, ở đây tôi muốn giới thiệu với các bạn một thuật toán tham ăn kháccũng có độ chính xác cao (gần như tuyệt đối) mà có phần đơn giản hơn và ứngdụng của nó cũng khá rộng rãi. Thuật toán như sau:+ Bước 1: Lập mảng Cvới Ci = ai / bi (i = 1, 2, ., n). + Bước 2: Sắp xếp mảng Ctăng dần theo giá trị các phần tử cùng với sự thay đổi thứ tự các chi tiết máy.Thứ tự các chi tiết mấy cuối cùng chính là thứ tự gia công cần tìm.Như vậy với ví dụ trước ta có vớithuật toán trên thì:- Bước 1: Mảng C = [2,7/6, 1/9, 7/3, 2/5].Thứ tựcác chi tiết giữ nguyên là: D1 -> D2 -> D3 -> D4 -> D5- Bước 2: Sau khi sắp xếptăng dần thìC = [1/9, 2/5, 7/6, 2, 7/3]Thứ tự cácchi tiết là: D3 -> D5 -> D2 -> D4 -> D1Thứ tự trên chính là thứ tự giacông phải tìm. Chúng ta có thể dễ dàng thấy được lịch trình gia công ở đây hoàntoàn giống với lịch trình gia công nếu như chúng ta giải quyết bài toán vớithuật toán Johnson. Các bạn có thể kiểm tra độ đúng đắn của thuật toán vớinhiều bộ test khác, tôi xin đưa ra một ví dụ nữa:Thứtự gia công sẽ là: D1 -> D4 -> D2-> D5-> D3Hoặc:D4 -> D1 -> D5 -> D2 -> D3 Thuật toán lập tỉ số như trên cònđược ứng dụng khá rộng rãi ở một số bài toán có chủ đề tương tự. Chúng ta hãyxét bài toán sau: Bắt đầu từ thời điểm 0, một người làm n công việc đánh sốhiệu từ 1 -> n(n ≤ 200). Với 1 ≤ i ≤ N, việc i cần làm trong T[i] đơn vị thời gian.Từ thời điểm 0 đến lúc bắt đầu làm công việc nào đó, người đó bị phạt một lượngtiền C[i] cho mỗi đơn vị thời gian. Khi đã làm một việc nào thì phải làm xongviệc ấy sau đó mới được chuyển sang làm việc khác. Hãy thu xếp trình tự làmviệc sao cho tổng số tiền phạt là ít nhất. Giả sử dữ liệu cho trong tệp có dạngnhư ví dụ sau: 63 1 1 6 4 7 4 3 4 2 1 3 Với dòng đầu đó là số lượng công việc (ở đâyn=6), dòng thứ 2 ghi thứ tự số lượng thời gian cần thiết cho từng công việc.Dòng thứ 3 ghi số tiền phạt cho mỗi đơn vị thời gian ở các công việc tương ứng. Để giải quyết bài toán trên ta có thể sử dụng thuậttoán lập dãy tỉ số như trên. Giả sử mảng A gồm các phần tử A[i] = T[i] / C[i] (i =1, 2, ., n). Khi đóta có các bước giải như sau: - Bước 1: mảng A là 3/4 ; 1/3 ; 1/4 ; 6/2 ;4/1 ; 7/3.Thứ tự công việc vẫn giữ nguyên.- Bước 2: Sắp xếp mảng Atăng dần: 1/4 ; 1/3 ; 3/4 ; 7/3 ; 6/2 ; 4/1. Thứ tự công việc lúc này là: 3 -> 2 -> 1 -> 6 -> 4 -> 5.- Côngviệc 3 làm từ 0 -> 1 h. Sốtiền bị phạt là: 0 (đồng).- Côngviệc 2 làm từ 1 -> 2 h. Sốtiền bị phạt là: 1*3 = 3 (đồng).- Côngviệc 1 làm từ 2 -> 5 h. Sốtiền bị phạt là: 2*4 = 8 (đồng).- Côngviệc 6 làm từ 5 -> 12 h. Sốtiền bị phạt là: 5*3 = 15 (đồng).- Côngviệc 4 làm từ 12 -> 18h. Sốtiền bị phạt là: 12*2 = 24 (đồng).- Côngviệc 5 làm từ 18 -> 19h. Sốtiền bị phạt là: 18*1 = 18 (đồng).Thứ tự công việc trên chính làthứ tự cần tìm. Tổng số tiền bị phạt trong trường hợp này là: 68 (đồng).ứng dụngcủa hai bài toán trên trong thực tế là rất lớn. Việc chọn lựa những thuật toánthích hợp để giải quyết những bài toán có nội dung tương tự là rất cần thiết.Rất mong được sự trao đổi và góp ý của các bạn về những bài toán tương tự chochủ đề trên thêm phần phong phú và bổ ích. . tiếtđược làm trên máy A rồi đến máy B.Một thuật toán hết sức nổi tiếngđể giải bài toán trên đó là thuật toán Johnson. Thuật toán gồm các bước nhưsau: + Chia các. gia công nếu như chúng ta giải quyết bài toán vớithuật toán Johnson. Các bạn có thể kiểm tra độ đúng đắn của thuật toán vớinhiều bộ test khác, tôi xin đưa