Skip to content

MST #175

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open

MST #175

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
91 changes: 91 additions & 0 deletions algorithms/mst.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
title: "Minimum Spanning Tree (MST)"
description: "Minimum Spanning Tree (MST)"
parent: "Algorithms"
---

# Minimum Spanning Tree (MST)

## Overview

The Minimum Spanning Tree (MST) finds the relationships with minimum weights such that any weakly connected component in the graph stays connected. It treats all edges as bi-directional and ensures that any pair of nodes that previously shared a path will still share a unique path in the MST subgraph.

MST serves as a common algorithm in scenarios such as:
- Designing a cost-effective road network connecting several cities.
- Power Grid / Utility cost optimization.
- Identifying redundancies in networks.

## Algorithm Details

MST first assigns each node to its own component. It iteratively scans for the minimum edges linking nodes across different components and merges them, ignoring the direction of edges throughout the process. The algorithm terminates when no further merges occur, producing a collection of trees.

The procedure finds a minimum or maximum weight spanning tree based on the specified `objective` and optimizes for the given `weightAttribute`. If no attribute is given, MST returns any collection of spanning trees. If any specified edges do not have the given weight attribute, or the value of the attribute is non-numeric, then they are treated as if they had infinite weight. Such an edge would only be included in the minimum spanning tree if no other edges with a valid weight attribute bridge the components it connects.

Comment on lines +20 to +23
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Infinite-weight rule is ambiguous for objective: "maximize"
Treating missing / non-numeric weights as “infinite” works for minimisation, but for maximisation you actually want them to behave as negative infinity so they never get selected. Spell this out (or state that they are excluded) to avoid user confusion & silent logic bugs.

-If any specified edges do not have the given weight attribute, or the value of the attribute is non-numeric, then they are treated as if they had infinite weight.
+If an edge lacks the attribute or the value is non-numeric, it is treated as:
+* `+∞` when `objective = "minimize"`  
+* `−∞` (effectively excluded) when `objective = "maximize"`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
MST first assigns each node to its own component. It iteratively scans for the minimum edges linking nodes across different components and merges them, ignoring the direction of edges throughout the process. The algorithm terminates when no further merges occur, producing a collection of trees.
The procedure finds a minimum or maximum weight spanning tree based on the specified `objective` and optimizes for the given `weightAttribute`. If no attribute is given, MST returns any collection of spanning trees. If any specified edges do not have the given weight attribute, or the value of the attribute is non-numeric, then they are treated as if they had infinite weight. Such an edge would only be included in the minimum spanning tree if no other edges with a valid weight attribute bridge the components it connects.
The procedure finds a minimum or maximum weight spanning tree based on the specified `objective` and optimizes for the given `weightAttribute`. If no attribute is given, MST returns any collection of spanning trees.
If an edge lacks the attribute or the value is non-numeric, it is treated as:
* `+∞` when `objective = "minimize"`
* `−∞` (effectively excluded) when `objective = "maximize"`.
Such an edge would only be included in the minimum spanning tree if no other edges with a valid weight attribute bridge the components it connects.
🤖 Prompt for AI Agents
In algorithms/mst.md around lines 20 to 23, clarify the handling of missing or
non-numeric weight attributes for the "maximize" objective. Update the text to
specify that for maximization, such edges should be treated as having negative
infinity weight or be excluded entirely, ensuring they are never selected. This
will prevent ambiguity and potential logic errors when maximizing the spanning
tree weight.

## Syntax

```cypher
CALL algo.mst([config])
```

### Parameters

The procedure accepts an optional configuration `Map` with the following optional parameters:

| Name | Type | Default | Description |
|---------------------|--------|------------------------|----------------------------------------------------------------------------|
| `nodeLabels` | Array | All labels | Array of node labels to filter which nodes are included in the computation |
| `relationshipTypes` | Array | All relationship types | Array of relationship types to define which edges are traversed |
| `objective` | string | 'minimize' | 'minimize' or 'maximize' what to optimize in the spanning tree |
| `weightAttribute` | string | Unweighted | the attribute to use as the tree weight. |

### Return Values
The procedure returns a stream of records with the following fields:

| Name | Type | Description |
|----------|--------|-----------------------------------------------|
| `edge` | Edge | An edge entity which is part of the MST graph |
| `weight` | Double | The weight of the Edge |




### Create the Graph

```cypher
CREATE
(CityHall:GOV),
(CourtHouse:GOV),
(FireStation:GOV),
(Electricity:UTIL),
(Water:UTIL),
(Building_A:RES),
(Building_B:RES),
(CityHall)-[rA:ROAD {cost: 2.2}]->(CourtHouse),
(CityHall)-[rB:ROAD {cost: 8.0}]->(FireStation),
(CourtHouse)-[rC:ROAD {cost: 3.4}]->(Building_A),
(FireStation)-[rD:ROAD {cost: 3.0}]->(Building_B),
(Building_A)-[rF:ROAD {cost: 5.2}]->(Building_B),
(Electricity)-[rG:ROAD {cost: 0.7}]->(Building_A),
(Water)-[rH:ROAD {cost: 2.3}]->(Building_B),
(CityHall)-[tA:TRAM {cost: 1.5}]->(Building_A),
(CourtHouse)-[tB:TRAM {cost: 7.3}]->(Building_B),
(FireStation)-[tC:TRAM {cost: 1.2}]->(Electricity)
RETURN *
```

## Examples:

Suppose you are an urban planner tasked with designing a new transportation network for a town. There are several vital buildings that must be connected by this new network. A cost estimator has already provided you with the estimated cost for some of the potential routes between these buildings.

Your goal is to connect every major building with the lowest total cost, even if travel between some buildings requires multiple stops and different modes of transport. The Minimum Spanning Tree algorithm helps you achieve this by identifying the most cost-effective network.

![City Graph](../images/city_plan.png)

```cypher
CALL algo.mst({weightAttribute: 'cost'}) YIELD edge, weight
```

#### Expected Results
The algorithm would yeild the following edge objects and their weights:

Comment on lines +88 to +90
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Heading level jump & spelling error break CI

  • #### Expected Results skips a level (MD001).
  • “yeild” → “yield” fails the spell-checker.
-#### Expected Results
-The algorithm would yeild the following edge objects and their weights:
+### Expected Results
+The algorithm would yield the following edge objects and their weights:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#### Expected Results
The algorithm would yeild the following edge objects and their weights:
### Expected Results
The algorithm would yield the following edge objects and their weights:
🧰 Tools
🪛 LanguageTool

[grammar] ~89-~89: Ensure spelling is correct
Context: ...## Expected Results The algorithm would yeild the following edge objects and their we...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.17.2)

88-88: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)

🤖 Prompt for AI Agents
In algorithms/mst.md around lines 88 to 90, fix the heading level by changing
the heading from #### to ### or another appropriate level to avoid skipping
levels, and correct the spelling mistake by replacing "yeild" with "yield" to
pass the spell-checker.

![City MST Graph](../images/city_mst.png)
Binary file added images/city_mst.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/city_plan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading