-
Notifications
You must be signed in to change notification settings - Fork 8
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
base: main
Are you sure you want to change the base?
MST #175
Changes from 11 commits
f1d4a21
5c7a778
a894f34
b59f0eb
1acf46c
1142822
06e3b0b
60ec0e5
5669659
50d3f6b
b830655
1a67691
d39d253
f1d9fed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -74,6 +74,7 @@ LocalDateTime | |
| LocalTime | ||
| Lovitz | ||
| MEM | ||
| MSF | ||
| Miesha | ||
| MotoGP | ||
| NRedisGraph | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,21 @@ | ||
| --- | ||
|
|
||
| title: "MSF" | ||
| description: "Minimum Spanning Forest Algorithm" | ||
| parent: "Algorithms" | ||
| nav_order: 9 | ||
| --- | ||
|
|
||
| # Minimum Spanning Forest (MSF) | ||
|
|
||
| The Minimum Spanning Forest algorithm computes the minimum spanning forest of a graph. A minimum spanning forest is a collection of minimum spanning trees, one for each connected component in the graph. | ||
| The Minimum Spanning Forest algorithm computes the minimum spanning forest of a | ||
| graph. A minimum spanning forest is a collection of minimum spanning trees, one | ||
| for each connected component in the graph. | ||
|
|
||
| ## What is a Minimum Spanning Forest? | ||
|
|
||
| ## What is a Minimum Spanning Forest? | ||
| - For a **connected graph**, the MSF is a single minimum spanning tree (MST) that connects all nodes with the minimum total edge weight | ||
| - For a **disconnected graph**, the MSF consists of multiple MSTs, one for each connected component | ||
| - The forest contains no cycles and has exactly `N - C` edges, where `N` is the number of nodes and `C` is the number of connected components | ||
| - The sum of the weights of the edges in the forest is minimized | ||
|
|
||
| ## Use Cases | ||
|
|
||
|
|
@@ -27,122 +29,68 @@ The Minimum Spanning Forest algorithm computes the minimum spanning forest of a | |
| ```cypher | ||
| CALL algo.MSF( | ||
| config: MAP | ||
| ) YIELD src, dest, weight, relationshipType | ||
| ) YIELD edges, nodes | ||
| ``` | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ### Parameters | ||
|
|
||
| | Parameter | Type | Description | | ||
| |-----------|------|-------------| | ||
| | `config` | MAP | Configuration map containing algorithm parameters | | ||
|
|
||
| #### Configuration Options | ||
|
|
||
| | Option | Type | Required | Default | Description | | ||
| |--------|------|----------|---------|-------------| | ||
| | `sourceNodes` | List of Nodes | No | All nodes | Starting nodes for the algorithm. If not provided, all nodes in the graph are considered | | ||
| | `relationshipTypes` | List of Strings | No | All types | Relationship types to traverse. If not provided, all relationship types are considered | | ||
| | `relationshipWeightProperty` | String | No | `null` | Property name containing edge weights. If not specified, all edges have weight 1.0 | | ||
| | `defaultValue` | Float | No | `1.0` | Default weight for edges that don't have the weight property | | ||
| The procedure accepts an optional configuration `Map` with the following optional parameters: | ||
|
|
||
| ### Returns | ||
| | 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. | | ||
|
|
||
| | Field | Type | Description | | ||
| |-------|------|-------------| | ||
| | `src` | Node | Source node of the edge in the spanning forest | | ||
| | `dest` | Node | Destination node of the edge in the spanning forest | | ||
| | `weight` | Float | Weight of the edge | | ||
| | `relationshipType` | String | Type of the relationship | | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Example 1: Basic MSF with Unweighted Graph | ||
|
|
||
| Find the minimum spanning forest treating all edges equally: | ||
|
|
||
| ```cypher | ||
| CALL algo.MSF({}) YIELD src, dest, weight, relationshipType | ||
| RETURN src.name AS source, dest.name AS destination, weight, relationshipType | ||
| ``` | ||
| ### Return Values | ||
| The procedure returns a stream of records corresponding to each tree in the forest with the following fields: | ||
|
|
||
| ### Example 2: MSF with Weighted Edges | ||
| | Name | Type | Description | | ||
| |---------|------|----------------------------------| | ||
| | `edges` | List | The edges that connect each tree | | ||
| | `nodes` | List | The nodes in the tree | | ||
|
|
||
| Consider a graph representing cities connected by roads with distances: | ||
| ### Create the Graph | ||
|
|
||
| ```cypher | ||
| // Create a weighted graph | ||
| CREATE (a:City {name: 'A'}), (b:City {name: 'B'}), (c:City {name: 'C'}), | ||
| (d:City {name: 'D'}), (e:City {name: 'E'}) | ||
| CREATE (a)-[:ROAD {distance: 2}]->(b), | ||
| (a)-[:ROAD {distance: 3}]->(c), | ||
| (b)-[:ROAD {distance: 1}]->(c), | ||
| (b)-[:ROAD {distance: 4}]->(d), | ||
| (c)-[:ROAD {distance: 5}]->(d), | ||
| (d)-[:ROAD {distance: 6}]->(e) | ||
|
|
||
| // Find minimum spanning forest using distance weights | ||
| CALL algo.MSF({ | ||
| relationshipWeightProperty: 'distance' | ||
| }) YIELD src, dest, weight | ||
| RETURN src.name AS from, dest.name AS to, weight AS distance | ||
| ORDER BY weight | ||
| ``` | ||
|
|
||
| **Result:** | ||
| ```text | ||
| from | to | distance | ||
| -----|----|--------- | ||
| B | C | 1.0 | ||
| A | B | 2.0 | ||
| A | C | 3.0 | ||
| B | D | 4.0 | ||
| D | E | 6.0 | ||
| 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 * | ||
| ``` | ||
|
|
||
| ### Example 3: MSF on Specific Relationship Types | ||
| ## Examples: | ||
|
|
||
| Find the spanning forest considering only specific relationship types: | ||
|
|
||
| ```cypher | ||
| CALL algo.MSF({ | ||
| relationshipTypes: ['ROAD', 'HIGHWAY'], | ||
| relationshipWeightProperty: 'distance' | ||
| }) YIELD src, dest, weight, relationshipType | ||
| RETURN src.name AS from, dest.name AS to, weight, relationshipType | ||
| ``` | ||
| 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. | ||
|
|
||
| ### Example 4: MSF Starting from Specific Nodes | ||
| 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 Forest algorithm helps you achieve this by identifying the most cost-effective network. | ||
|
|
||
| Compute the spanning forest starting from a subset of nodes: | ||
|  | ||
|
|
||
| ```cypher | ||
| MATCH (start:City) WHERE start.name IN ['A', 'B'] | ||
| WITH collect(start) AS startNodes | ||
| CALL algo.MSF({ | ||
| sourceNodes: startNodes, | ||
| relationshipWeightProperty: 'distance' | ||
| }) YIELD src, dest, weight | ||
| RETURN src.name AS from, dest.name AS to, weight | ||
| CALL algo.MSF({weightAttribute: 'cost'}) YIELD edge, weight | ||
| ``` | ||
|
Comment on lines
87
to
89
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. CRITICAL: Example YIELD clause contradicts documented and actual API. Line 87 shows Update the example to match the actual API: ```cypher
-CALL algo.MSF({weightAttribute: 'cost'}) YIELD edge, weight
+CALL algo.MSF({weightAttribute: 'cost'}) YIELD src, dest, weight, relationshipType
+RETURN src, dest, weight, relationshipTypeIn algorithms/msf.md around lines 86 to 88, the example YIELD clause is |
||
|
|
||
| ### Example 5: Disconnected Graph | ||
|
|
||
| For a graph with multiple components, MSF returns multiple trees: | ||
|
|
||
| ```cypher | ||
| // Create two disconnected components | ||
| CREATE (a:Node {name: 'A'})-[:CONNECTED {weight: 1}]->(b:Node {name: 'B'}), | ||
| (b)-[:CONNECTED {weight: 2}]->(c:Node {name: 'C'}), | ||
| (x:Node {name: 'X'})-[:CONNECTED {weight: 3}]->(y:Node {name: 'Y'}) | ||
|
|
||
| // Find MSF | ||
| CALL algo.MSF({ | ||
| relationshipWeightProperty: 'weight' | ||
| }) YIELD src, dest, weight | ||
| RETURN src.name AS from, dest.name AS to, weight | ||
| ``` | ||
| #### Expected Results | ||
coderabbitai[bot] marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| The algorithm would yield a single tree containing the following edge and node objects: | ||
|
|
||
| **Result:** Two separate trees (A-B-C and X-Y) | ||
|  | ||
|
|
||
| ## Algorithm Details | ||
|
|
||
|
|
@@ -161,9 +109,8 @@ FalkorDB's MSF implementation uses an efficient matrix-based approach optimized | |
| ## Best Practices | ||
|
|
||
| 1. **Weight Properties**: Ensure weight properties are numeric (integers or floats) | ||
| 2. **Missing Weights**: Use `defaultValue` to handle edges without weight properties | ||
| 3. **Large Graphs**: For large graphs (100K+ nodes), consider filtering by `sourceNodes` or `relationshipTypes` | ||
| 4. **Directed vs Undirected**: The algorithm treats relationships as undirected for spanning forest purposes | ||
| 2. **Missing Weights**: Edges without the specified weight property will only be included in the tree if there are no other edges that could be used to connect the connected component | ||
| 4. **Directed vs Undirected**: The algorithm treats all relationships as undirected for spanning forest purposes | ||
|
|
||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ## Related Algorithms | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: FalkorDB/docs
Length of output: 586
🏁 Script executed:
Repository: FalkorDB/docs
Length of output: 446
🏁 Script executed:
Repository: FalkorDB/docs
Length of output: 446
🏁 Script executed:
Repository: FalkorDB/docs
Length of output: 173
🏁 Script executed:
Repository: FalkorDB/docs
Length of output: 3656
🏁 Script executed:
Repository: FalkorDB/docs
Length of output: 1172
🏁 Script executed:
Repository: FalkorDB/docs
Length of output: 1884
🌐 Web query:
FalkorDB algo.MSF YIELD signature official API documentation💡 Result:
Signature (from official docs):
CALL algo.MSF(config: MAP) YIELD src, dest, weight, relationshipType. [1]
Where:
Sources: FalkorDB algorithm docs (MSF) and Procedures overview. [1] https://docs.falkordb.com/algorithms/msf.html [2] https://docs.falkordb.com/cypher/procedures.html
🌐 Web query:
FalkorDB Minimum Spanning Forest algorithm procedure yields fields💡 Result:
FalkorDB's MSF procedure (CALL algo.MSF(...)) yields these fields: src, dest, weight, relationshipType. [1][2]
Sources:
CRITICAL: Procedure signature and examples do not match the official FalkorDB API.
The official FalkorDB MSF procedure yields
src, dest, weight, relationshipType—notedges, nodes. This affects multiple sections:YIELD edges, nodes(incorrect)edgesandnodes(incorrect)YIELD edge, weight(also incorrect)Update all three sections to reflect the actual API:
```cypher CALL algo.MSF( config: MAP -) YIELD edges, nodes +) YIELD src, dest, weight, relationshipTypeIn algorithms/msf.md around lines 29–32, 49–52 and 87, the MSF procedure
signature and examples use incorrect yield names; replace the incorrect "YIELD
edges, nodes" at lines 29–32 with "YIELD src, dest, weight, relationshipType",
update the Return Values table at lines 49–52 to list src (Node), dest (Node),
weight (Float), relationshipType (String) with the provided descriptions, and
change the example at line 87 from "YIELD edge, weight" to "YIELD src, dest,
weight, relationshipType".