Bây giờ ta xét trường hợp riêng thứ hai của bài toán ựường ựi ngắn nhất, mà ựể giải nó có thể xây dựng thuật toán với ựộ phức tạp tắnh toán O(n2), ựó là khi ựồ thị không có chu trình (còn trọng số trên các cung có thể là các số thực tuỳ ý). Trước hết ta chứng minh ựịnh lý sau.
định lý 11.1 Giả sử G là ựồ thị không có chu trình. Khi ựó các ựỉnh của nó có thể ựánh số sao cho mỗi cung của ựồ thị chỉ hướng từ ựỉnh có chỉ số nhỏ hơn ựến ựỉnh có chỉ số lớn hơn, nghĩa là mỗi cung của nó có sự biểu diễn dưới dạng (v[i], v[j]), trong ựó i < j.
Vắ dụ 11.1 đồ thị trong hình 11.1 có các ựỉnh số thoả mãn ựiều kiện nêu trong ựịnh lý.
Hình 11.1 đồ thị không có chu trình.
để chứng minh ựịnh lý ta mô tả thuật toán sau ựây, cho phép tìm ra cách ựánh số thoả mãn ựiều kiện ựịnh lý.
Procudure Numbering;
(* đầu vào: đồ thị có hướng G=(V,E) với n ựỉnh không chứa chu trình ựược cho bởi danh sách kề Ke(v), v ∈ V.
đầu ra:
Với mọi cung (u,v) của ựồ thị ta ựều có NR [u] < NR [v] *) Begin
For v∈ V do Vao[v]:=0; (* Tắnh Vao[v]=deg-(v) *) for u∈ V do
for v∈ Ke(u) do Vao[v]:=Vao[v]+1; Queue:=∅ ;
For v∈ V do
if Vao[v]=0 then Queue⇐ v; num:=0;
while queue <>∅ do begin
u⇐ queue; num:=num+1; NR[u]:=num; for v ∈ Ke(u) do
begin
Vao[v]:=Vao[v]-1;
If Vao[v]=0 then queue⇐ v; end;
end; End;
Thuật toán ựược xây dựng dựa trên ý tưởng rất ựơn giản sau: rõ ràng trong ựồ thị không có chu trình bao giờ cũng tìm ựược ựỉnh có bán bậc vào bằng 0 (không có cung ựi vào). Thực vậy, bắt ựầu từ ựỉnh v1 nếu có cung ựi vào nó từ v2 thì ta lại chuyển sang xét ựỉnh v2 . Nếu có cung từ v3 ựi vào v2, thì ta lại chuyển sang xét ựỉnh v3. . .Do ựồ thị không có chu trình nên sau một số hữu hạn lần chuyển như vậy ta phải ựi ựến ựỉnh không có cung ựi vào. Thoạt tiên, tìm các ựỉnh như vậy của ựồ thị. Rõ ràng ta có thể ựánh số chúng theo thứ tự tuỳ ý bắt ựầu từ 1. Tiếp theo, loại bỏ khỏi ựồ thị những ựỉnh ựã ựược ựánh số cùng các cung ựi ra khỏi chúng, ta thu ựược ựồ thị mới cũng không có chu trình, và thủ
tục ựược lặp với ựồ thị mới này. Quá trình ựó sẽ ựược tiếp tục cho ựến khi tất cả các ựỉnh của ựồ thị ựược ựánh số.
Chú ý:
1) Rõ ràng trong bước khởi tạo ra phải duyệt qua tất cả các cung của ựồ thị khi tắnh bán bậc vào của các ựỉnh, vì vậy ở ựó ta tốn cỡ O(m) phép toán, trong ựó m là số cung của ựồ thị. Tiếp theo, mỗi lần ựánh số một ựỉnh, ựể thực hiện việc loại bỏ ựỉnh ựã ựánh số cùng với các cung ựi ra khỏi nó, chúng ta lại duyệt qua tất cả các cung này. Suy ra ựể ựánh số tất cả các ựỉnh của ựồ thị chúng ta sẽ phải duyệt qua tất cả các cung của ựồ thị một lần nữa. Vậy ựộ phức tạp của thuật toán là O(m).
2) Thuật toán có thể áp dụng ựể kiểm tra xem ựồ thị có chứa chu trình hay không? Thực vậy, nếu kết thúc thuật toán vẫn còn có ựỉnh chưa ựược ựánh số (num<n) thì ựiều ựó có nghĩa là ựồ thị chứa chu trình.
Do có thuật toán ựánh số trên, nên khi xét ựồ thị không có chu trình ta có thể giả thiết là các ựỉnh của nó ựược ựánh số sao cho mỗi cung chỉ ựi từ ựỉnh có chỉ số nhỏ ựến ựỉnh có chỉ số lớn hơn. Thuật toán tìm ựường ựi ngắn nhất trên ựồ thị không có chu trình ựược mô tả trong sơ ựồ sau ựây.
Procedure Critical_Path;
(* Tìm ựường ựi ngắn nhất từ ựỉnh nguồn ựến tất cả các ựỉnh còn lại trên ựô thị không có chu trình *)
đầu vào:
đồ thị G=(V,E), trong ựó V={ v[1], v[2], . . . , v[n]} . đối với mỗi cung (v[i], v[j]) ∈ E, ta có i<j.
đồ thị ựược cho bởi danh sách kề Ke(v), v ∈ V. đầu ra:
Khoảng cách từ v[1] ựến tất cả các ựỉnh còn lại ựược ghi trong mảng d[v[i]], i= 2, 3, . . .,n *)
Begin
for j:=2 to n do d[v[j]]:=a[v[1], v[j]]; for j:=2 to n do
for v ∈ Ke[v[j]] do d[v]:=min(d[v], d[v[j]]+a[v[j], v]); End;
độ phức tạp tắnh toán của thuật toán là O(m), do mỗi cung của ựồ thị phải xét qua ựúng một lần.
Các thuật toán ựược mô tả ở trên thường ựược ứng dụng vào việc xây dựng những phương pháp giải bài toán ựiều khiển việc thực hiện những dự án lớn, gọi tắt là PERT (Project Evaluation and Review Technique) hay CDM (Critical path Method). Một vắ dụ ựơn giản cho ứng dụng này ựược mô tả trong vắ dụ dưới ựây.
Công ựoạn t[i] Các công ựoạn phải ựược hoàn thành trước nó 1 15 Không có 2 30 1 3 80 Không có 4 45 2, 3 5 124 4 6 15 2, 3 7 15 5, 6 8 19 5
Vắ dụ 11.2 Việc thi công một công trình lớn ựược chia thành n công ựoạn, ựánh số từ 1 ựến n. Có một số công ựoạn mà việc thực hiện nó chỉ ựược tiến hành sau khi một sô công ựoạn nào ựó ựã hoàn thành. đối với mỗi cong ựoạn i biết t[i]] là thời gian cần thiết ựể hoàn thành nó (i=1, 2,. . .,n). Dữ liệu với n=8 ựược cho trong bảng dưới ựây
Giả sử thời ựiểm bắt ựầu tiến hành thi công công trình là 0. Hãy tìm tiến ựộ thi công công trình (chỉ rõ mỗi công ựoạn phải ựược bắt ựầu thực hiện vào thời ựiểm nào) cho công trình ựược hoàn thành xong trong thời ựiểm sớm nhất có thể ựược.
Ta có thể xây dựng ựồ thị có hướng n ựỉnh biểu diễn hạn chế về trình tự thực hiện các công việc như sau: Mỗi ựỉnh của ựồ thị tương ứng với một công việc, nếu công việc i phải ựược thực hiện trước công ựoạn j thì trên ựồ thị có cung (i,j), trọng số trên cung này ựược gán bằng t[i], xem hình 11.2 dưới ựây.
Hình 11.2 đồ thị minh hoạ PERT.
Thêm vào ựồ thị hai ựỉnh 0 và n+1 tương ứng với hai sự kiện ựặc biệt: ựỉnh 0 tương ứng với công ựoạn lễ khởi công, nó phải ựược thực hiện trước tất cả các công ựoạn khác, và ựỉnh n+1 tương ứng với công ựoạn cắt băng khánh thành công trình, nó phải ựược thực hiện sau các công ựoạn, với t[0]=t[n+1]=0 (trên thực tế chỉ cần nối ựỉnh 0 với tất cả các ựỉnh có bán bậc bằng 0 và nối tất cả các ựỉnh có bán bậc ra bằng 0 với ựỉnh n+1). Gọi ựồ thị thu ựược là G. Rõ ràng bài toán ựặt ra dẫn về bài toán tìm ựường ựi ngắn nhất từ ựỉnh 0 ựến tất cả các ựỉnh còn lại trên ựồ thị G. Do ựồ thị G rõ ràng là không chứa chu trình, nên ựể giải bài toán ựặt ra có thể áp dụng các thuật toán mô tả trên, chỉ cần ựổi dấu tất cả các trọng số trên các cung thành dấu ngược lại, hoặc ựơn giản hơn chỉ cần ựổi toán tử Min trong thuật toán Critcal_Path thành toán tử Max. Kết thúc thuật toán, chúng ta thu ựược d[v] là ựộ dài ựường ựi dài nhất từ ựỉnh 0 ựến ựỉnh v. Khi ựó d[v] cho ta thời ựiểm sớm nhất có thể bắt ựầu thực hiện công ựoạn v, nói riêng d[n+1] là thời ựiểm sớm nhất có thể cắt băng khánh thành, tức là thời ựiểm sớm nhất có thể hoàn thành toàn bộ công trình.
Cây ựường ựi dài nhất của bài toán trong vắ dụ 11.2 tìm ựược theo thuật toán ựược chỉ ra trong hình 11.2.