Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -798,4 +798,6 @@ PyG
pyg
NeighborLoader
GraphSAGE

subgraph
maxFlow
modelled
5 changes: 5 additions & 0 deletions algorithms/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ This overview summarizes the available algorithms and links to their individual
- [Pathfinding Algorithms](#pathfinding-algorithms)
- [Centrality Measures](#centrality-measures)
- [Community Detection](#community-detection)
- [Network Flow Algorithms](#network-flow-algorithms)

---

Expand Down Expand Up @@ -55,3 +56,7 @@ For path expressions like `shortestPath()` used directly in Cypher queries, refe
- **[CDLP (Community Detection Label Propagation)](./cdlp.md)**
Detects communities in a network, by propagating labels through the graph structure.

## Network Flow Algorithms

- **[MaxFlow](./maxflow.md)**
Comment thread
swilly22 marked this conversation as resolved.
Computes the maximum amount of flow that can be routed through a directed, weighted graph from one or more **source** nodes to one or more **sink** (target) nodes.
175 changes: 175 additions & 0 deletions algorithms/maxflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
---
title: "Max Flow"
description: "Max Flow"
parent: "Algorithms"
nav_order: 8
---

# Max Flow

## Overview

The Max Flow algorithm computes the maximum amount of flow that can be routed through a directed, weighted graph from one or more **source** nodes to one or more **sink** (target) nodes. Edge weights represent capacities — the upper bound on how much flow an edge can carry.

Max Flow is commonly applied in scenarios such as:
- Network throughput optimization (bandwidth, pipelines, logistics)
- Traffic routing and congestion analysis
- Supply chain and distribution planning
- Bipartite matching and scheduling problems

## Algorithm Details

The procedure implements a capacity-scaling max-flow algorithm over the subgraph induced by the specified node labels and relationship types. It builds a residual graph from the selected edges (using the configured capacity property), then repeatedly finds augmenting paths from the source super-node to the sink super-node and pushes flow along them until no augmenting path exists.

Multiple source or sink nodes are supported by introducing a virtual super-source connected to every source node, and a virtual super-sink connected from every sink node, each with infinite capacity.

The algorithm returns the set of nodes and edges that carry positive flow, together with the per-edge flow values and the total maximum flow.

### Performance

The algorithm operates with a time complexity of **O(V · E²)**, where:
- **|V|** represents the total number of nodes in the subgraph
- **|E|** represents the total number of edges in the subgraph

Comment thread
swilly22 marked this conversation as resolved.
For sparse graphs this is typically much faster in practice.

## Syntax

```cypher
CALL algo.maxFlow(config)
YIELD nodes, edges, edgeFlows, maxFlow
```

### Parameters

The procedure accepts a required configuration `Map` with the following parameters:

| Name | Type | Default | Description |
|----------------------|--------|---------------|-----------------------------------------------------------------------------|
| `sourceNodes` | Array | *(required)* | One or more node objects that act as flow sources |
| `targetNodes` | Array | *(required)* | One or more node objects that act as flow sinks |
| `relationshipTypes` | Array | *(required)* | Relationship types that define the edges of the flow network |
| `capacityProperty` | String | `'capacity'` | Name of the numeric edge property used as the edge capacity |
| `nodeLabels` | Array | All labels | Array of node labels used to restrict which nodes are included |

### Return Values

The procedure yields a single record with the following fields:

| Name | Type | Description |
|-------------|---------|------------------------------------------------------------------------------------|
| `nodes` | Array | All node entities that participate in the max-flow solution (carry positive flow) |
| `edges` | Array | All edge entities that carry positive flow |
| `edgeFlows` | Array | Numeric flow value for each edge in `edges`, in the same order |
| `maxFlow` | Integer | The total maximum flow from all source nodes to all sink nodes |

## Examples

Consider this pipeline network:

```
(A) --[cap:10]--> (B) --[cap:8]--> (C)
\ ^
\----------[cap:5]---------------/
```
Comment on lines +70 to +74
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language tag to the fenced diagram block.

This fence is missing a language identifier, which triggers markdownlint MD040.

Suggested fix
-```
+```text
 (A) --[cap:10]--> (B) --[cap:8]--> (C)
  \                                  ^
   \----------[cap:5]---------------/
</details>

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.21.0)</summary>

[warning] 70-70: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @algorithms/maxflow.md around lines 70 - 74, The fenced diagram block
containing "(A) --[cap:10]--> (B) --[cap:8]--> (C)" is missing a language tag
which triggers markdownlint MD040; update that fenced code block (the
triple-backtick fence that wraps the diagram) to include a language identifier
such as "text" (i.e., change totext) so the diagram block is properly
tagged.


</details>

<!-- fingerprinting:phantom:triton:hawk -->

<!-- This is an auto-generated comment by CodeRabbit -->


Node **A** is the source, node **C** is the sink. There are two routes from A to C:
- **A → C** directly, with capacity 5
- **A → B → C**, with a bottleneck of 8 (min of 10 and 8)

The maximum flow is therefore **13**.

### Create the Graph

```cypher
CREATE
(a:Node {name: 'A'}),
(b:Node {name: 'B'}),
(c:Node {name: 'C'}),

(a)-[:PIPE {cap: 10}]->(b),
(a)-[:PIPE {cap: 5}]->(c),
(b)-[:PIPE {cap: 8}]->(c)
```

### Example: Compute the maximum flow between two nodes

```cypher
MATCH (s:Node {name: 'A'}), (t:Node {name: 'C'})
CALL algo.maxFlow({
sourceNodes: [s],
targetNodes: [t],
capacityProperty: 'cap',
relationshipTypes: ['PIPE']
})
YIELD nodes, edges, edgeFlows, maxFlow
RETURN maxFlow
```

#### Expected Results

| maxFlow |
|---------|
| `13` |

### Example: Inspect per-edge flow on the solution

```cypher
MATCH (s:Node {name: 'A'}), (t:Node {name: 'C'})
CALL algo.maxFlow({
sourceNodes: [s],
targetNodes: [t],
capacityProperty: 'cap',
relationshipTypes: ['PIPE']
})
YIELD edges, edgeFlows
UNWIND range(0, size(edges) - 1) AS i
RETURN
startNode(edges[i]).name AS from,
endNode(edges[i]).name AS to,
edgeFlows[i] AS flow
```

#### Expected Results

| from | to | flow |
|------|-----|------|
| `A` | `B` | `8` |
| `A` | `C` | `5` |
| `B` | `C` | `8` |

### Example: Restrict the subgraph by node label

When the graph contains multiple node labels, use `nodeLabels` to limit the algorithm to a specific subset of nodes:

```cypher
MATCH (s:Intersection {name: 'Source'}), (t:Intersection {name: 'Sink'})
CALL algo.maxFlow({
sourceNodes: [s],
targetNodes: [t],
capacityProperty: 'bandwidth',
nodeLabels: ['Intersection'],
relationshipTypes: ['CONNECTS']
})
YIELD nodes, maxFlow
RETURN size(nodes) AS participatingNodes, maxFlow
```

### Example: Multiple sources and multiple sinks

`sourceNodes` and `targetNodes` each accept arrays, allowing multi-commodity-style problems to be modelled with virtual super-nodes:

```cypher
MATCH
(s1:Node {name: 'SourceA'}),
(s2:Node {name: 'SourceB'}),
(t:Node {name: 'Sink'})
CALL algo.maxFlow({
sourceNodes: [s1, s2],
targetNodes: [t],
capacityProperty: 'cap',
relationshipTypes: ['PIPE']
})
YIELD maxFlow
RETURN maxFlow
```
Loading