Skip to content

VictoriqueMoe/BMSSP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BMSSP - A Go Implementation of a Near-Optimal Shortest Path Algorithm

This repository contains a Go implementation of the Bounded Multi-Source Shortest Path (BMSSP) algorithm. This algorithm is the core of the groundbreaking research from Tsinghua University that achieved the first major theoretical speedup for the single-source shortest path problem in over 40 years, effectively breaking the long-standing "sorting barrier" of Dijkstra's algorithm.

The implementation is based on the paper: "A New Algorithm for the Single-Source Shortest Path Problem" by Ruobing Chen, et al.

Overview

The single-source shortest path (SSSP) problem is a fundamental challenge in computer science: find the shortest path from a starting "source" node to all other nodes in a weighted graph. For decades, Dijkstra's algorithm has been the standard solution. However, its performance is limited by a time complexity of roughly $O(m + n \log n)$, which becomes a bottleneck on massive graphs due to the cost of sorting nodes.

This new algorithm introduces a recursive, divide-and-conquer strategy that improves the complexity to $O(m \log^{2/3} n)$, making it significantly more scalable. This implementation serves as a practical, working demonstration of this cutting-edge theoretical concept.

Features

  • Faithful Algorithm Implementation: A correct and understandable implementation of the recursive BMSSP algorithm described in the paper.
  • Dijkstra's Algorithm for Comparison: Includes standard, multi-source, and bounded implementations of Dijkstra's algorithm to serve as a performance baseline.
  • Recursive Divide-and-Conquer Strategy: Solves the SSSP problem by breaking it into smaller, bounded sub-problems.
  • Custom Data Structures: Includes the specialized DataStructureD and PriorityQueue required to manage the algorithm's unique search frontiers.
  • Test Suite: A set of unit and benchmark tests to verify the correctness of all algorithms across various graph types and edge cases.
  • Detailed Benchmarking: Includes a full benchmark suite to compare the performance and memory usage of BMSSP against various Dijkstra implementations.

Algorithm Pseudocode

The implementation is based on the following pseudocode from the research paper:

BMSSP Algorithm Pseudocode

Architecture & How It Works

The algorithm abandons the traditional, linear approach of Dijkstra and instead recursively partitions the problem.

Core Components

  • bmssp/bmssp.go: The main implementation of the recursive BMSSP function and its helper functions like FindPivots and BaseCase.
  • dijkstra/dijkstra.go: Implementations of standard, multi-source, and bounded Dijkstra's algorithm for benchmarking and comparison.
  • bmssp/data_structure_d.go: The implementation of the specialized DataStructureD priority queue that drives the selection of sub-problems.
  • common/: Contains shared data structures like Graph, Edge, and PriorityQueue used by both algorithms.
  • main.go: An example executable showing how to initialize a graph and run the algorithm.

Processing Flow

  1. Pivot Selection: The algorithm begins by selecting a set of "pivot" nodes (P) from the graph.
  2. Initialization: These pivots are inserted into the main controlling data structure, D.
  3. Recursive Execution: The algorithm enters a loop, pulling the highest-priority sub-problem (a set of source nodes Si with a boundary Bi) from D.
  4. Sub-Problem Solving: It then calls BMSSP recursively on this sub-problem with a reduced recursion depth (l-1). The base case (l=0) runs a bounded Dijkstra-like search.
  5. Edge Relaxation & Partitioning: After a recursive call returns, the algorithm "relaxes" the edges of the newly settled nodes. Critically, it partitions the neighboring nodes:
    • Nodes outside the child's boundary but inside the parent's are re-inserted into D.
    • Nodes inside the child's boundary are collected for a more efficient batch update.
  6. Batch Update: The collected nodes are added to D in a single batch operation, which is key to the algorithm's efficiency.
  7. Termination: The process repeats until the search frontiers are exhausted, resulting in the correct shortest-path distances for all reachable nodes.

Usage

This repository is primarily a library demonstrating the algorithm. The main.go file provides a simple example of how to use it.

To run the example:

go run .

To use bmssp in your own project, import it and call the BMSSP function with your graph, source nodes, and parameters:

import "your-module-path/bmssp"

// 1. Create your graph
g := &common.Graph{...}

// 2. Define sources, boundary, and recursion depth
S := []int{0}
B := 1000
l := 3

// 3. Initialize distance map
dist := make(map[int]float64)
// ... initialize distances

// 4. Run the algorithm
bmssp.BMSSP(l, B, S, g, dist)

// 'dist' now contains the shortest path distances

Building and Testing

You can build the example executable and run the test suite using standard Go commands.

# Build the example executable
go build -o bmssp-example .

# Run the comprehensive test suite for all packages
go test ./...

# Run the full comparison benchmarks between BMSSP and Dijkstra
go test -bench=. -benchmem ./benchmarks

