tdt4120

Forelesning 22. oktober Kortest vei fra én til alle

Pensum

Læringsmål


  1. Dekomponering
  2. DAG-Shortest-Path
  3. Kantslakking
  4. Bellman-Ford
  5. Djikstras algoritme

1:5 Dekomponering

Vi begynner med å anta en asyklisk graf. Vi ser at vi kan la grafen være sin egen delinstansgraf.

Vil finne avstand $\delta(s, t)$ fra startnoden $s$. Vi antar så induktivt at vi har funnet $\delta(s, -)$ for inn-naboer. Inn-nabo $x$ gir mulig stilengde $\delta(s, x) + w(x, t)$; velg minium!

Vi får altså at $\delta(s, t) = min\{\delta(s, u) + w(u, t), \delta(s, v) + w(v, t)\}$

Video startet;

Dekomponeringen fungerer bare for asykliske grafer!

2:5 DAG-Shortest-Path

topologically sort G
initialize_single_source(G, s)
for each vertex v in V
  for each edge (u, v) in E
    relax(u, v, w)
  end
end

function initialize_single_source(G, s)
  for each vertex v in V
    v.d = Inf
    v.pi = nothing
  end
  s.d = 0
end

function relax(u, v, w)
  if v.d > u.d + w(u, v)
    v.d = u.d + w(u, v)
    v.pi = u
  end
end

Vil heller bruker ut kanter enn inn kanter.

Hvis vi skiller ut init, kanv i kjøre minium

Så lenge u.d er rett, kan vi trygt utføre linje 8 og 9 (de siste to linjene)

Med andre ord, nå kan vi bruke ut-kanter også!

Dette kalles reaching, istedenfor pulling. Som i vanlig DP, husk valg som tas. Dette gjøres vha. en forgjenger ($\pi$)!

Flytter init og min til en egen funksjon, refaktor!

function dag_shortest_path(G, w, s)
  topologically sort the vertices of G
  initialize-single-source(G, s)
  for each vertex u, in topsort order
    for each vertex v in G.adj[u]
      relax(u, v, w)
    end
  end
end

NB! Sykler fungerer ikke med denne modellen

Operasjon Antall Kjøretid
Topologisk-sortering 1 $\Theta(V + E)$
Initialisering 1 $\Theta(V)$
RELAX E $\Theta(1)$

Kantslakking er altså en oppspalting av miniums-operasjoner fra dekomponeringen. Vi har foreløpig ikke vært så kreative med hvordan vi har brukt det - la oss studere teknikken i litt mer detalj.


3:5 Kantslakking

Kantslakking; problematisk når vi har flere strukne kanter i en sti.

Sti-slakkings-egenskapen

Om p er en kortest vei fra s til v og vi slakker kantene til p i rekkefølge, så vil v få riktig avstandsestimat. Det gjelder uavhengig av om andre slakkinger forekommer, selv om de kommer innimellom. Se side 650 for flere slektninger av denne egenskapen.


La $\langle v_1, v_2, \ldots , v_k\rangle$ være korteste vei til $z$. Vi vil slakke kantene langs stien, men kjenner ikke rekkefølgen.

Løsning: Slakk absolutt alle kanter $k - 1$ ganger!


Hvis vi lar $k = |V|$ så får alle noder rett estimat


4:5 Bellman-ford

function bellman_ford(G, w, s)
  initialize_single_source(G, s)
  for i = 1 to |G.V| - 1
    for each edge (u, v) in G.E
      relax(u, v w)
    end
  end
  for each edge (u, v) in G.E
    if v.d > u.d + w(u, v)
      return false
    end
  end
  return true
Operasjon Antall Kjøretid
Initialisering 1 $\Theta(V)$
RELAX $V - 1$ $\Theta(E)$
RELAX $O(V)$ $\Theta(E)$

Totalt: O(VE)


Om et estimat endres, så var tidligere slakking fra noden bortkastet.

Konklusjon: Slakk kanter fra v når v.d ikke kan forbedres.


Strategi 1 av 2:

Slakk kanter ut fra noder i topologisk sortert rekkefølge

Hvorfor blir det rett?

Når alle inn-kanter er slakket kan ikke noden forbedres og trygt velges som neste.


Hva om vi vil ha sykler?


Strategi 2 av 2:

Velg den gjenværende med lavest estimat.

Hvorfor blir dette rett?

Gjenværende noder kan kun forbedres ved slakking fra andre gjenværende. Det laveste estimatet kan dermed ikke forbedres.


5:5 Dijkstras algoritme

function dijkstra(G, w, s)
  initialize_single_source(G, s)
  S = []
  Q. = G.V #Queue
  while Q != empty
    u = extract_min(Q) # Korteste stien til start
    push!(S, u)
    for each vertex v in G.adj[u]
      relax(u, v, w)
    end
  end
end
Operasjon Antall Kjøretid
Initialisering 1 $\Theta(V)$
BUILD-HEAP 1 $\Theta(V)$
EXTRACT-MIN $V$ $O(lg V)$
DECREASE-KEY $E$ $O(lg V)$

Total: O(V lg V + E lg V)

Med binærheap: bedre enn lineært søk for $E = o(V^2/lg V)$

Med Fibonacci-heap: DECREASE-KEY er $O(1)$: vi får $O(V lg V + E)$