praca_magisterska/code/pseudocode.md

3.5 KiB
Raw Blame History

Shortest Path Algorithms — Pseudocode

1. Dijkstra's Algorithm

Finds shortest paths from a single source to all nodes. Requirement: all edge weights must be non-negative.

DIJKSTRA(Graph, source):
    for each node v in Graph:
        dist[v] ← ∞
        prev[v] ← NULL
    dist[source] ← 0

    PQ ← min-priority queue ordered by dist
    PQ.insert(source, 0)
    visited ← ∅

    while PQ is not empty:
        u ← PQ.extract_min()

        if u ∈ visited:
            continue
        visited ← visited  {u}

        for each neighbour v of u with edge weight w:
            if dist[u] + w < dist[v]:
                dist[v] ← dist[u] + w
                prev[v] ← u
                PQ.insert(v, dist[v])

    return dist, prev

Complexity: O((V + E) log V) with a binary heap.

2. Bellman-Ford Algorithm

Finds shortest paths from a single source to all nodes. Advantage over Dijkstra: handles negative edge weights.

BELLMAN_FORD(Graph, source):
    for each node v in Graph:
        dist[v] ← ∞
        prev[v] ← NULL
    dist[source] ← 0

    repeat |V| - 1 times:                         ← main relaxation loop
        for each edge (u, v, w) in Graph:
            if dist[u] + w < dist[v]:
                dist[v] ← dist[u] + w
                prev[v] ← u

    for each edge (u, v, w) in Graph:              ← negative cycle check
        if dist[u] + w < dist[v]:
            error "Graph contains a negative cycle"

    return dist, prev

Complexity: O(V · E).

3. A* Algorithm

Finds the shortest path from source to a specific goal node. Uses a heuristic h(n) that estimates the cost from n to the goal. Requirement: h(n) must be admissible (never overestimates).

A_STAR(Graph, source, goal, h):
    for each node v in Graph:
        g[v] ← ∞                                  ← actual cost from source
        prev[v] ← NULL
    g[source] ← 0

    PQ ← min-priority queue ordered by f(v) = g[v] + h(v)
    PQ.insert(source, g[source] + h(source))
    visited ← ∅

    while PQ is not empty:
        u ← PQ.extract_min()

        if u = goal:
            return reconstruct_path(prev, goal), g[goal]

        if u ∈ visited:
            continue
        visited ← visited  {u}

        for each neighbour v of u with edge weight w:
            tentative ← g[u] + w
            if tentative < g[v]:
                g[v] ← tentative
                prev[v] ← u
                f[v] ← g[v] + h(v)
                PQ.insert(v, f[v])

    return "no path found"

Complexity: depends on heuristic quality; worst case O((V + E) log V), same as Dijkstra.

Path Reconstruction (used by all three)

RECONSTRUCT_PATH(prev, target):
    path ← []
    node ← target
    while node ≠ NULL:
        path.prepend(node)
        node ← prev[node]
    return path

Quick Comparison

Property Dijkstra Bellman-Ford A*
Negative weights
Negative cycle detect
Heuristic required no no yes (admissible h)
Finds path to all nodes all nodes single goal node
Time complexity O((V+E) log V) O(V · E) O((V+E) log V) best
Best use case general SSSP negative edges known goal + good h