Kortstepad-algoritme
Het kortstepadalgoritme, ook bekend als Dijkstra's algoritme, is een graaf-algoritme beschreven door Edsger Dijkstra in 1959.[1] Gegeven een gerichte graaf G waarin de afstand tussen ieder tweetal verbonden punten van G ten minste 0 bedraagt, rekent het algoritme voor een bepaalde beginknoop
de kortste afstand uit tot alle punten van G. Toepassingen van dit algoritme zijn onder meer bij verkeersmodellen, route-navigatiesystemen en telecommunicatie.
[bewerken] De basis
Het algoritme is gebaseerd op de opmerking dat de afstand (de lengte van het kortste pad) tussen ieder tweetal punten v en w van een gerichte graaf G als volgt berekend kan worden:
- Zij
de afstand tussen v en x, voor x een punt van G. - Zij
, de verzameling van punten y die direct verbonden zijn met w (via een tak van y naar w). - Zij
het gewicht van de tak tussen twee direct met elkaar verbonden knopen y en w.
- De afstand van v naar w is
, het minimum van de som van de afstand van v naar een punt y in N plus de directe afstand van dat punt naar w. Oftewel - weinig verrassend - als de som van alle directe afstanden in een pad minimaal is, dan is de totale lengte van dat pad (die som dus) minimaal.
- Verder definiëren we
, de verzameling van punten y die direct verbonden zijn met v (via een tak van v naar y).
[bewerken] Het algoritme
Het algoritme is eigenlijk een veralgemenisering van de basis van hierboven. Het algoritme verdeelt de punten van G in drie verzamelingen:
- A: de verzameling van punten waarvan de kortste afstand tot gb berekend is
- X: de verzameling van punten waarnaar er al wel een pad bekend is vanuit gb, maar niet noodzakelijk het kortste
- V(G) − A − X: de overige punten van V (deze verzameling wordt niet bijgehouden in het algoritme en heeft dus geen naam)
Hiervoor geldt uiteraard dat
, A en X hebben geen punten gemeen.
Daarnaast bestaat er een array d(v), geïndiceerd met de punten v van G. Voor elk punt
wordt dit array door het algoritme dusdanig gevuld dat aan het eind geldt d(g) = de lengte van het kortste pad van gb naar g.
Initieel geldt
-
- A = {gb}

- d(gb) = 0


Het algoritme herhaalt nu de volgende stappen totdat X de lege verzameling wordt (op dat moment zijn er geen bereikbare punten meer over), vanuit gb:
-
- Kies uit X het punt x met de minimale waarde van d(x); dit is de eindwaarde van d(x) voor dat punt. Immers, d(x) heeft de waarde van de lengte van het kortste pad naar x vanuit gb dat we tot nu toe gezien hebben. Ieder ander pad naar x moet over x lopen en is dus langer, omdat alle kanten een positieve lengte hebben.
- Omdat d(x) definitief is, verplaatsen we x van X naar A. Voor alle punten z die bereikbaar zijn vanuit x en die nog niet in A zitten, doen we het volgende:
- Zit z nog niet in X, dan voegen we het punt aan X toe. Onze eerste schatting voor de afstand tussen gb en z is dan d(x) + gew(x,z) -- deze waarde plaatsen we in d(z)
- Zit z al wel in X, dan passen we de schatting in d(z) aan -- de nieuwe waarde is het minimum van de lengte van het nieuw-gevonden pad naar z (d(x) + gew(x,z)) en de lengte van het kortste pad naar z dat we al gevonden hadden.
Zodra dit algoritme afloopt (en dat doet het, want V(G) is eindig en iedere stap verplaatst een element van X naar A), dan is d(v) gevuld met de afstanden van gb naar alle punten die vanuit dit beginpunt bereikbaar zijn. Is d(w) oneindig voor een
, dan is dat punt w niet bereikbaar vanuit gb.
[bewerken] Algoritme in pseudocode
In pseudocode ziet het algoritme er als volgt uit:
foreach vV(G) do d(v) =
; A := gb d(a) := 0 X :=
foreach z : z
![]()
do X := X
{z} d(z) := gew(gb,z) ; /* * X en d zijn nu geïnitialiseerd */ while not(X =
) do /* * X is nog niet leeg */ y : (y
X)
(d(y) = MIN {d(y')|y'
X} /* * y is dus het element van X met de laagste waarde van d(v) -- dit is de definitieve * waarde van d(y) */ A := A
{y} X := X
{y} /* * y is nu verplaatst van X naar A */ foreach z: z
M_(y)
not (z
A) do if not (z
X) then X := X
{z} d(z) := d(y) + gew(y,z) else /* * dus z
X */ d(z) := MIN{d(z), d(y) + gew(y,z)}
Referenties
|
de afstand tussen v en x, voor x een punt van
, de
het gewicht van de tak tussen twee direct met elkaar verbonden knopen y en w.
, het minimum van de som van de afstand van v naar een punt y in N plus de directe afstand van dat punt naar w. Oftewel - weinig verrassend - als de som van alle directe afstanden in een pad minimaal is, dan is de totale lengte van dat pad (die som dus) minimaal.
, de 


V(G) do d(v) =
;
A :=
foreach z : z
do
X := X
{z}
d(z) := gew(
(d(y) = MIN {d(y')|y'
{y}
/*
* y is nu verplaatst van X naar A
*/
foreach z: z