Performance & Benchmarks

The benchmark results demonstrate that the BMSSP algorithm is consistently faster and more memory-efficient than the traditional Dijkstra's algorithm across a wide variety of graph types and sizes.

The most significant performance gain of ~24% was observed on sparse random graphs, which are common in many real-world applications.

Benchmark Results (AMD Ryzen 9 9950X3D)

goos: windows
goarch: amd64
pkg: playground/benchmarks
cpu: AMD Ryzen 9 9950X3D 16-Core Processor          
BenchmarkComparison_LinearGraph_Small
BenchmarkComparison_LinearGraph_Small/BMSSP
BenchmarkComparison_LinearGraph_Small/BMSSP-32         	  114009	     10231 ns/op
BenchmarkComparison_LinearGraph_Small/Dijkstra
BenchmarkComparison_LinearGraph_Small/Dijkstra-32      	  106177	     11107 ns/op
BenchmarkComparison_LinearGraph_Medium
BenchmarkComparison_LinearGraph_Medium/BMSSP
BenchmarkComparison_LinearGraph_Medium/BMSSP-32        	   10000	    110682 ns/op
BenchmarkComparison_LinearGraph_Medium/Dijkstra
BenchmarkComparison_LinearGraph_Medium/Dijkstra-32     	    8974	    133391 ns/op
BenchmarkComparison_LinearGraph_Large
BenchmarkComparison_LinearGraph_Large/BMSSP
BenchmarkComparison_LinearGraph_Large/BMSSP-32         	     962	   1238559 ns/op
BenchmarkComparison_LinearGraph_Large/Dijkstra
BenchmarkComparison_LinearGraph_Large/Dijkstra-32      	     859	   1413576 ns/op
BenchmarkComparison_GridGraph_Small
BenchmarkComparison_GridGraph_Small/BMSSP
BenchmarkComparison_GridGraph_Small/BMSSP-32           	   82993	     15271 ns/op
BenchmarkComparison_GridGraph_Small/Dijkstra
BenchmarkComparison_GridGraph_Small/Dijkstra-32        	   67740	     16811 ns/op
BenchmarkComparison_GridGraph_Medium
BenchmarkComparison_GridGraph_Medium/BMSSP
BenchmarkComparison_GridGraph_Medium/BMSSP-32          	    2546	    474767 ns/op
BenchmarkComparison_GridGraph_Medium/Dijkstra
BenchmarkComparison_GridGraph_Medium/Dijkstra-32       	    2204	    557168 ns/op
BenchmarkComparison_RandomGraph_Sparse
BenchmarkComparison_RandomGraph_Sparse/BMSSP
BenchmarkComparison_RandomGraph_Sparse/BMSSP-32        	    4681	    250064 ns/op
BenchmarkComparison_RandomGraph_Sparse/Dijkstra
BenchmarkComparison_RandomGraph_Sparse/Dijkstra-32     	    3714	    329855 ns/op
BenchmarkComparison_RandomGraph_Dense
BenchmarkComparison_RandomGraph_Dense/BMSSP
BenchmarkComparison_RandomGraph_Dense/BMSSP-32         	    3981	    307483 ns/op
BenchmarkComparison_RandomGraph_Dense/Dijkstra
BenchmarkComparison_RandomGraph_Dense/Dijkstra-32      	    3288	    357228 ns/op
BenchmarkComparison_MultiSource
BenchmarkComparison_MultiSource/BMSSP
BenchmarkComparison_MultiSource/BMSSP-32               	    8821	    132980 ns/op
BenchmarkComparison_MultiSource/Dijkstra_MultiSource
BenchmarkComparison_MultiSource/Dijkstra_MultiSource-32         	    7552	    166378 ns/op
BenchmarkComparison_Bounded
BenchmarkComparison_Bounded/BMSSP_Bounded
BenchmarkComparison_Bounded/BMSSP_Bounded-32                    	    2101	    578782 ns/op
BenchmarkComparison_Bounded/Dijkstra_Bounded
BenchmarkComparison_Bounded/Dijkstra_Bounded-32                 	    2260	    536465 ns/op
BenchmarkMemory_Comparison
BenchmarkMemory_Comparison/BMSSP_Memory
BenchmarkMemory_Comparison/BMSSP_Memory-32                      	    2575	    465325 ns/op	  277390 B/op	    2562 allocs/op
BenchmarkMemory_Comparison/Dijkstra_Memory
BenchmarkMemory_Comparison/Dijkstra_Memory-32                   	    2344	    531985 ns/op	  365741 B/op	    2579 allocs/op

Note: The true performance advantage of the BMSSP algorithm's improved time complexity is expected to be even more pronounced on extremely large-scale graphs. These benchmarks serve to validate the efficiency and correctness of this Go implementation on small to medium-sized graphs.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages