4.4 Korteste stier

Korteste veje.

En kantvægtet, rettet graf er en rettet graf, hvor hver kant er udstyret men en vægt eller omkostning. En korteste vej fra knude \(s\) til knude \(t\) er en rettet vej fra \(s\) til \(t\) med den egenskab, at ingen anden sådan vej har en lavere vægt.

Shortest path

Egenskaber.

Vi sammenfatter flere vigtige egenskaber og antagelser:

Datatype for kantvægtet, rettet graf.

Vi repræsenterer de vægtede kanter ved hjælp af følgende APG:

public class DirectedEdge implements Comparable<Edge>
Edge(int v, int w, double weight)skab en rettet kant fra v til w med vægt weight
doubleweight()denne kants vægt
intfrom()knuden, denne kant peger fra
voidto()knuden, denne kant peger på
StringtoString()tekstuel repræsentation af kanten

Metoderne from() og to() angiver kantens endepunkter. Programmet DirectedEdge.java implementerer denne APG.

Vi repræsenterer kantvægtede, rettede grafer ved hjælp af følgende APG:

public class EdgeWeightedDigraph
Graph(int V)skab en rettet graf med V knuder og ingen kanter
Graph(In in)læs en rettet graf fra indputstrømmen in
intV()antal knuder
intE()antal kanter
voidaddEdge(DirectedEdge e)tilføj kanten e til denne graf
Iterable<DirectedEdge>adj(int v)kanter som peger fra v
Iterable<DirectedEdge>edges()alle kanter i denne graf
StringtoString()tekstuel repræsentation af grafen
Programmet EdgeWeightedDigraph.java implementerer denne APG ved brug af nabolisterepræsentationen.

edge-weighted orienteret graf representation


APG for korteste veje.

Vi bruger følgende APG til at beregne korteste veje i en kantvægtet, rettet graf:

public class SP
SP(EdgeWeightedDigraph G, int s)konstruktør
doubledistTo(int v) afstand fra \(s\) til \(v\), eller \(\infty\) hvis ingen sti findes
booleanhasPathTo(int v)findes en sti fra \(s\) til \(v\)?
Iterable≤DirectedEdge>pathTo(int v)en sti fra \(s\) til \(v\), eller null hvis ingen sti findes
Vi forbereder nogle testdata:

Datastruktur for korteste veje med enkelt kilde.

Betrat en kantvægtet, rettet graf \(G\) og en startknude \(s\). Et korteste-veje-træ er en delgraf indeholdene \(s\) og alle knuder, der kan nås fra \(s\), der danner et rettet træ rodfæstet i \(s\), hvori hver vej er en korteste vej i \(G\).

Vi repræsenterer de korteste-veje med to knude-indekserede rækker:

Shortest stier tree

Slækning.

Vores algoritmer for korteste veje er baseret på en operation kaldet slækning . Vi sætter først distTo[s] til 0 og distTo[v] til uendeligt for alle andre knuder \(v\).

Påstand. (Optimalitet af korteste veje)

Lad \(G\) være en kantvægtet, rettet graf med startknude \(s\). Antag, at for hver knude \(v\), der kan nås fra \(s\), angiver distTo[v] er længden af nogen sti fra s til v . For hver knude \(v\), der ikke kan nås fra \(s\), er distTo[v] lig med uendeligt. Disse værdier er længden af ​​ korteste stier hvis og kun hvis de opfylder distTo [w] <= distTo [v] + e.weight () for hver kant \(e\) = v-> w. Optimalitetsbetingelserne leder til en generel algoritme til at finde korteste veje. For øjeblikket begrænser vi os til ikke-negative vægte.

Påstand. (Generel algoritme for korteste veje)

Sæt først distTo [s] til 0, og alle andre afstande i distTo [] til uendelig. Fortsæt med at slække en vilkårlig kant i \(G\), indtil der ikke er flere kanter, der kan slækkes. Herefter gælder for hver knude \(v\), der kan nås fra s , at afstanden i distTo [v] angiver længden af en korteste vej fra s til v , og værdien af edgeTo[] er den sidste kant på denne vej.

Dijkstras algoritme.

Sæt først dist [s] til 0 og alle andre indgange i distTo [] til uendeligt. Begynd med et tomt træ. Vælg en knude uden for træet med laveste afstand i distTo[], føj den til træet, og slæk den. Fortsæt indtil alle knuder er i træet eller ingen knude uden for træet har en endelig afstand i distTo[].

Programmet DijkstraSP.java er en effektiv implementation af Dijkstras algoritme. Den bruger prioritetskøen fra IndexMinPQ.java.

Påstand.

Dijkstras algoritme finder korteste veje fra en enkelt kilde i en kantvægtet rettet med ikke-negative vægte i ekstra plads proportional med \(V\) og tid proportional med \(E\log V\) i værste fald.

Kantvægtede, acycliske, rettede grafer.

Vi bruger forkortelsen KRAG for kantvægtet, rettet, acyklisk graf.

Påstand.

Ved at slække knuder i topologisk orden kan vi finde korteste og længste stier fra en enkelt kilde i en KRAG i tid proportional med \(E + V\).

Korteste veje i kantvægtede rettede grafer.

Påstand.

Der findes en korteste vej fra \(s\) til \(v\) i en kantvægtet, rettet graf hvis og kun hvis der findes mindst én rettet sti fra \(s\) til \(v\) og ingen knude på nogen rettet sti fra \(s\) til \(v\) er på en negativ kreds.

Påstand.

Bellman-Fords algoritme finder korteste stier fra en enkelt given kilde \(s\) (eller finder en negativ kreds, der kan nås fra \(s\)) i en kantvægtet, rettet graf med \(V\) knuder og \(E\) kanter i tid proportional med \(EV\) og ekstra plads proportional med \(V\), i værste fald.