4.4 Alle-til-alle korteste vei
`Floyd-Warshall` (`d`- og `π`-regel), `Slow-APSP` (min-pluss-produkt) og `Transitive-Closure` — matrisebaserte APSP-algoritmer.
(65 %). Grunnlaget er de 17 settene fra august 2015 til august 2023 som er
gjennomgått tema for tema — det er nevneren hver gang boka oppgir en prosent.
Prioritet: kjenne til. Men temaet differensierer i toppen, og det er verdt
å merke seg hvorfor: håndkjøringen er helt mekanisk, og den som har regnet
gjennom to runder på forhånd, får poengene på fem minutter.
To sjangre henter fra kapitlet:
- Sjanger C — håndkjøring, altså at du utfører algoritmen steg for steg og
oppgir bare det etterspurte. Her er det en matrise som etterspørres, og
ofte bare for én bestemt runde k eller én bestemt celle.
- Sjanger E — kjøretidskunnskap, altså at du oppgir kjøretiden i det
strammeste uttrykket som er riktig. for Floyd-Warshall er et
av de tallene som skal kunne skrives ned kaldt.
De to fellene som koster mest i dette kapitlet:
1. Å bruke vanlig matriseprodukt i Slow-APSP. Produktet der er
min-pluss: du tar minimum av summer, ikke summen av produkter.
2. Å blande d-regelen og π-regelen i Floyd-Warshall. De oppdateres
samtidig, men etter forskjellige regler — og π-regelen arver fra rad
k, ikke fra rad i.
Slik er kapitlet lagt opp (50 min):
| Innhold | Tid |
|---|---|
| Hvorfor et eget alle-til-alle-problem | ca. 7 min |
Floyd-Warshall: d-regelen og π-regelen | ca. 20 min |
Slow-APSP og min-pluss-produktet | ca. 14 min |
Transitive-Closure og utskrift av stien | ca. 9 min |
Forkunnskaper
- kap. 4.3 — korteste vei fra én kilde. Dette sto der:
Dijkstra er og krever ikke-negative kantvekter;
Bellman-Ford er , tåler negative kanter og oppdager negative
sykler. Begge bygger på slakking: hvis , er den
nye veien bedre, og og oppdateres.
- kap. 4.1 — grafrepresentasjon. Vi bruker
nabomatrisen her, ikke nabolister: algoritmene i dette kapitlet arbeider
direkte på en -matrise.
- kap. 1.1 — de asymptotiske symbolene.
Ett nytt begrep innføres underveis: mellomnode. Det er den eneste ideen du
trenger utover kap. 4.3.
Hvorfor et eget alle-til-alle-problem (~7 min)
En rutetjeneste skal vise reisetiden mellom alle par av holdeplasser, ikke
bare fra én. Den enkle løsningen er å kjøre Dijkstra én gang per node:
kjøringer à , altså .
For en glissen graf, der er omtrent like stor som , er det et godt
valg. For en tett graf, der nærmer seg , blir det —
og da finnes noe bedre. Floyd-Warshall gjør jobben i , uten
logaritmefaktor og uten prioritetskø.
Og det finnes en grunn til: Dijkstra krever ikke-negative kantvekter. Har
grafen negative kanter, må du bruke Bellman-Ford per node, og det koster
. Floyd-Warshall tåler negative kanter uten videre.
problemet med å finne den korteste avstanden mellom hvert par av noder i en
graf, ikke bare fra én bestemt kilde.
Svaret er en -matrise d med avstander, og gjerne en tilsvarende
matrise π med forgjengere, slik at selve stiene kan hentes ut.
Løsningen er ikke automatisk «kjør én-kilde-algoritmen ganger». For
tette grafer og for grafer med negative kanter finnes bedre alternativer, og
valget mellom dem er en fast eksamensoppgave.
en node som ligger inni en sti — altså verken start- eller endepunkt.
I stien er mellomnodene 2 og 3.
Hele Floyd-Warshall bygger på dette begrepet: algoritmen utvider trinn
for trinn hvilke noder som får lov til å opptre som mellomnoder, fra ingen til
alle.
Floyd-Warshall: d-regelen og π-regelen (~20 min)
Ideen er å stille ett spørsmål av gangen: hvor korte blir stiene hvis bare
node 1 får være mellomnode? Så: hvis bare node 1 og 2 får det? Og så videre,
til alle nodene er tillatt.
La være den korteste avstanden fra til når bare nodene
er tillatt som mellomnoder. Da er selve
vektmatrisen — ingen mellomnoder er tillatt, så bare direkte kanter teller — og
er svaret.
Overgangen fra til er ett enkelt valg: enten går den korteste stien
gjennom node , eller så gjør den det ikke.
W[1..n][1..n] med W[i][i] = 0, W[i][j] = w(i,j) når kanten finnes, ogINF ellers. Nodene er nummerert 1 til . Negative kantvekter ertillatt; negative sykler er ikke.
Prebetingelse: grafen har ingen negativ sykel.
Postbetingelse: d[i][j] er den korteste avstanden fra i til j, ogpi[i][j] er forgjengeren til j på en korteste sti fra i.
Floyd-Warshall(W)
Input: vektmatrisen W[1..n][1..n]
Output: avstandsmatrisen d og forgjengermatrisen pi
d = W
for i = 1 to n
for j = 1 to n
if i != j and W[i][j] < INF
pi[i][j] = i
else
pi[i][j] = NIL
for k = 1 to n
for i = 1 to n
for j = 1 to n
if d[i][k] + d[k][j] < d[i][j]
d[i][j] = d[i][k] + d[k][j]
pi[i][j] = pi[k][j]
return d, pi
Kjoeretid: Theta(V^3)Invarianten i én setning: etter runde k inneholder d[i][j] den korteste
avstanden fra i til j blant alle stier som bare bruker nodene 1 til k
som mellomnoder.
d-regelen og π-regelen er ikke den samme regelen. d tar minimum av
den gamle verdien og veien om k. π beholder den gamle forgjengeren så lenge
den gamle veien er minst like kort — og arver pi[k][j] når veien om k
vinner. Legg merke til at den arvede verdien hentes fra rad k, ikke fra
rad i: den siste kanten inn til j er den samme som på den korteste stien
fra k til j.
Kjøretid: tre nøstede løkker over , med konstant arbeid innerst,
altså . Grensen er tett: løkkene kjører alltid ferdig, uansett
graf.
Rekkefølgen på løkkene er ikke likegyldig. k må være den ytterste.
Bytter du om, brytes invarianten, og resultatet blir galt.
Et internt transportnett har fire terminaler nummerert 1 til 4, med disse
enveis-strekningene og kjøretidene:
(3), (7), (8), (2), (1),
(2).
a) Skriv opp vektmatrisen og den tilhørende .
b) Utfør runden med .
c) Utfør runden med , og oppgi begge matrisene.
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| 1 | 0 | 3 | 7 | |
| 2 | 8 | 0 | 2 | |
| 3 | 0 | 1 | ||
| 4 | 2 | 0 |
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| 1 | NIL | 1 | NIL | 1 |
| 2 | 2 | NIL | 2 | NIL |
| 3 | NIL | NIL | NIL | 3 |
| 4 | 4 | NIL | NIL | NIL |
I står
i selv som forgjenger overalt der det finnes en direktekant — den korteste kjente stien fra
i til j er da kanten, og forgjengerentil
j er i.b) Med ser vi etter stier som er kortere enn det vi
har. To celler forbedres:
- : veien koster , mot før.
Forgjengeren arves fra rad 1: .
- : veien koster , mot før.
.
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| 1 | 0 | 3 | 7 | |
| 2 | 8 | 0 | 2 | 15 |
| 3 | 0 | 1 | ||
| 4 | 2 | 5 | 0 |
c) Med ser vi etter stier . To celler forbedres:
- : veien koster , mot før.
.
- : veien koster , mot før.
.
Sluttilstanden — det du ville levert på eksamen:
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| 1 | 0 | 3 | 5 | 7 |
| 2 | 8 | 0 | 2 | 15 |
| 3 | 0 | 1 | ||
| 4 | 2 | 5 | 7 | 0 |
| 1 | 2 | 3 | 4 | |
|---|---|---|---|---|
| 1 | NIL | 1 | 2 | 1 |
| 2 | 2 | NIL | 2 | 1 |
| 3 | NIL | NIL | NIL | 3 |
| 4 | 4 | 1 | 2 | NIL |
Legg merke til tre ting.
Alle cellene som ikke nevnes, står uendret fra forrige runde — i begge
matrisene. En vanlig feil er å regne om hele matrisen fra grunnen av.
Forgjengeren arves fra rad
k, ikke fra rad i. Ved hentet vi, ikke .
Rad 3 er uendret gjennom begge rundene. Node 3 har bare én utgående kant, til
node 4, og hverken node 1 eller 2 kan nås derfra på to runder.
Fellen her er å blande d-regelen og π-regelen. d tar et minimum;π gjør et valg mellom to forgjengere, og valget følger utfallet av
minimumet.
(Innstegsoppgave, sjanger D — definisjon med egne ord, altså én presis setning
med hovedpoenget først.)
Hva betyr i Floyd-Warshall, og hva er ?
Bruk grafen fra Eksempel 1, og fortsett fra .
Utfør runden med , og oppgi bare de cellene i som endrer seg,
med de nye verdiene og de nye forgjengerne.
Ta stilling til hver av påstandene om Floyd-Warshall:
a) Løkkene kan kjøres i hvilken som helst rekkefølge, siden alle tre går
over alle nodene.
b) Algoritmen krever ikke-negative kantvekter.
c) Kjøretiden er uansett hvor mange kanter grafen har.
Slow-APSP og min-pluss-produktet (~14 min)
Det finnes en helt annen vei til det samme svaret, og den er verdt å kunne
fordi den kommer som en egen håndkjøringsoppgave: å bygge stiene opp kant for
kant i stedet for mellomnode for mellomnode.
La være den korteste avstanden fra til blant stier med
høyst kanter. Da er , og skrittet videre er å legge til én
kant til.
Den ser ut som et matriseprodukt, men med minimum der produktet har sum, og
pluss der det har gange.
Dette er kapitlets viktigste felle. Vanlig matriseprodukt ville vært
— sum av produkter. Her er det minimum av summer, og
et svar regnet ut med vanlig produkt er fullstendig meningsløst i
grafsammenheng.
W[1..n][1..n] som over.L er en matrise av samme form, med L[i][j] = korteste avstand med høyst etvisst antall kanter.
Prebetingelse: ingen negativ sykel.
Postbetingelse: rutinen returnerer matrisen der hver sti er forlenget med
høyst én kant til.
Slow-APSP(L, W)
Input: matrisene L og W, begge n x n
Output: matrisen L' der stiene er forlenget med hoeyst en kant
la L' vaere en ny n x n matrise
for i = 1 to n
for j = 1 to n
L'[i][j] = INF
for k = 1 to n
L'[i][j] = min(L'[i][j], L[i][k] + W[k][j])
return L'
Kjoeretid: Theta(V^3) per produktInvarianten i én setning: er L korteste avstander med høyst kanter,
er L' korteste avstander med høyst kanter.
Hele APSP-problemet løses ved å gjenta produktet. En korteste sti i en graf
uten negative sykler har høyst kanter, så produkter etter det
første holder — altså naivt. Med gjentatt kvadrering kommer man
ned i , men Floyd-Warshall med sine er
fortsatt bedre.
Kjøretid: for ett produkt, for hele den
naive løsningen.
Bruk den samme grafen som i Eksempel 1, med vektmatrisen .
Regn ut , altså den korteste avstanden fra node 1 til node 3 med
høyst to kanter. Vis alle leddene.
| Summen | |||
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | |||
| 4 |
Svaret: , via , altså stien .
Legg merke til de tre -leddene. Regelen
gjelder, og de bidrar ikke til minimumet. Leddet med er
fordi det ikke finnes noen kant ; leddet med er
fordi det ikke finnes noen kant .
Kontrollen mot vanlig matriseprodukt. Med vanlig produkt ville vi regnet
, altså . Det gir ingen mening som avstand, og det er ikke det oppgaven
spør etter — men det er nøyaktig den feilen som gjøres når man leser
«matriseprodukt» og går på autopilot.
Svarformen på eksamen: ett tall. Ba oppgaven om hele , er det
matrisen. Ba den om én celle, er det tallet og ikke mer.
Bruk grafen fra Eksempel 1.
a) Regn ut , altså korteste avstand fra node 2 til node 4 med
høyst to kanter.
b) Regn ut .
Transitive-Closure og utskrift av stien (~9 min)
Noen ganger er ikke avstanden interessant — bare om det i det hele tatt går an
å komme fra til . Da holder det med sanne og usanne verdier, og
algoritmen blir billigere i praksis fordi den slipper aritmetikk.
den boolske varianten av Floyd-Warshall: er sann hvis det
finnes en vei fra til som bare bruker nodene 1 til som mellomnoder.
Regelen er
— «eller» der d-regelen har «minimum», «og» der den har «pluss».
Kjøretid .
Startmatrisen har sann på diagonalen og der det finnes en kant.
Enhver node når seg selv med null kanter.
skriver ut selve stien fra til ved å lese forgjengermatrisen
baklengs: siste node er , forgjengeren er , og så videre til
du treffer .
Kjøretid per sti — stien kan ikke ha flere enn noder.
Dette er grunnen til at π-matrisen finnes. d gir bare tallet; π gir
veien. Ber en oppgave om stien, er det du skal bruke, ikke .
Bruk fra Eksempel 1.
a) Hvilken sti fra node 4 til node 3 er kodet i matrisen på dette
tidspunktet?
b) Forklar med én setning hvorfor d-matrisen alene ikke er nok til å
svare på a).
En kartleverandør skal regne ut reisetid mellom alle par av steder.
a) Grafen er glissen () og alle vektene er positive. Hvilken
algoritme velger du, og hva blir kjøretiden?
b) Grafen er tett () og noen vekter er negative, men det
finnes ingen negativ sykel. Hvilken velger du, og hva blir kjøretiden?
c) Bare spørsmålet «finnes det en vei?» skal besvares, for alle par.
Hvilken velger du?
De to første koster hele oppgaven.
- Å bruke vanlig matriseprodukt i Slow-APSP. Produktet er
min-pluss: minimum av summer, ikke sum av produkter. Et svar regnet ut
med vanlig produkt er meningsløst som avstand.
- Å blande d-regelen og π-regelen. d tar et minimum; π velger
mellom den gamle forgjengeren og . Og den arvede verdien hentes
fra rad k — ikke fra rad i.
- Å regne om hele matrisen i hver runde. Bare de cellene der veien om k
faktisk er kortere, endrer seg. Alle andre står uendret, i begge matrisene.
- Å bytte om løkkene i Floyd-Warshall. k må være ytterst. Med i eller
j ytterst brytes invarianten, og svaret blir galt.
- Å bruke Dijkstra på en graf med negative kanter. Dette er felle #8.
Floyd-Warshall og Bellman-Ford tåler negative kanter; Dijkstra gjør det
ikke.
- Å oppgi stien fra d-matrisen. d gir lengden, π gir veien. Ber
oppgaven om stien, skal du lese π baklengs.
- Å glemme at . I min-pluss-regningen er det de
endelige leddene som konkurrerer; -leddene er bare med for
fullstendighetens skyld.
Og den gjennomgående: å oppgi mer enn det som er spurt om. Ber oppgaven om
etter én bestemt runde, er det den ene matrisen som er svaret — ikke hele
kjøringen, og ikke i tillegg.
Kjøretidene samlet
Dette er kapitlets puggeflate. Eksamen er hjelpemiddelfri, så tabellen må ligge
i hodet.
| Algoritme | Kjøretid | Krav / egenskap |
|---|---|---|
Floyd-Warshall | tåler negative kanter; ingen negativ sykel; k ytterst | |
Slow-APSP, ett produkt | min-pluss, ikke vanlig matriseprodukt | |
Slow-APSP, hele problemet naivt | produkter etter det første | |
Transitive-Closure | boolsk: «eller» og «og» i stedet for min og pluss | |
Print-All-Pairs-Shortest-Path | per sti | leser π baklengs |
kjøringer av Dijkstra | krever ikke-negative vekter; best på glisne grafer | |
kjøringer av Bellman-Ford | tåler negative kanter, men dyrt |
Én presisering som er verdt å ta med seg.
Floyd-Warshall bryr seg ikke omhvor mange kanter grafen har — kjøretiden er uansett. Det er både
styrken (tette grafer) og svakheten (svært glisne grafer, der kjøringer av
Dijkstra er raskere).Begrepsbank
Begrepsbanken er flashcard- og repetisjonsstoff — den gjentar det du nettopp
har lest. Hopp trygt over ved førstegangslesing; tidsanslaget for kapitlet
gjelder kjernestoffet.
løser alle-til-alle korteste vei ved å prøve hver node etter tur som tillatt
mellomnode, og oppdatere hele avstandsmatrisen for én om gangen.
Kjøretid , uavhengig av antall kanter.
Tåler negative kantvekter, men ikke negative sykler. k må være den
ytterste løkka.
Er veien om node kortere enn den vi hadde, brukes den.
Celler der veien om ikke er kortere, står uendret — de skal ikke regnes
om.
forgjengeren beholdes når den gamle veien er minst like kort, og arves fra
rad når veien om vinner: .
Oppdateres i samme løkke som d, men etter en annen regel.
Fellen er å arve fra rad . Den siste kanten inn til er den samme som
på korteste sti fra til , og det er derfor rad som gjelder.
en node som ligger inni en sti, altså verken start- eller endepunkt.
er avstandene når bare nodene 1 til er tillatt som mellomnoder.
Hele Floyd-Warshalls invariant er formulert i dette begrepet.
Forlenger alle stier med høyst én kant til.
Ikke vanlig matriseprodukt. Vanlig produkt ville vært sum av produkter, og
gir ingen mening som avstand.
bygger korteste stier opp kant for kant ved gjentatte min-pluss-produkter.
per produkt, for hele problemet naivt.
Erstattes i praksis av Floyd-Warshall, som er totalt — men
min-pluss-regningen kommer som egen håndkjøringsoppgave.
korteste avstand fra til blant stier med høyst kanter.
, og er svaret når grafen ikke har negative sykler.
«Høyst», ikke «nøyaktig». Diagonalleddene er det som gjør
kortere stier lovlige.
den boolske varianten: finnes det i det hele tatt en vei fra til ?
,
kjøretid .
Startmatrisen har sann på diagonalen — enhver node når seg selv.
skriver ut selve stien ved å lese baklengs fra til .
Kjøretid per sti.
d gir lengden, π gir veien. Ber oppgaven om stien, er det som
brukes.
Er samtidig i Floyd-Warshall og i Slow-APSP.
Regelen gjelder i all regning på denne matrisen.
NIL betyr enten at , eller at ingen vei er funnet.
Fra kan hele stien leses ut baklengs i .
en graf er glissen når er omtrent som , og tett når nærmer
seg .
For glisne grafer er kjøringer av Dijkstra — — best. For
tette er Floyd-Warshall med best.
Tettheten er halve svaret på «hvilken algoritme velger du»; fortegnet på
vektene er den andre halvparten.
Dijkstra forutsetter ikke-negative kantvekter og kan gi feil svar med éneneste negativ kant.
Floyd-Warshall og Bellman-Ford tåler negative kanter.
Sjekk fortegnet før du velger algoritme — det er det første spørsmålet i en
korteste-vei-oppgave.
en sykel der summen av kantvektene er negativ.
Da finnes ingen korteste sti: du kan gå rundt sykelen igjen og igjen og få
lavere og lavere kostnad.
Floyd-Warshall forutsetter at det ikke finnes noen. Bellman-Ford
oppdager dem, og det er dens særegne styrke.
oppgavetypen der du utfører algoritmen steg for steg og oppgir sluttilstanden.
Her er svarformen den etterspurte matrisen for den etterspurte runden —
eller den ene cellen, hvis det er det som er spurt om.
Ikke lever både d og π når bare én var etterspurt.
oppgavetypen der du oppgir kjøretiden til en navngitt algoritme.
for Floyd-Warshall og Transitive-Closure, for
naiv Slow-APSP.
Merk at antall kanter ikke inngår i noen av dem — det er poenget med
matriseformuleringen.
Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.
Skolesaga er en uavhengig læringsressurs og er ikke tilknyttet eller godkjent av Norges teknisk-naturvitenskapelige universitet. Dette er ikke offisielt studiemateriell. Les mer.