or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-algorithms.mdanalysis.mdcentrality.mdcore-classes.mdgenerators.mdindex.mdlayouts.mdshortest-paths.mdtraversal.mdvisualization.md

shortest-paths.mddocs/

0

# Shortest Path Algorithms

1

2

Comprehensive collection of shortest path algorithms for finding optimal paths between nodes in weighted and unweighted graphs. rustworkx provides implementations of major shortest path algorithms optimized for performance with parallel processing support.

3

4

## Capabilities

5

6

### Dijkstra's Algorithm

7

8

Single-source shortest path algorithm for graphs with non-negative edge weights. Supports both single-target and all-targets modes with optional weight functions.

9

10

```python { .api }

11

def dijkstra_shortest_paths(graph, source: int, target: int = None, weight_fn = None, default_weight: float = 1.0, as_undirected: bool = False) -> dict:

12

"""

13

Find shortest paths using Dijkstra's algorithm.

14

15

Parameters:

16

- graph: PyGraph or PyDiGraph to search

17

- source (int): Source node index

18

- target (int, optional): Target node index, if None finds paths to all nodes

19

- weight_fn (callable, optional): Function to extract edge weight

20

- default_weight (float): Default edge weight if weight_fn not provided

21

- as_undirected (bool): Treat directed graph as undirected

22

23

Returns:

24

dict: Mapping of target nodes to path lists

25

"""

26

27

def dijkstra_shortest_path_lengths(graph, node: int, edge_cost_fn, goal: int = None) -> dict:

28

"""

29

Compute shortest path lengths using Dijkstra's algorithm.

30

31

Parameters:

32

- graph: Input graph

33

- node (int): Source node index

34

- edge_cost_fn (callable): Function returning edge cost as float

35

- goal (int, optional): Target node, returns single entry if specified

36

37

Returns:

38

dict: Mapping of target nodes to path lengths

39

"""

40

41

def all_pairs_dijkstra_shortest_paths(graph, edge_cost_fn):

42

"""

43

All-pairs shortest paths using Dijkstra's algorithm.

44

Multithreaded execution for improved performance.

45

46

Parameters:

47

- graph: Input graph

48

- edge_cost_fn (callable): Function returning edge cost as float

49

50

Returns:

51

AllPairsPathMapping: Nested mapping of source -> target -> path

52

"""

53

54

def all_pairs_dijkstra_path_lengths(graph, edge_cost_fn):

55

"""

56

All-pairs shortest path lengths using Dijkstra's algorithm.

57

58

Parameters:

59

- graph: Input graph

60

- edge_cost_fn (callable): Function returning edge cost as float

61

62

Returns:

63

AllPairsPathLengthMapping: Nested mapping of source -> target -> length

64

"""

65

```

66

67

### Bellman-Ford Algorithm

68

69

Single-source shortest path algorithm supporting negative edge weights. Detects negative cycles and provides comprehensive error handling.

70

71

```python { .api }

72

def bellman_ford_shortest_paths(graph, source: int, target: int = None, weight_fn = None, default_weight: float = 1.0, as_undirected: bool = False):

73

"""

74

Find shortest paths using Bellman-Ford algorithm.

75

Supports negative edge weights and detects negative cycles.

76

77

Parameters:

78

- graph: PyGraph or PyDiGraph to search

79

- source (int): Source node index

80

- target (int, optional): Target node index

81

- weight_fn (callable, optional): Function to extract edge weight

82

- default_weight (float): Default edge weight

83

- as_undirected (bool): Treat directed graph as undirected

84

85

Returns:

86

PathMapping: Mapping of target nodes to paths

87

88

Raises:

89

NegativeCycle: When negative cycle is detected

90

"""

91

92

def bellman_ford_shortest_path_lengths(graph, node: int, edge_cost_fn, goal: int = None):

93

"""

94

Compute shortest path lengths using Bellman-Ford algorithm.

95

96

Parameters:

97

- graph: Input graph

98

- node (int): Source node index

99

- edge_cost_fn (callable): Function returning edge cost (can be negative)

100

- goal (int, optional): Target node

101

102

Returns:

103

PathLengthMapping: Mapping of target nodes to path lengths

104

105

Raises:

106

NegativeCycle: When negative cycle is detected

107

"""

108

109

def all_pairs_bellman_ford_shortest_paths(graph, edge_cost_fn):

110

"""

111

All-pairs shortest paths using Bellman-Ford algorithm.

112

113

Parameters:

114

- graph: Input graph

115

- edge_cost_fn (callable): Function returning edge cost

116

117

Returns:

118

AllPairsPathMapping: Nested mapping of source -> target -> path

119

120

Raises:

121

NegativeCycle: When negative cycle is detected

122

"""

123

124

def all_pairs_bellman_ford_path_lengths(graph, edge_cost_fn):

125

"""

126

All-pairs shortest path lengths using Bellman-Ford algorithm.

127

128

Parameters:

129

- graph: Input graph

130

- edge_cost_fn (callable): Function returning edge cost

131

132

Returns:

133

AllPairsPathLengthMapping: Nested mapping of source -> target -> length

134

135

Raises:

136

NegativeCycle: When negative cycle is detected

137

"""

138

```

