UltipaDocs
Try Playground
  • Introduction
  • Managing HDC Graphs
  • Managing Distributed Projections
  • Installing Algorithms
  • Running Algorithms
    • Degree Centrality
    • Closeness Centrality
    • Harmonic Centrality
    • Graph Centrality
    • Betweenness Centrality
    • Eigenvector Centrality
    • Katz Centrality
    • CELF
    • PageRank
    • ArticleRank
    • TextRank
    • HITS
    • SybilRank
    • Jaccard Similarity
    • Overlap Similarity
    • Cosine Similarity
    • Pearson Correlation Coefficient
    • Euclidean Distance
    • K-Hop All
    • Bipartite Graph
    • HyperANF
    • Connected Component
    • Triangle Counting
    • Induced Subgraph
    • k-Core
    • k-Truss
    • p-Cohesion
    • k-Edge Connected Components
    • Local Clustering Coefficient
    • Topological Sort
    • Schema Overview
    • Dijkstra's Single-Source Shortest Path
    • Delta-Stepping Single-Source Shortest Path
    • Shortest Path Faster Algorithm (SPFA)
    • Minimum Spanning Tree
    • Breadth-First Search (BFS)
    • Depth-First Search (DFS)
    • Adamic-Adar Index
    • Common Neighbors
    • Preferential Attachment
    • Resource Allocation
    • Total Neighbors
    • Louvain
    • Leiden
    • Label Propagation
    • HANP
    • k-Means
    • kNN (k-Nearest Neighbors)
    • K-1 Coloring
    • Conductance
      • Random Walk
      • Node2Vec Walk
      • Node2Vec
      • Struc2Vec Walk
      • Struc2Vec
      • LINE
      • Fast Random Projection
      • Summary of Graph Embedding
      • Gradient Descent
      • Backpropagation
      • Skip-gram
      • Skip-gram Optimization
  1. Docs
  2. /
  3. Graph Analytics & Algorithms
  4. /
  5. Pathfinding

Shortest Path Faster Algorithm (SPFA)

HDC

Overview

The Shortest Path Faster Algorithm (SPFA) is an improvement of the Bellman–Ford algorithm which computes the shortest paths from a source node to all other reachable nodes (i.e., single-source shortest paths) in a graph. It is especially well-suited for graphs with negative-weight edges.

The algorithm was first published by E.F. Moore in 1959, but it was later rediscovered and popularized under the name "Shortest Path Faster Algorithm (SPFA)" by FanDing Duan in 1994.

  • F. Duan, 关于最短路径的SPFA快速算法 [About the SPFA algorithm] (1994)

Concepts

Shortest Path Faster Algorithm (SPFA)

Given a graph G = (V, E) and a source node s∈V, array d[] is used to store the distances of the shortest paths from s to all nodes. Initialize all elements in d[] to infinity, except for d[s] = 0.

The basic idea of SPFA is the same as the Bellman–Ford algorithm in that each node is used as a candidate to relax its adjacent nodes. However, SPFA improves efficiency by avoiding unnecessary iterations over all nodes. Instead, it maintains a first-in, first-out queue Q to store candidate nodes, and a node is added to the queue only when it has been relaxed.

NOTE

The term relaxation refers to the process of updating the distance of a node v that is connected to node u to a potential shorter distance by considering the path through node u. Specifically, the distance of node v is updated to d[v] = d[u] + w(u,v), where w(u,v) is the weight of the edge (u,v). This update is performed only if the current d[v] is greater than d[u] + w(u,v).

At the begining of the algorithm, all nodes are assigned an initial distance of infinity, except for the source node, which is set to 0. The source node is viewed as first relaxed and pushed into the queue.

During each iteration, SPFA dequeues a node u from Q as a candidate. For each edge (u,v) in the graph, if node v can be relaxed, the following steps are performed:

  • Relax node v: d[v] = d[v] + w(u,v).
  • Push node v into Q if v is not in Q.

This process repeats until no more nodes can be relaxed.

The steps below illustrate how to compute the SPFA with source node A and find the weighted shortest paths in the outgoing direction:

Considerations

  • SPFA can handle graphs with negative edge weights under the conditions that (1) the source node does not have access to any node within a negative cycle, and (2) the shortest paths are directed. A negative cycle is a cycle where the sum of the edge weights is negative. If the graph contains such cycles or if shortest paths are undirected when negative weights exist, SPFA will output infinite results. This occurs because the algorithm can repeatedly traverse the negative cycle or edge, continually lowering the path cost each time.
  • If multiple shortest paths exist between two nodes, the algorithm will find all of them.
  • In disconnected graphs, the algorithm only outputs the shortest paths from the source node to all nodes belonging to the same connected component as the source node.

Example Graph

Run the following statements on an empty graph to define its structure and insert data:

ALTER EDGE default ADD PROPERTY {
  value int32
};
INSERT (A:default {_id: "A"}),
       (B:default {_id: "B"}),
       (C:default {_id: "C"}),
       (D:default {_id: "D"}),
       (E:default {_id: "E"}),
       (F:default {_id: "F"}),
       (G:default {_id: "G"}),
       (A)-[:default {value: 2}]->(B),
       (A)-[:default {value: 4}]->(F),
       (B)-[:default {value: 3}]->(C),
       (B)-[:default {value: 3}]->(D),
       (B)-[:default {value: 6}]->(F),
       (D)-[:default {value: 2}]->(E),
       (D)-[:default {value: 2}]->(F),
       (E)-[:default {value: 3}]->(G),
       (F)-[:default {value: 1}]->(E);

Creating HDC Graph

To load the entire graph to the HDC server hdc-server-1 as my_hdc_graph:

CREATE HDC GRAPH my_hdc_graph ON "hdc-server-1" OPTIONS {
  nodes: {"*": ["*"]},
  edges: {"*": ["*"]},
  direction: "undirected",
  load_id: true,
  update: "static"
}

Parameters

Algorithm name: sssp

Name
Type
Spec
Default
Optional
Description
ids_id//NoSpecifies a single source node by its _id.
uuids_uuid//NoSpecifies a single source node by its _uuid.
directionStringin, out/YesSpecifies that the shortest paths should only contain incoming edges (in) or outgoing edges (out); edge direction is ignored if it is unset.
edge_schema_property[]"<@schema.?><property>"//YesSpecifies numeric edge properties used as weights by summing their values. Only properties of numeric type are considered, and edges without these properties are ignored.
record_pathInteger0, 10YesWhether to include the shortest paths in the results; sets to 1 to return the totalCost and the shortest paths, or to 0 to return the totalCost only.
impl_typeStringspfabetaNoSpecifies the implementation type of the SSSP algorithm; for the SPFA, keep it as spfa; beta is Ultipa's default shortest path algorithm.
return_id_uuidStringuuid, id, bothuuidYesIncludes _uuid, _id, or both to represent nodes in the results. Edges can only be represented by _uuid.
limitInteger≥-1-1YesLimits the number of results returned. Set to -1 to include all results.
orderStringasc, desc/YesSorts the results by totalCost.

File Writeback

CALL algo.sssp.write("my_hdc_graph", {
  ids: "A",
  edge_schema_property: "@default.value",
  impl_type: "spfa",
  return_id_uuid: "id"
}, {
  file: {
    filename: "costs"
  }
})

Result:

File: costs
_id,totalCost
D,5
F,4
B,2
E,5
C,5
G,8
CALL algo.sssp.write("my_hdc_graph", {
  ids: "A",
  edge_schema_property: "@default.value",
  impl_type: "spfa",
  record_path: 1,
  return_id_uuid: "id"
}, {
  file: {
    filename: "paths"
  }
})

Result:

File: costs
totalCost,_ids
8,A--[102]--F--[107]--E--[109]--G
5,A--[101]--B--[105]--D
5,A--[102]--F--[107]--E
5,A--[101]--B--[104]--C
4,A--[102]--F
2,A--[101]--B

Full Return

CALL algo.sssp.run("my_hdc_graph", {
  ids: 'A',
  edge_schema_property: 'value',
  impl_type: 'spfa',
  record_path: 0,
  return_id_uuid: 'id',
  order: 'desc'
}) YIELD r
RETURN r

Result:

_idtotalCost
G8
D5
E5
C5
F4
B2

Stream Return

CALL algo.sssp.stream("my_hdc_graph", {
  ids: 'A',
  edge_schema_property: '@default.value',
  impl_type: 'spfa',
  record_path: 1,
  return_id_uuid: 'id'
}) YIELD r
RETURN r

Result:

totalCost
_ids
8["A","102","F","107","E","109","G"]
5["A","101","B","105","D"]
5["A","102","F","107","E"]
5["A","101","B","104","C"]
4["A","102","F"]
2["A","101","B"]