Devlog #86 – Fala 65: Działanie kapilarne, A*, krzywe parametryczne, wiązka wirowa, koloidy i trasowanie internetowe

Fala 65 to szerokie wydanie dotykające statyki płynów, przeszukiwania ścieżek, geometrii obliczeniowej, fotoniki, materii miękkiej i sieci komputerowych. Działanie kapilarne czyni namacalnym prawo Jurina z wklęsłymi i wypukłymi meniskami oraz mierzalnym wznoszeniem w różnych promieniach rurki; A* pokazuje, dlaczego świadome heurystyki miażdżą Dijkstrę na rzadkich labiryntach; symulacja krzywych parametrycznych krok po kroku przechodzi przez konstrukcję de Casteljau, zanim uogólni się na B-spliny i dokładne okręgi NURBS; wiązki wirowe ujawniają, jak spiralne czoło fazy niesie skwantowany orbitalny moment pędu; teoria DLVO wyjaśnia, dlaczego koloidy są jednocześnie stabilne i podatne na nagłą flokulację; a trasowanie internetowe ożywia błędy zliczania do nieskończoności Bellmana-Forda i ich naprawę obok ponownej zbieżności link-state. Biblioteka osiąga 591 symulacji.

Fala 65 — dodano 6 symulacji
591
Symulacji łącznie
6
Nowych w tej fali
65
Numer fali
86
Nr Devlogu

Nowe symulacje

💧

Działanie kapilarne — prawo Jurina, menisk i napięcie powierzchniowe

Prawo Jurina h = 2γcosθ / (ρgr) zademonstrowane w wielu promieniach rurki. Kształt menisku dla cieczy zwilżających (wklęsły) vs niezwilżającej rtęci (wypukły). Wznoszenie proporcjonalne do 1/r pokazane obok siebie. Wpływ temperatury na napięcie powierzchniowe γ z rzeczywistymi danymi wody.

🗺️

Przeszukiwanie ścieżek A* — kopiec binarny, trzy heurystyki i porównanie algorytmów

A* z kopcem binarnym (f = g + h). Trzy heurystyki: Manhattan, euklidesowa, diagonalna. Bezpośrednie porównanie: A* vs Dijkstra vs zachłanne best-first. Predefiniowane generowanie labiryntu. Wizualizacja: zbiór otwarty (cyjan), zbiór zamknięty (niebieski), ścieżka (żółty). Licznik ekspansji węzłów.

✏️

Krzywe parametryczne — Bézier, B-spline i NURBS

Krzywe Béziera: konstrukcja de Casteljau animowana krok po kroku. B-spliny: rekurencja Coxa-de Boora z edytorem wektora węzłów. NURBS: dokładna reprezentacja okręgu poprzez wymierne funkcje bazowe. Stopień 2–5, przeciągalne punkty kontrolne wszędzie.

🌀

Wiązka wirowa — mody Laguerre'a-Gaussa i orbitalny moment pędu

Mody wiązki Laguerre'a-Gaussa LGp,ℓ ze spiralną fazą exp(iℓφ) i uogólnionym wielomianem Laguerre'a Lp|ℓ|. Orbitalny moment pędu ℓℏ na foton. Spiralny i widlasty wzór interferencyjny pokazujący OAM. Osobliwość fazy na osi wiązki.

🧪

Koloidy — teoria DLVO, Stokes-Einstein i agregacja fraktalna