139

140

### Floyd-Warshall Algorithm

141

142

All-pairs shortest path algorithm particularly effective for dense graphs. Supports parallel execution and multiple output formats.

143

144

```python { .api }

145

def floyd_warshall(graph, weight_fn = None, default_weight: float = 1.0, parallel_threshold: int = 300):

146

"""

147

All-pairs shortest paths using Floyd-Warshall algorithm.

148

149

Parameters:

150

- graph: Input graph

151

- weight_fn (callable, optional): Function to extract edge weight

152

- default_weight (float): Default edge weight

153

- parallel_threshold (int): Node count threshold for parallel execution

154

155

Returns:

156

AllPairsPathLengthMapping: Nested mapping of path lengths

157

"""

158

159

def floyd_warshall_numpy(graph, weight_fn = None, default_weight: float = 1.0, parallel_threshold: int = 300):

160

"""

161

Floyd-Warshall algorithm returning NumPy distance matrix.

162

163

Parameters:

164

- graph: Input graph

165

- weight_fn (callable, optional): Function to extract edge weight

166

- default_weight (float): Default edge weight

167

- parallel_threshold (int): Node count threshold for parallel execution

168

169

Returns:

170

numpy.ndarray: Distance matrix with np.inf for unreachable pairs

171

"""

172

173

def floyd_warshall_successor_and_distance(graph, weight_fn = None, default_weight: float = 1.0, parallel_threshold: int = 300):

174

"""

175

Floyd-Warshall returning both distance and successor matrices.

176

177

Parameters:

178

- graph: Input graph (PyDiGraph only)

179

- weight_fn (callable, optional): Function to extract edge weight

180

- default_weight (float): Default edge weight

181

- parallel_threshold (int): Node count threshold for parallel execution

182

183

Returns:

184

Tuple[numpy.ndarray, numpy.ndarray]: (distance_matrix, successor_matrix)

185

"""

186

```

187

188

### A* Algorithm

189

190

Heuristic shortest path algorithm using estimated costs to guide search toward target node. Optimal when heuristic is admissible.

191

192

```python { .api }

193

def astar_shortest_path(graph, node: int, goal_fn, edge_cost_fn, estimate_cost_fn):

194

"""

195

A* shortest path algorithm with heuristic guidance.

196

197

Parameters:

198

- graph: Input graph

199

- node (int): Starting node index

200

- goal_fn (callable): Function returning True for goal nodes

201

- edge_cost_fn (callable): Function returning non-negative edge cost

202

- estimate_cost_fn (callable): Heuristic function returning estimated cost to goal

203

204

Returns:

205

NodeIndices: List of node indices forming shortest path

206

"""

207

```

208

209

### Specialized Path Functions

210

211

Additional path-finding utilities for specific use cases and path enumeration.

212

213

```python { .api }

214

def all_simple_paths(graph, from_: int, to, min_depth: int = None, cutoff: int = None) -> list:

215

"""

216

Find all simple paths between nodes (no repeated nodes).

217

218

Parameters:

219

- graph: Input graph

220

- from_ (int): Source node index

221

- to (int or list): Target node(s)

222

- min_depth (int, optional): Minimum path length

223

- cutoff (int, optional): Maximum path length

224

225

Returns:

226

list: List of paths, each path is list of node indices

227

"""

228

229

def all_shortest_paths(graph, source: int, target: int, weight_fn = None, default_weight: float = 1.0, as_undirected: bool = False) -> list:

230

"""

231

Find all shortest paths between two specific nodes.

232

233

Parameters:

234

- graph: Input graph

235

- source (int): Source node index

236

- target (int): Target node index

237

- weight_fn (callable, optional): Function to extract edge weight

238

- default_weight (float): Default edge weight

239

- as_undirected (bool): Treat directed graph as undirected

240

241

Returns:

242

list: List of shortest paths (each path is list of node indices)

243

"""

244

245

def single_source_all_shortest_paths(graph, source: int, weight_fn = None, default_weight: float = 1.0, as_undirected: bool = False) -> dict:

246

"""

247

All shortest paths from single source to all other nodes.

248

249

Parameters:

250

- graph: Input graph

251

- source (int): Source node index

252

- weight_fn (callable, optional): Function to extract edge weight

253

- default_weight (float): Default edge weight

254

- as_undirected (bool): Treat directed graph as undirected

255

256

Returns:

257

dict: Mapping of target nodes to lists of shortest paths

258

"""

259

260

def k_shortest_path_lengths(graph, start: int, k: int, edge_cost, goal: int = None) -> dict:

261

"""

262

Compute lengths of k-th shortest paths.

263

264

Parameters:

265

- graph: Input graph

266

- start (int): Source node index

267

- k (int): Which shortest path to find (1st, 2nd, etc.)

268

- edge_cost (callable): Function returning edge cost

269

- goal (int, optional): Target node

270

271

Returns:

272

dict: Mapping of destination nodes to k-th shortest path length

273

"""

274

275

def has_path(graph, source: int, target: int, as_undirected: bool = False) -> bool:

276

"""

277

Check if path exists between two nodes.

278

279

Parameters:

280

- graph: Input graph

281

- source (int): Source node index

282

- target (int): Target node index

283

- as_undirected (bool): Treat directed graph as undirected

284

285

Returns:

286

bool: True if path exists, False otherwise

287

"""

288

```

