← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Bellman-Ford Algorithm

Algorithms PHP 7.1+ Advanced
debt(d8/e5/b3/t7)
d8 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'silent in production until users hit it' (d9), scored d8 because phpstan and manual review (per detection_hints) won't flag using Dijkstra on a negative-weight graph — it's an algorithmic correctness issue that produces wrong distances silently, only surfacing when users hit pathological inputs like arbitrage cycles.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix says swap Dijkstra for Bellman-Ford accepting O(V*E), but that means replacing the relaxation loop, likely changing graph representation from adjacency list to edge list, and adding V-th pass for cycle detection — a meaningful refactor within the shortest-path component.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Per applies_to (library/cli/web) the algorithm choice is contained within a graph/routing module; it doesn't shape the whole system, but the chosen representation (edge list vs adjacency) and cycle-handling semantics do impose ongoing cost on that component.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap (contradicts how a similar concept works elsewhere)' (t7). The misconception explicitly states devs treat Bellman-Ford as 'just a slower Dijkstra' — but Dijkstra's greedy assumption is fundamentally wrong for negative weights, and common_mistakes note skipping the V-th pass silently loses cycle detection. The 'obvious' Dijkstra intuition is actively misleading here.

About DEBT scoring →

Also Known As

Bellman-Ford SSSP with negative weights negative cycle detection

TL;DR

Single-source shortest path algorithm that handles negative edge weights and detects negative cycles by relaxing all edges V-1 times.

Explanation

Bellman-Ford solves the single-source shortest path problem on weighted directed graphs, including graphs with negative edge weights - a case Dijkstra cannot handle. The algorithm initialises the distance to the source as 0 and all other distances as infinity, then relaxes every edge V-1 times, where V is the vertex count. Relaxing an edge (u, v, w) means: if dist[u] + w < dist[v], update dist[v]. After V-1 passes, all shortest paths are guaranteed to be found because any simple path has at most V-1 edges. A V-th pass is used to detect negative cycles: if any edge can still be relaxed, a negative cycle is reachable from the source, and no finite shortest path exists for nodes on or reachable from that cycle. Time complexity is O(V*E), which is slower than Dijkstra's O((V+E) log V), so use Bellman-Ford only when negative weights are possible or when you need cycle detection. Practical applications include currency arbitrage detection (negative log rates), routing protocols like RIP and distance-vector routing, network delay analysis, and constraint systems. Bellman-Ford also serves as a subroutine in Johnson's algorithm for all-pairs shortest paths on sparse graphs with negative weights. In PHP, you might implement it for financial arbitrage checks, dependency graphs with negative weights (rebates, credits), or game economies where certain actions produce net gains.

Diagram

flowchart LR
    A((A<br/>0)) -->|4| B((B))
    A -->|5| C((C))
    B -->|-3| C
    C -->|2| D((D))
    B -->|6| D
    subgraph Passes
        P1[Pass 1: relax all edges] --> P2[Pass 2: refine via B to -3 to C]
        P2 --> P3[Pass V-1: distances settled]
        P3 --> P4{V-th pass<br/>any relaxation?}
        P4 -->|Yes| NC[Negative cycle detected]
        P4 -->|No| OK[Shortest paths valid]
    end
    style OK fill:#238636,color:#fff
    style NC fill:#da3633,color:#fff

Common Misconception

Bellman-Ford is just a slower Dijkstra - it is not. Bellman-Ford handles negative edge weights and detects negative cycles, which Dijkstra fundamentally cannot do because Dijkstra's greedy choice assumes settled distances never improve.

Why It Matters

Real systems frequently model gains and losses as negative weights: currency arbitrage, financial netting, credit-and-debit ledgers, and reward-based routing. Choosing Bellman-Ford in these cases avoids silent wrong answers that Dijkstra would produce, and its negative-cycle detection is critical for spotting exploitable loops in trading and economic models.