Stokes-Einstein: D = kBT/(6πηr). Teoria DLVO: odpychanie elektrostatyczne (ekranowanie Debye'a) + przyciąganie van der Waalsa. Flokulacja i agregacja fraktalna z suwakiem siły jonowej. Prędkość sedymentacji v = 2r²(ρ−ρf)g/(9η). Kolor wg rozmiaru agregatu.

🌐

Trasowanie internetowe — Bellman-Ford, Dijkstra link-state i koncepcje BGP

Wektor odległości Bellmana-Forda z demonstracją zliczania do nieskończoności i naprawą split horizon. Zalewanie link-state Dijkstry z wizualizacją tabeli routera. Animacja awarii łącza i ponownej zbieżności. Koncepcja path-vector BGP. Pokazuje pętle trasowania i ich rozwiązanie.

💧 Działanie kapilarne — prawo Jurina i menisk

Napięcie powierzchniowe i kąt zwilżania

Napięcie powierzchniowe γ (N/m) powstaje z asymetrycznych sił międzycząsteczkowych na granicy ciecz-powietrze: cząsteczki na powierzchni mają mniej sąsiadów niż cząsteczki w masie i znajdują się w stanie o wyższej energii. Gdy ciecz styka się z ciałem stałym, konkurują trzy energie granic: ciecz-powietrze (γLA), ciało stałe-ciecz (γSL) i ciało stałe-powietrze (γSA). Ich równowaga determinuje kąt zwilżania θ poprzez równanie Younga:

Równanie Younga (równowaga sił na linii styku):
  γ_SA = γ_SL + γ_LA · cos θ
  cos θ = (γ_SA − γ_SL) / γ_LA

Klasy kąta zwilżania:
  θ = 0°:    idealne zwilżanie (ciecz rozpływa się całkowicie)
  0 < θ < 90°: zwilżanie (menisk wklęsły, wznoszenie kapilarne)
  θ = 90°:   neutralny
  90° < θ < 180°: niezwilżanie (menisk wypukły, depresja kapilarna)
  θ = 180°:  idealne niezwilżanie (stan superhydrofobowy Cassiego-Baxtera)

Woda na szkle:  θ ≈ 20°  (zwilżanie)
Rtęć na szkle: θ ≈ 140° (niezwilżanie)

Prawo Jurina: wznoszenie kapilarne

W rurce o promieniu r menisk tworzy różnicę ciśnień na zakrzywionej powierzchni (równanie Younga-Laplace'a). Dla sferycznego menisku w okrągłej rurce ta różnica ciśnień podtrzymuje słup cieczy o wysokości h:

Ciśnienie Younga-Laplace'a na zakrzywionej granicy:
  ΔP = 2γ / R_c
  gdzie R_c = r / cos θ   (promień krzywizny menisku w rurce)

Równowaga ciśnień (ciśnienie kapilarne = ciśnienie hydrostatyczne):
  2γ cos θ / r = ρ g h

Prawo Jurina:
  h = 2γ cos θ / (ρ g r)

Przykład — woda w szkle (r = 0,5 mm):
  γ = 0,073 N/m, θ = 20°, ρ = 1000 kg/m³, g = 9,81 m/s²
  h = 2 × 0,073 × cos(20°) / (1000 × 9,81 × 0,0005) ≈ 28 mm

Symulacja renderuje obok siebie rurki o różnych promieniach z animowanym wznoszeniem cieczy. Kształt menisku rysowany jest jako łuk kołowy o krzywiźnie 1/Rc. Bieżący wykres h vs 1/r potwierdza liniową zależność przewidywaną przez prawo Jurina. Dla rtęci kąt zwilżania θ > 90° daje cosθ < 0, więc h jest ujemne — rtęć jest wciśnięta poniżej poziomu zbiornika.

Zależność napięcia powierzchniowego od temperatury

Napięcie powierzchniowe maleje w przybliżeniu liniowo wraz z temperaturą dla większości cieczy. Dla wody γ(T) można przybliżyć regułą Eötvösa i jest stabelaryzowane od 0°C (0,0756 N/m) do 100°C (0,0589 N/m). Suwak temperatury symulacji reguluje γ wykorzystując rzeczywiste dane wody i przelicza wysokość wznoszenia we wszystkich rurkach jednocześnie, pokazując, że podgrzana woda wznosi się niżej — istotne dla zjawisk kapilarnych podczas wrzenia i w mikroprzepływach.

🗺️ Przeszukiwanie ścieżek A* — heurystyki, optymalność i zbiór otwarty

Algorytm A*

A* (Hart, Nilsson, Raphael, 1968) przeszukuje graf ważony w poszukiwaniu najkrótszej ścieżki ze startu s do celu g, oceniając każdy węzeł n estymatą kosztu f(n) = g(n) + h(n):

f(n) = g(n) + h(n)

  g(n) = dokładny koszt najkrótszej znalezionej dotąd ścieżki z s do n
  h(n) = heurystyczna estymata kosztu z n do celu g

A* utrzymuje dwa zbiory:
  Zbiór otwarty:   węzły odkryte, ale jeszcze nie rozwinięte (kopiec min wg wartości f)
  Zbiór zamknięty: węzły już rozwinięte

Główna pętla:
  dopóki zbiór otwarty nie jest pusty:
    n = węzeł w zbiorze otwartym o najniższym f(n)   // O(log N) z kopcem binarnym
    jeśli n == cel: zwróć ścieżkę
    dodaj n do zbioru zamkniętego
    dla każdego sąsiada m węzła n:
      tentative_g = g(n) + edge_cost(n, m)
      jeśli m w zbiorze zamkniętym i tentative_g ≥ g(m): kontynuuj
      jeśli tentative_g < g(m):
        g(m) = tentative_g
        f(m) = g(m) + h(m)
        parent(m) = n
        dodaj m do zbioru otwartego (lub zmniejsz klucz, jeśli już obecny)

Dopuszczalność heurystyki i optymalność

A* gwarantowanie znajduje optymalną ścieżkę wtedy i tylko wtedy, gdy heurystyka h(n) jest dopuszczalna: nigdy nie zawyża prawdziwego kosztu osiągnięcia celu. Trzy zaimplementowane heurystyki to:

Współrzędne siatki (x, y) dla komórki, cel w (gx, gy):

Odległość Manhattan (norma L1):
  h(n) = |x − gx| + |y − gy|
  Dopuszczalna dla siatek 4-połączonych (bez ruchu diagonalnego)
  Niedopuszczalna dla siatek 8-połączonych (zaniża skróty diagonalne)

Odległość euklidesowa (norma L2):
  h(n) = √((x − gx)² + (y − gy)²)
  Dopuszczalna dla dowolnego ruchu; zwykle rozwija mniej węzłów niż Manhattan
  na siatkach 8-połączonych, ale wymaga porównań zmiennoprzecinkowych

Odległość diagonalna (Czebyszewa):
  h(n) = max(|x − gx|, |y − gy|)
  Dopuszczalna dla siatek 8-połączonych z jednostkowym kosztem diagonalnym
  Dokładna dla jednolitego kosztu ruchu diagonalnego; rozwija najmniej węzłów

Porównanie z Dijkstrą i zachłannym best-first

Panel porównania algorytmów uruchamia wszystkie trzy algorytmy jednocześnie w tym samym labiryncie i wyświetla liczby ekspansji węzłów obok siebie:

Implementacja kopca binarnego utrzymuje każdą iterację na poziomie O(log N), gdzie N to rozmiar zbioru otwartego, czyniąc A* praktycznym na siatkach do 500×500 (250 000 węzłów) przy prędkościach interaktywnych. Licznik ekspansji węzłów aktualizuje się na żywo w każdej klatce animacji krok po kroku.

✏️ Krzywe parametryczne — Bézier, B-spliny i NURBS

Krzywe Béziera i konstrukcja de Casteljau

Krzywa Béziera stopnia n jest definiowana przez n+1 punktów kontrolnych P0, …, Pn i parametryzowana przez t ∈ [0, 1]. Algorytm de Casteljau oblicza dowolny punkt na krzywej poprzez powtarzaną interpolację liniową:

Algorytm de Casteljau:
  P_i^(0) = Pᵢ             (inicjalizacja punktami kontrolnymi)
  P_i^(r) = (1−t) · P_i^(r−1) + t · P_{i+1}^(r−1)   dla r = 1, …, n

  Punkt krzywej przy parametrze t: B(t) = P_0^(n)

Reprezentacja w bazie Bernsteina (równoważna):
  B(t) = Σᵢ₌₀ⁿ  C(n,i) · tⁱ · (1−t)^(n−i) · Pᵢ
  gdzie C(n,i) = n! / (i! (n−i)!)  (współczynnik dwumianowy)

Stopień 3 (sześcienny) Bézier — najczęstszy:
  B(t) = (1−t)³P₀ + 3t(1−t)²P₁ + 3t²(1−t)P₂ + t³P₃

Symulacja animuje konstrukcję de Casteljau klatka po klatce, gdy t przemiata 0→1: każdy pośredni segment interpolacji rysowany jest w coraz jaśniejszym kolorze, a punkt końcowy kreśli krzywą. Przeciąganie punktów kontrolnych aktualizuje animację w czasie rzeczywistym.

B-spliny i rekurencja Coxa-de Boora

B-spliny uogólniają krzywe Béziera z kontrolą lokalną: przesunięcie jednego punktu kontrolnego wpływa na krzywą jedynie w lokalnym sąsiedztwie, a nie na całą krzywą. Są definiowane przez wektor węzłów T = {t0, …, tm} i funkcje bazowe Ni,k(t) obliczane rekurencją Coxa-de Boora:

Rekurencja Coxa-de Boora:
  N_{i,0}(t) = 1  jeśli tᵢ ≤ t < t_{i+1},  w przeciwnym razie 0
  N_{i,k}(t) = (t − tᵢ)/(t_{i+k} − tᵢ) · N_{i,k−1}(t)
             + (t_{i+k+1} − t)/(t_{i+k+1} − t_{i+1}) · N_{i+1,k−1}(t)

Krzywa B-spline stopnia k z n+1 punktami kontrolnymi:
  C(t) = Σᵢ₌₀ⁿ  N_{i,k}(t) · Pᵢ

Właściwości:
  Nośnik lokalny: N_{i,k}(t) ≠ 0 tylko na [tᵢ, t_{i+k+1}]
  Rozkład jedności: Σᵢ N_{i,k}(t) = 1 dla wszystkich t
  Ciągłość C^(k−1) wszędzie (C^(k−2) przy powtórzonych węzłach)

Edytor wektora węzłów pozwala przeciągać poszczególne wartości węzłów lub wstawiać/usuwać węzły. Powtórzone węzły lokalnie zmniejszają ciągłość — węzeł powtórzony k razy tworzy narożnik przy tej wartości parametru, przydatne dla ostrzy i ostrych cech. Symulacja koduje kolorystycznie każdą funkcję bazową Ni,k(t) osobno i wykreśla je wszystkie w pasku poniżej głównego płótna.

NURBS i dokładny okrąg

Niejednorodne wymierne B-spliny (NURBS) dodają wagę wi do każdego punktu kontrolnego, umożliwiając dokładną reprezentację stożkowych — w tym okręgów i łuków — których splajny wielomianowe mogą jedynie przybliżać:

Krzywa NURBS:
  C(t) = Σᵢ N_{i,k}(t) · wᵢ · Pᵢ
         ─────────────────────────
         Σᵢ N_{i,k}(t) · wᵢ

Dokładna ćwiartka okręgu z 3 punktami kontrolnymi (stopień 2):
  P₀ = (1, 0),  w₀ = 1
  P₁ = (1, 1),  w₁ = √2/2 ≈ 0,7071   (waga punktu pośredniego)
  P₂ = (0, 1),  w₂ = 1

  Wektor węzłów: [0, 0, 0, 1, 1, 1]

Pełny okrąg: 9 punktów kontrolnych (trzy ćwiartki-łuki połączone ciągłością C¹)
             Wagi naprzemiennie 1 i √2/2

Panel NURBS pokazuje wielobok kontrolny z suwakami wag dla każdego punktu. Zmniejszenie wagi poniżej 1 odciąga krzywą od tego punktu kontrolnego; zwiększenie powyżej 1 przyciąga krzywą do niego. Dokładny okrąg jest domyślnym przykładem NURBS — zmiana wagi centralnej z √2/2 na 1 deformuje go w parabolę, demonstrując rolę wag.

🌀 Wiązka wirowa — mody Laguerre'a-Gaussa i orbitalny moment pędu

Mody wiązki Laguerre'a-Gaussa

Mody Laguerre'a-Gaussa (LG) są dokładnymi rozwiązaniami paraksjalnego równania falowego we współrzędnych cylindrycznych (ρ, φ, z). Tworzą ortogonalną bazę dla wiązek o symetrii rotacyjnej. Wiązka LG o indeksie radialnym p i indeksie azymutalnym ℓ ma amplitudę pola elektrycznego:

LG_{p,ℓ}(ρ, φ, z):

  u(ρ, φ, z) = C_{p,ℓ} · (ρ√2/w(z))^|ℓ| · L_p^|ℓ|(2ρ²/w²(z))
              · exp(−ρ²/w²(z))                     ← obwiednia gaussowska
              · exp(i ℓ φ)                          ← spiralna faza
              · exp(−i k ρ²/(2R(z)))               ← krzywizna czoła fali
              · exp(i (2p+|ℓ|+1) ζ(z))            ← faza Gouya

gdzie:
  w(z)  = przewężenie wiązki w pozycji z: w(z) = w₀√(1 + (z/z_R)²)
  R(z)  = promień krzywizny: R(z) = z(1 + (z_R/z)²)
  ζ(z)  = faza Gouya: arctan(z/z_R)
  z_R   = zasięg Rayleigha: πw₀²/λ
  L_p^|ℓ| = uogólniony wielomian Laguerre'a

Spiralna faza i orbitalny moment pędu

Azymutalny czynnik fazowy exp(iℓφ) nawija fazę o 2πℓ radianów wokół jednego pełnego obrotu w φ. To spiralne czoło fazy oznacza, że wiązka niesie orbitalny moment pędu (OAM) ℓℏ na foton — odrębny od spinowego momentu pędu ±ℏ światła spolaryzowanego kołowo:

OAM na foton: L_z = ℓ ħ

Profil natężenia: I ∝ |u|² ∝ ρ^(2|ℓ|) · [L_p^|ℓ|(…)]² · exp(−2ρ²/w²)

Dla p = 0 (bez węzłów radialnych):
  Pojedynczy jasny pierścień („pączek”) przy ρ_max = w(z) · √(|ℓ|/2)
  Ciemny rdzeń (osobliwość fazy) przy ρ = 0

Dla p > 0:
  p koncentrycznych ciemnych pierścieni wewnątrz zewnętrznego pierścienia
  Łącznie p+1 jasnych pierścieni

Ładunek topologiczny ℓ:
  |ℓ| = liczba nawinięć fazy 2π na obwód azymutalny
  Znak determinuje skrętność (zgodnie z ruchem wskazówek zegara vs przeciwnie)

Symulacja renderuje profil natężenia 2D jako mapę cieplną i nakłada mapę fazy jako koło kolorów w dowolnie wybranej płaszczyźnie z. Panel interferencji pokazuje charakterystyczne wzory spiralne (pojedyncza szczelina) lub widlaste (podwójna szczelina) używane w laboratorium do pomiaru ładunku topologicznego ℓ. Gdy wiązka LG interferuje z falą płaską, wynikowy wzór ma |ℓ| dodatkowych lub brakujących prążków w punkcie rozwidlenia.

🧪 Koloidy — teoria DLVO i stabilność koloidalna

Ruch Browna i równanie Stokesa-Einsteina

Cząstka koloidalna (promień r, 1 nm–1 μm) zawieszona w płynie podlega ruchowi Browna, ponieważ fluktuacje termiczne nieustannie ją popychają. Współczynnik dyfuzji D wiąże średnie kwadratowe przemieszczenie z czasem i jest podany równaniem Stokesa-Einsteina:

Równanie Stokesa-Einsteina:
  D = k_B T / (6π η r)

gdzie:
  k_B = 1,38 × 10⁻²³ J/K  (stała Boltzmanna)
  T   = temperatura (K)
  η   = lepkość dynamiczna rozpuszczalnika (Pa·s)
  r   = promień cząstki (m)

Relacja Einsteina (dyfuzja–ruchliwość):
  D = μ k_B T   gdzie μ = ruchliwość = 1/(6π η r)

Średnie kwadratowe przemieszczenie:
  ⟨r²⟩ = 6 D t   (ruch Browna 3D)
  ⟨r²⟩ = 4 D t   (2D)

Przykład — cząstka 100 nm w wodzie przy 25°C:
  D = (1,38×10⁻²³ × 298) / (6π × 8,9×10⁻⁴ × 50×10⁻⁹) ≈ 4,9 × 10⁻¹² m²/s

Teoria DLVO: stabilność i flokulacja

Teoria DLVO (Derjaguin, Landau, Verwey, Overbeek) opisuje całkowity potencjał oddziaływania między dwiema naładowanymi cząstkami koloidalnymi jako sumę odpychania elektrostatycznego i przyciągania van der Waalsa:

Całkowity potencjał DLVO:
  V_total(h) = V_EDL(h) + V_vdW(h)

Odpychanie podwójnej warstwy elektrostatycznej (zlinearyzowany Poisson-Boltzmann):
  V_EDL(h) = 64π ε ε₀ r (k_B T / ze)² tanh²(zeψ₀/4k_BT) · exp(−κh)

  κ = długość ekranowania Debye'a-Hückela:
  κ⁻¹ = √(ε ε₀ k_B T / (2 N_A e² I))
  I = siła jonowa = ½ Σ cᵢ zᵢ²

Przyciąganie van der Waalsa (Hamaker):
  V_vdW(h) = −A_H / (12π h²) · f(r, h)
  A_H = stała Hamakera (typowa wartość ~10⁻²⁰ J dla tlenek/woda/tlenek)

Bariera stabilności:
  Jeśli V_max > ~15 k_B T: koloid stabilny (kinetycznie zahamowana flokulacja)
  Jeśli V_max < ~5 k_B T:  szybka koagulacja (szybka agregacja Smoluchowskiego)
  Dodanie soli ściska długość Debye'a → obniża barierę → flokulacja

Suwak siły jonowej ściska długość Debye'a κ−1 z ~100 nm (niska sól) do ~1 nm (fizjologiczna), zmniejszając barierę energetyczną Vmax i wyzwalając flokulację. Symulacja wizualizuje to jako bieżącą krzywą V(h) z wysokością bariery opisaną w jednostkach kBT. Gdy bariera spadnie poniżej ~5kBT, cząstki zaczynają się agregować na płótnie, a histogram rozkładu wielkości agregatów aktualizuje się w czasie rzeczywistym.

Sedymentacja

Cząstki większe niż ~1 μm osadzają się pod wpływem grawitacji. Prędkość sedymentacji dla kuli w reżimie Stokesa wynosi:

Prędkość sedymentacji Stokesa:
  v_s = 2r²(ρ_p − ρ_f) g / (9η)

Liczba Pécleta (adwekcja vs dyfuzja):
  Pe = v_s · r / D = v_s · 6π η r² / (k_B T)

Pe < 1: dominuje dyfuzja → stabilna zawiesina
Pe > 1: dominuje sedymentacja → osiadanie grawitacyjne

Przykład — kula krzemionkowa 1 μm w wodzie:
  ρ_p = 2200 kg/m³, ρ_f = 1000 kg/m³
  v_s = 2 × (500×10⁻⁹)² × 1200 × 9,81 / (9 × 8,9×10⁻⁴) ≈ 0,73 μm/s
  D = 4,9×10⁻¹³ m²/s  →  Pe ≈ 1,5 (na granicy)

Symulacja koloruje cząstki wg rozmiaru ich bieżącego klastra agregatowego (pojedyncza = niebieska, dimer = zielony, …, duży klaster = czerwony) i nakłada wektory prędkości osiadania dla cząstek, gdzie Pe > 1.

🌐 Trasowanie internetowe — wektor odległości, link-state i BGP

Trasowanie wektorem odległości Bellmana-Forda

Protokoły wektora odległości (np. RIP) sprawiają, że każdy router okresowo rozgłasza całą swoją tabelę trasowania bezpośrednim sąsiadom. Każdy router aktualizuje własną tabelę, korzystając z rekurencji Bellmana-Forda:

Rekurencja Bellmana-Forda:
  d_x(y) = min po wszystkich sąsiadach v z { c(x,v) + d_v(y) }

  d_x(y) = szacowany koszt z routera x do celu y
  c(x,v) = koszt bezpośredniego łącza x → v
  d_v(y) = ogłoszony koszt sąsiada v do y

Reguła aktualizacji (gdy x otrzymuje aktualizację od sąsiada v):
  dla każdego celu y:
    jeśli c(x,v) + d_v(y) < d_x(y):
      d_x(y) = c(x,v) + d_v(y)
      next_hop_x(y) = v    // aktualizacja tabeli trasowania

Zbieżność: O(średnica) rund aktualizacji dla poprawnej topologii

Problem zliczania do nieskończoności

Gdy łącze ulega awarii, protokoły wektora odległości mogą wpaść w patologiczną pętlę, w której dwa routery na przemian zwiększają ogłaszany koszt do celu, odbijając się między sobą, aż odległość „liczy do nieskończoności” (zazwyczaj ograniczonej do 16 w RIP):

Topologia: A — B — C  (łącze B-C ulega awarii; pozostaje tylko łącze A-B)

Przed awarią: d_B(C) = 1, d_A(C) = 2
Po awarii:
  B zauważa, że łącze B-C nie działa; d_B(C) = ∞
  Ale tabela B nadal pokazuje d_A(C) = 2 (nieaktualne)
  B aktualizuje: d_B(C) = 1 + d_A(C) = 3  (błędnie! przez A, ale A trasuje przez B)
  A aktualizuje: d_A(C) = 1 + d_B(C) = 4
  B aktualizuje: d_B(C) = 5 … i tak dalej aż do ∞

Naprawa — Split Horizon:
  Router A nigdy nie ogłasza B trasy, której nauczył się od B
  → ogłoszenie A dla C (poznane przez B) jest tłumione wobec B
  → B poprawnie uczy się d_B(C) = ∞ po awarii łącza

Naprawa — Poison Reverse:
  Bardziej agresywnie: A jawnie ogłasza d_A(C) = ∞ z powrotem do B
  Eliminuje zliczanie do nieskończoności dla pętli dwuwęzłowych natychmiast

Symulacja pozwala wywołać awarię łącza, klikając dowolną krawędź, a następnie przejść krok po kroku przez rundy aktualizacji Bellmana-Forda. Przy wyłączonym split horizon pętla zliczania do nieskończoności jest wyraźnie widoczna w tabelach routerów. Włączenie split horizon pokazuje tę samą awarię rozwiązaną w jednej rundzie.

Dijkstra link-state (OSPF) i ponowna zbieżność

Protokoły link-state (OSPF, IS-IS) przyjmują fundamentalnie inne podejście: każdy router zalewa całą sieć swoim lokalnym ogłoszeniem stanu łącza (LSA), więc wszystkie routery budują identyczną mapę topologii. Każdy router uruchamia następnie lokalnie Dijkstrę, aby obliczyć najkrótsze ścieżki:

Zalewanie Link-State:
  Każdy router generuje LSA: {ID routera, [sąsiad, koszt, ...]}
  LSA jest zalewane do wszystkich routerów w obszarze (numery sekwencyjne zapobiegają pętlom)
  Wszystkie routery budują identyczną bazę danych stanu łącza (LSDB)

Dijkstra na LSDB (dla każdego routera):
  Identyczna z Dijkstrą, z samym routerem jako źródłem
  Wynik: pełne drzewo najkrótszych ścieżek do wszystkich celów
  Zainstalowane w tabeli trasowania jako wpisy przekazywania

Ponowna zbieżność po awarii łącza:
  Uszkodzony router/łącze generuje nowe LSA z nieskończonym kosztem
  Zalewa sieć → wszystkie routery aktualizują LSDB → ponownie uruchamiają Dijkstrę
  Zbieżność w O(E log V) na router wobec O(średnica) rund dla BF

BGP (Border Gateway Protocol):
  Protokół path-vector: ogłasza pełną ścieżkę AS, nie tylko odległość
  Eliminuje pętle trasowania: odrzuca aktualizacje zawierające własny AS na ścieżce
  Oparty na polityce: operatorzy kontrolują, które trasy są akceptowane/preferowane

Animacja ponownej zbieżności pokazuje propagację fali zalewu LSA jako falę na diagramie sieci, a następnie podświetla każdy router ponownie uruchamiający Dijkstrę, gdy dociera do niego fala. Tabele routerów aktualizują się wizualnie w panelu po prawej. Zakładka BGP demonstruje mechanizm path-vector na uproszczonej topologii trzech AS, pokazując, jak atrybut AS-path zapobiega problemowi zliczania do nieskończoności, który nęka protokoły wektora odległości.

Co dalej

Fala 66 jest w przygotowaniu z sześcioma kolejnymi symulacjami: epicyklami Fouriera animującymi dowolną krzywą zamkniętą jako sumę obracających się okręgów, wahadłem magnetycznym z fraktalnymi basenami przyciągania, zwilżaniem powierzchni i histerezą kąta zwilżania, kinematyką przekładni zębatych, problemem plecakowym 0/1 rozwiązywanym programowaniem dynamicznym oraz kodowaniem Huffmana z granicami entropii. Biblioteka zbliża się do 600 symulacji.

← Devlog #85: Fala 64 Devlog #87: Fala 66 →