289

290

### Distance and Connectivity Utilities

291

292

Functions for computing graph distances and analyzing connectivity patterns.

293

294

```python { .api }

295

def distance_matrix(graph, parallel_threshold: int = 300, as_undirected: bool = False, null_value: float = 0.0):

296

"""

297

Compute unweighted distance matrix (each edge has distance 1).

298

299

Parameters:

300

- graph: Input graph

301

- parallel_threshold (int): Node count for parallel execution

302

- as_undirected (bool): Treat directed graph as undirected

303

- null_value (float): Value for absent edges

304

305

Returns:

306

numpy.ndarray: Distance matrix

307

"""

308

309

def unweighted_average_shortest_path_length(graph, parallel_threshold: int = 300, disconnected: bool = False) -> float:

310

"""

311

Average shortest path length with unweighted edges.

312

313

Parameters:

314

- graph: Input graph

315

- parallel_threshold (int): Node count for parallel execution

316

- disconnected (bool): Include only connected pairs if True

317

318

Returns:

319

float: Average shortest path length

320

"""

321

322

def num_shortest_paths_unweighted(graph, source: int):

323

"""

324

Count unweighted shortest paths from source node.

325

326

Parameters:

327

- graph: Input graph

328

- source (int): Source node index

329

330

Returns:

331

NodesCountMapping: Mapping of target nodes to path counts

332

"""

333

```

334

335

## Usage Examples

336

337

### Basic Shortest Path Finding

338

339

```python

340

import rustworkx as rx

341

342

# Create weighted graph

343

graph = rx.PyGraph()

344

nodes = graph.add_nodes_from(['A', 'B', 'C', 'D'])

345

graph.add_edges_from([

346

(nodes[0], nodes[1], 4.0),

347

(nodes[1], nodes[2], 2.0),

348

(nodes[2], nodes[3], 3.0),

349

(nodes[0], nodes[3], 10.0)

350

])

351

352

# Find shortest paths from node 0

353

paths = rx.dijkstra_shortest_paths(graph, nodes[0])

354

print(f"Paths from A: {paths}")

355

356

# Get only path lengths

357

lengths = rx.dijkstra_shortest_path_lengths(

358

graph, nodes[0],

359

edge_cost_fn=lambda x: x

360

)

361

print(f"Path lengths: {lengths}")

362

```

363

364

### Handling Negative Weights

365

366

```python

367

# Graph with negative weights

368

digraph = rx.PyDiGraph()

369

nodes = digraph.add_nodes_from(['S', 'A', 'B', 'T'])

370

digraph.add_edges_from([

371

(nodes[0], nodes[1], 1.0),

372

(nodes[1], nodes[2], -3.0), # Negative weight

373

(nodes[2], nodes[3], 2.0),

374

(nodes[0], nodes[3], 5.0)

375

])

376

377

try:

378

paths = rx.bellman_ford_shortest_paths(

379

digraph, nodes[0],

380

weight_fn=lambda x: x

381

)

382

print(f"Shortest paths: {paths}")

383

except rx.NegativeCycle as e:

384

print(f"Negative cycle detected: {e}")

385

```

386

387

### A* Pathfinding with Heuristic

388

389

```python

390

# Grid graph for A* demonstration

391

def manhattan_distance(node_data, target_pos):

392

"""Manhattan distance heuristic."""

393

x1, y1 = node_data

394

x2, y2 = target_pos

395

return abs(x1 - x2) + abs(y1 - y2)

396

397

grid = rx.generators.grid_graph(5, 5)

398

target_node = 24 # Bottom-right corner

399

target_pos = (4, 4)

400

401

path = rx.astar_shortest_path(

402

grid,

403

node=0, # Top-left corner

404

goal_fn=lambda node: node == target_node,

405

edge_cost_fn=lambda edge: 1.0,

406

estimate_cost_fn=lambda node: manhattan_distance(node, target_pos)

407

)

408

print(f"A* path: {path}")

409

```

410

411

### All-Pairs Shortest Paths

412

413

```python

414

# Compute all-pairs shortest paths

415

all_paths = rx.all_pairs_dijkstra_shortest_paths(

416

graph,

417

edge_cost_fn=lambda x: x

418

)

419

420

# Access specific path

421

path_0_to_3 = all_paths[nodes[0]][nodes[3]]

422

print(f"Path from A to D: {path_0_to_3}")

423

424

# Get distance matrix for analysis

425

distances = rx.floyd_warshall_numpy(graph, weight_fn=lambda x: x)

426

print(f"Distance matrix:\n{distances}")

427

```