Common Mistakes

  • Running only V-1 iterations and skipping the V-th check - you lose negative cycle detection and may return meaningless distances.
  • Stopping early without an updated-flag optimisation, or conversely failing to break when no relaxation occurred in a full pass.
  • Reporting shortest paths for nodes reachable from a negative cycle - those distances are undefined and should be marked -infinity.
  • Using Bellman-Ford on large graphs where all weights are non-negative - Dijkstra with a heap is dramatically faster.
  • Confusing edge list representation with adjacency list - Bellman-Ford iterates over edges, so an edge list is often the cleanest structure.

Avoid When

  • All edge weights are non-negative - Dijkstra with a heap is much faster.
  • The graph is a DAG - a topological-sort relaxation runs in O(V+E).
  • Very dense graphs where O(V*E) becomes O(V^3) - consider Floyd-Warshall if you need all-pairs anyway.

When To Use

  • Graph contains negative edge weights - Dijkstra will produce wrong answers.
  • You must detect negative cycles, e.g. currency arbitrage or exploitable game loops.
  • As a subroutine in Johnson's algorithm for all-pairs shortest paths on sparse graphs with negatives.
  • Distance-vector routing protocols where nodes propagate distance estimates iteratively.

Code Examples

✗ Vulnerable
// WRONG: uses Dijkstra on a graph with negative weights - silently incorrect:
function shortestPath(array $graph, int $src): array {
    $dist = array_fill(0, count($graph), PHP_INT_MAX);
    $dist[$src] = 0;
    $heap = new SplMinHeap();
    $heap->insert([0, $src]);
    while (!$heap->isEmpty()) {
        [$d, $u] = $heap->extract();
        foreach ($graph[$u] as [$v, $w]) {
            // Negative w can produce shorter paths for already-settled nodes,
            // but Dijkstra will not revisit them - result is wrong.
            if ($dist[$u] + $w < $dist[$v]) {
                $dist[$v] = $dist[$u] + $w;
                $heap->insert([$dist[$v], $v]);
            }
        }
    }
    return $dist; // Incorrect when any edge weight is negative
}
✓ Fixed
/**
 * Bellman-Ford: handles negative weights, detects negative cycles.
 * $edges: list of [u, v, weight]. $v: vertex count.
 * Returns ['dist' => array, 'negativeCycle' => bool].
 */
function bellmanFord(array $edges, int $v, int $src): array {
    $dist = array_fill(0, $v, PHP_INT_MAX);
    $dist[$src] = 0;

    // Relax all edges V-1 times
    for ($i = 0; $i < $v - 1; $i++) {
        $updated = false;
        foreach ($edges as [$u, $to, $w]) {
            if ($dist[$u] !== PHP_INT_MAX && $dist[$u] + $w < $dist[$to]) {
                $dist[$to] = $dist[$u] + $w;
                $updated = true;
            }
        }
        if (!$updated) break; // Early exit optimisation
    }

    // V-th pass: any relaxation implies a reachable negative cycle
    foreach ($edges as [$u, $to, $w]) {
        if ($dist[$u] !== PHP_INT_MAX && $dist[$u] + $w < $dist[$to]) {
            return ['dist' => $dist, 'negativeCycle' => true];
        }
    }

    return ['dist' => $dist, 'negativeCycle' => false];
}

Added 5 Aug 2026
Views 11
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 4 pings W 1 ping T 1 ping F
PetalBot 1
Bing 1
Google 3 ChatGPT 1 Bing 1 PetalBot 1
crawler 6
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
If your graph has negative edge weights or you need negative-cycle detection, replace Dijkstra with Bellman-Ford - accept O(V*E) in exchange for correctness.
📦 Applies To
PHP 7.1+ web cli library
🔗 Prerequisites
🔍 Detection Hints
Dijkstra-style priority queue relaxation applied to a graph whose edges include negative weights, or absence of a V-th pass when negative-cycle detection is required
Auto-detectable: ✗ No phpstan manual-review
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: High Context: Function Tests: Update


✓ schema.org compliant