Cho một mạng với các liên kết vô hướng, giải thuật định tuyến Netchange của Taijbnapis tính các bảng định tuyến tối ưu theo số chặng ít nhất. Giải thuật cho phép tính lại các bảng định tuyến khi tôpô mạng thay đổi với việc tính lại chỉ mang tính bộ phận. Giải thuật dựa trên các giả thiết sau:
N1. Mỗi nút biết kích thước mạng (số nút trong mạng) N. N2. Các kênh truyền có tính chất FIFO.
N3. Các nút được thông báo khi kênh truyền liền kề bị hỏng, sửa đổi hay thêm mới. N4. Chi phí mỗi đường đi bằng số chặng trên đường đi.
Giải thuật có thể xử lý các kênh truyền bị hỏng hay phục hồi, thêm mới, nhưng giả thiết các nút sẽ được thông báo mỗi khi kênh truyền liền kề bị hỏng hay phục hồi. Một nút hỏng hoặc được phục hồi được các nút láng giềng xem như các kênh truyền liền kề nó bị hỏng hay được phục hồi, tương ứng. Giải thuật duy trì tại mỗi nút u một bảng Nbu, trong đó Nbu[v] là định danh của nút láng giềng của u trên đường đi từ u đến v. Yêu cầu của giải thuật này như sau:
R1. Nếu tôpô mạng ổn định sau hữu hạn lần thay đổi, giải thuật sẽ kết thúc sau hữu hạn bước tính.
R2. Khi giải thuật kết thúc, bảng Nbu thỏa mãn: (a) Nếu u = v thì Nbu[v] = local;
(b) Nếu tồn tại đường đi từ u đến v u thì Nbu[v] = w, trong đó w là láng giềng của u trên đường đi ngắn nhất từ u đến v;
(c) Nếu không tồn tại bất kỳ đường đi nào từ u đến v thì Nbu[v] = udef.
Giải thuật Netchange được mô tả trong Hình 3.4. Giả thiết một cạnh thay đổi được thông báo đồng thời cho cả hai nút liền kề.
Nút u sử dụng Du[v] để lưu khoảng cách ước lượng d(u, v), sử dụng Nbu[v] để lưu định danh của nút láng giềng liền kề u trên đường đi từ u đến v (nếu có). ndisu[w, v], với w là láng giềng của u, được u sử dụng để lưu khoảng cách ước lượng d(w, v) do w thông
lượng khoảng cách đến v từ mỗi nút láng giềng, u chọn nút láng giềng w0 “gần” v nhất theo hiểu biết của nó và đặt khoảng cách từ nó đến v là Du[v] = 1 + ndisu[w0, v], đồng thời chọn w0 là nút đầu tiên trên đường đi từ u đến v, tức đặt Nbu[v] = w0.
Ban đầu, u chỉ biết chắc chắn đường đi từ nó đến chính nó (Du[u] = 0 và Nbu[u] =
local), các đường đi còn lại chưa biết nên được xem như không có (Du[v] = N và Nbu[v] = udef, v u). Kết thúc đoạn mã khởi tạo, u gửi các thông báo <mydist, u, 0> đến mỗi nút láng giềng w để thông báo cho w biết khoảng cách d(u, u) = 0.
Khi nhận được một thông báo <mydist, v, d> từ láng giềng w, u cập nhật ndistu[w, v] = d rồi thực hiện thủ tục Recompute(v) để tính toán lại khoảng cách từ u đến v. Thủ tục này đơn giản thực hiện công thức
d(u, v) = 1 + min d(w, v), w Neighu.
Sau khi tính lại, nếu khoảng cách ước lượng Du[v] thay đổi, u gửi thông báo <mydist, v,
Du[v])> đến tất cả các láng giềng của nó để mỗi nút láng giềng cũng tính lại khoảng cách đến v.
Khi cạnh <u, w> bị mất, như giả thiết, cả u và w được thông báo về mất mát đó, trong đó u nhận được thông báo <fail, w> và w nhận được thông báo <fail, u>. Nút u sẽ loại w khỏi danh sách các láng giềng khi nhận được <fail, w>, đồng thời tính lại khoảng cách đến tất cả các đỉnh, tức lần lượt gọi thủ tục Recompute(v) cho mỗi nút v.
Nếu cạnh <u, w> mới được thêm vào hay vừa được phục hồi, u nhận được thông báo <repair, w> và w nhận được thông báo <repair, u>. Khi nhận được <repair, w>, u kết nạp w vào danh sách các láng giềng, đồng thời thông báo cho w biết mọi “kết quả tính toán” của mình, tức gửi cho w thông báo <mydist, v, Du[v]> với mọi v.
var Neighu : set of Nodes; (* Các láng giềng của u *)
Du : array of 0..N; (* Du[v] ước lượng khoảng cách d(u, v) *)
Nbu : array of Nodes; (* Nbu[v] là láng giềng trên đường đi từ u đến v*) ndisu : array of 0..N; (* ndisu[w, v] ước lượng d(w, v) *)
begin forall wNeighu, v V do ndisu[w, v] := N; forall v V do
begin Du[v] := N; Nbu[v] := udef end; Du[u] := 0; Nbu[u] := local;
forall wNeighu do send <mydist, u, 0> to w end
Recompute(v)
begin
if u = v then begin Du[v] := 0; Nbu[v] := local end else begin (* Ước lượng khoảng cách đến v *) d := 1 + min{ndisu[w, v]: wNeighu}; if d < N then begin Du[v] := d; Nbu[v] := w với 1 + ndisu[w, v] = d end
else begin Du[v] := N; Nbu[v] := udef end end;
if Du[v] đã thay đổi then
forall x Neighu do send <mydist, v, Du[v]> to x end
Khi nhận được thông báo <mydist, v, d> từ láng giềng w:
{Thông báo <mydist, v, d> ở đầu hàng đợi Qwv} begin receive <mydist, v, d> from w;
ndisu[w, v] := d; Recompute(v) end
Khi nhận được thông báo cạnh uw hỏng:
end
Khi nhận được thông báo cạnh uw được khôi phục hoặc thêm mới:
begin receive <repair, w>; Neighu := Neighu U {w}; forall v V do
begin ndisu[w, v] := N;
send <mydist, v, Du[v]> to w end
end
Hình 3.4.Giải thuật Netchange.
Chúng ta sẽ chứng minh một số tính chất sau của giải thuật. Những tính chất này được phát biểu dưới dạng các bất biến và được thể hiện trong Hình 3.5.
P(u, w, v) ≡
up(u, w) w Neighu
^ up(u, w) ^ Qwu chứa thông báo <mydist, v, d> thông báo cuối cùng dạng này thỏa mãn d = Dw[v]
^ up(u, w) ^ Qwu không chứa thông báo <mydist, v, d> ndisu[w, v] = Dw[v]
L(u, v) ≡
(u = v) (Du[v] = 0 ^ Nbu[v] = local) ^ (u v ^ w Neighu: ndisu[w, v] < N-1)
(Du[v] = 1 + minndisu[w, v] = 1 + ndisu[Nbu[v], v]) w Neighu ^ (u v ^ w Neighu: ndisu[w, v] N-1) (Du[v] = N ^ Nbu[v] = udef) (v1) (v2) (v3) (v4) (v5) (v6)
Bất biến P(u, w, v) phát biểu rằng nếu u đã kết thúc xử lý thông báo <mydist, v, .> từ w gửi đến thì u ước lượng d(w, v) bằng d(w, v) do w ước lượng. Vị từ up(u, w) là đúng nếu và chỉ nếu liên kết (lưỡng hướng) giữa u và w tồn tại và đang hoạt động. Bất biến
L(u, v) phát biểu rằng u ước lượng d(u, v) luôn luôn phù hợp với hiểu biết cục bộ của nó, và Nbu[v] được thiết lập tương ứng.
Giải thuật kết thúc khi không còn thông báo nào được trao đổi trên các liên kết. Cấu hình tại đó không có bất kỳ thông báo nào đang truyền trên các liên kết được gọi là ổn định. Vị từ stable được dùng để chỉ tính chất này và được phát biểu như sau
stable ≡ u, w: up(u, w) => Qwu không chứa thông báo <mydist, ., .> nào.
Chúng ta phải giả thiết các biến Neighu được khởi tạo đúng đắn, phản ánh đúng sự tồn tại của các liên kết hoạt động, nghĩa là (v1) đúng lúc khởi tạo. Để chứng minh các bất biết trên, ba kiểu chuyển trạng thái cần phải quan tâm
(1) Nhận được thông báo <mydist, ., .>. Toàn bộ đoạn mã thực hiện được xem như một chuyển trạng thái. Trong chuyển trạng thái này, một thông báo nhận được và có thể nhiều thông báo được gửi đi.
(2) Một liên kết bị hỏng và xử lý thông báo <fail, .> bởi hai nút tại hai đầu liên kết bị hỏng.
(3) Một liên kết được sửa đổi và xử lý thông báo <repair, .> bởi hai nút được kết nối.
Bổ đề 3.1. Với mọi u0, w0, và v0, P(u0, w0, v0) là một bất biến.
Chứng minh. Sau khởi tạo, P(u0, w0, v0) đúng. Nếu up(u0, w0), (v2), (v3) đúng,
ndisu0[w0, v0] = N.
Nếu w0 = v0, Dw0[u0] = 0 nhưng thông báo <mydist, v0, 0> có trong Qw0u0, do vậy (v2) và (v3) đúng.
Nếu w0 u0, Dw0[u0] = N và không có thông báo nào trong Qw0u0, do vậy (v2) và (v3) đúng.
Chúng ta xét ba trường hợp chuyển trạng thái như đã nói ở trên.
Loại 1. Giả sử u nhận được thông báo <mydist, v, d> từ w. Tôpô mạng không thay đổi và các tập Neigh không thay đổi, do vậy (v1) đúng.
Nếu v = v0, u = u0, và w = w0, giá trị của ndistu0[w0, v0] có thể thay đổi. Tuy nhiên, nếu thông báo <mydist, v0, .> khác còn trên liên kết thì giá trị của thông báo này vẫn thỏa mãn (v2) và (v3). Nếu thông báo nhận được là thông báo cuối cùng trên hàng đợi thì d =
Dw0[v0], vì vậy (v2) và (v3) đúng.
Nếu v = v0, u = w0, và u0 là láng giềng của u thì (v2) và (v3) có thể sai nếu giá trị của
Dw0[v0] thay đổi do thực hiện Recompute(w0). Tuy nhiên, trong trường hợp này, một thông báo <mydist, v0, .> với giá trị mới được gửi tới u0, giả thiết của (v3) không thỏa mãn còn kết luận của (v2) thỏa mãn nên cả (v2) và (v3) đều đúng. Đây cũng là trường hợp duy nhất thông báo <mydist, v0, .> được thêm vào Qw0v0, và nó luôn thỏa mãn d =
Dw0[v0].
Nếu v = v0, u u0, w0, P(u0, w0, v0) không thay đổi.
Loại 2. Giả sử liên kết uw bị hỏng.
Nếu u = u0 và w = w0, giả thiết của (v2) và (v3) không thỏa mãn, vì vậy cả (v2) và (v3) đúng. (v1) đúng vì w0 bị loại khỏi Neighu0 và ngược lại. Điều tương tự cũng xảy ra nếu u = w0 và w = u0.
Nếu u = w0 nhưng w u0, kết luận của (v2), (v3) có thể không thỏa mãn vì Dw0[v0] thay đổi. Trong trường hợp này, thông báo <mydist, v0, .> do w0 gửi không thỏa mãn giả thiết của (v3) và làm cho kết luận của (v2) đúng, như vậy cả (v2) và (v3) đúng.
Trong các trường hợp khác, P(u0, w0, v0) không thay đổi.
Loại 3. Giả sử liên kết uw được thêm.
Nếu u = u0, w = w0, và up(u0, w0), w0 được thêm vào Neighu0 và ngược lại nên (v1) đúng. Thông báo <mydist, v0, Dw0[v0]> được w0 gửi làm cho kết luận của (v2) đúng và giả thiết của (v3) sai nên P(u0, w0, v0) không thay đổi.
Trong các trường hợp khác, P(u0, w0, v0) không thay đổi. ■
Bổ đề 3.2.Với mỗi u0, v0, L(u0, v0) là một bất biến.
Chứng minh. Ban đầu Du0[u0] = 0 và Nbu0[u0] = local, với v0 u0 và mọi w Neighu,
Loại 1. Giả sử u nhận được thông báo <mydist, v, d> từ w. Nếu u u0 hoặc v v0,
L(u0, v0) không thay đổi.
Nếu u = u0 và v = v0, giá trị ndistu0[w, v0] thay đổi, tuy nhiên Du0[v0] và Nbu0[v0] được tính lại chính xác nên L(u0, v0) được thỏa mãn.
Loại 2. Giả sử liên kết uw hỏng.
Nếu u = u0 hoặc w = u0 thì Neighu0 thay đổi, nhưng Du0[v0] và Nbu0[v0] được tính lại chính xác thỏa mãn L(u0, v0).
Loại 3. Giả sử liên kết uw được thêm.
Nếu u = u0, Neighu0 thay đổi do kết nạp w, tuy nhiên u đặt ndistu0[w, v0] bằng N nên
L(u0, v0) vẫn thỏa mãn. ■
Định lý 3.1. Khi đạt được cấu hình ổn định, Nbu[v] thỏa mãn (1)Nếu u = v, Nbu[v] = local;
(2)Nếu tồn tại đường đi từ u đến v u, Nbu[v] = w, trong đó w là nút láng giềng của u trên đường đi ngắn nhất từ u đến v.
(3)Nếu không tồn tại đường đi từ u đến v, Nbu[v] = udef.
Chứng minh. Khi giải thuật kết thúc, vị từ stable đúng, cùng với bất biến P(u, w, v) nên với mọi u, w, v: up(u, w) ndistu[w, v] = Dw[v].
Áp dụng L(u, v) cho mọi u, v ta có
Du[v] = 0 nếu u = v
= 1 + minDw[v] nếu u v ^ w Neighu: Dw[v] < N-1 w Neighu
= N nếu u v ^ w Neighu: Dw[v] N-1 (v7).
chứng tỏ rằng Du[v] = d(u, v) nếu u và v trong cùng một thành phần liên thông, và Du[v] = N nếu u và v thuộc hai thành phần liên thông khác nhau.
Trước tiên, chúng ta chứng minh quy nạp nếu u và v thuộc cùng một thành phần liên thông thì Du[v] ≤ d(u, v).
Trường hợp d(u, v) = k+1: có nghĩa tồn tại w Neighu với d(w, v) = k. Theo giả thiết quy nạp, Dw[v] ≤ k, và theo (v7) Du[v] ≤ k+1.
Bây giờ ta sẽ chứng minh bằng quy nạp rằng nếu Du[v] < N thì tồn tại đường đi từ u đến v và d(u, v) ≤ Du[v].
Trường hợp Du[v] = 0: Công thức (v7)dẫn tới Du[v] = 0 chỉ khi u = v, d(u, v) = 0. Trường hợp Du[v] = k+1 < N : Công thức (v7) dẫn tới w Neighu với Dw[v] = k. Bằng quy nạp, tồn tại đường đi từ w đến v và d(w, v) ≤ k, do vậy tồn tại đường đi từ u đến v và d(u, v) ≤ k+1. ■
Để chứng minh giải thuật sẽ dẫn đến cấu hình ổn định nếu tôpô mạng không thay đổi, ta sử dụng một hàm tiêu chuẩn f được xác định trên cấu hình c như sau
f(c) = (t0, t1, …, tN) là bộ (N+1) phần tử, trong đó ti = (số thông báo <mydist, ., i>) + (số cặp thứ tự u, v sao cho Du[v] = i).
Bổ đề 3.3. Mỗi thông báo <mydist, ., .> được xử lý làm giảm f.
Chứng minh. Giả sử nút u với Du[v] = d1 nhận được một thông báo <mydist, v, d2>, và sau khi tính lại Du[v] = d. Giải thuật đảm bảo d ≤ d2+1.
Trường hợp d < d1: Lúc này d = d2 + 1, do vậy td2 giảm đi một và td1 cũng giảm đi một, chỉ td với d > d2 tăng. Do vậy, f giảm.
Trường hợp d = d1: Không có thông báo <mydist, ., .> mới nào được sinh ra và chỉ td2 giảm, do vậy f giảm.
Trường hợp d > d1: Lúc này td1 và td2 giảm đi một, chỉ td với d > d1 tăng. Do vậy, f giảm. ■
Định lý 3.2. Nếu tôpô của mạng ổn định sau hữu hạn biến đổi, giải thuật đạt đến cấu hình ổn định sau hữu hạn bước.
Chứng minh. Nếu tôpô mạng ổn định, chỉ có xử lý các thông báo <mydist, ., .> được thực hiện; và theo Bổ đề 3.3, f giảm trong mọi xử lý. Do f không thể giảm mãi nên giải thuật sẽ đến cấu hình ổn định sau hữu hạn bước. ■
Nhận xét:
- Giải thuật Netchange được phát triển từ giải thuật của Bellman-Ford.
- Cũng giống như giải thuật Bellman-Ford, giải thuật Netchange có vòng lặp định tuyến và hiện tượng đếm đến vô hạn.
- Trong giải thuật Netchange, việc tính đường định tuyến đến nút này hoàn toàn độc lập với tính đường định tuyến đến các nút khác. Chính vì vậy, giải thuật Netchange thuộc lớp giải thuật định tuyến độc lập điểm đích.
- Khi một cạnh, giả sử <u, w> bị hỏng, u không nhất thiết phải tính lại khoảng cách đến tất cả các nút như giải thuật mà chỉ cần tính lại những nút v mà Nbu[v] = w.
- Nên lấy tất cả các thông báo trong mỗi Qwu , với w là láng giềng của u, và cập nhật các ndistu trước khi gọi thủ tục Recompute(v) cho mỗi v xuất hiện trong một thông báo nào đó. Làm như vậy, số lần tính lại sẽ giảm đi, tất nhiên số thông báo cần gửi và thời gian hội tụ của giải thuật cũng được giảm.