Skip to content

Commit

Permalink
One sentence per line
Browse files Browse the repository at this point in the history
and other doc formatting
  • Loading branch information
jjaderberg committed Oct 24, 2023
1 parent 56d224d commit d492135
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 19 deletions.
6 changes: 4 additions & 2 deletions doc/modules/ROOT/pages/algorithms/dag/dag-algorithms.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
Directed Acyclic Graphs (DAGs) are directed graphs that do not contain cycles.
These kind of graphs are commonly used to model dependencies between entities.

The canonical algorithm that goes hand in hand with DAGs is topological sort, for which GDS provides an efficient parallel implementation. Running topological sort is the best way to make sure the graph is a DAG.
The canonical algorithm that goes hand in hand with DAGs is topological sort, for which GDS provides an efficient parallel implementation.
Running topological sort is the best way to make sure the graph is a DAG.

Some of the problems that are computationally hard to solve in the general case can be solved efficiently when the scope is limited to DAGs. One of these is the longest path problem, for which GDS provides an efficient algorithm.
Some of the problems that are computationally hard to solve in the general case can be solved efficiently when the scope is limited to DAGs.
One of these is the longest path problem, for which GDS provides an efficient algorithm.

The Neo4j GDS library includes the following DAG algorithms:

Expand Down
30 changes: 19 additions & 11 deletions doc/modules/ROOT/pages/algorithms/dag/longest-path.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ include::partial$/operations-reference/alpha-note.adoc[]

Finding the longest path that leads to a node in a graph is possible to do in linear time for the special case of DAGs.

GDS implementation for this algorithm is based on topological sort and takes linear time. If the graph is not a DAG, the runtime is still linear, but the results cannot be trusted. You can use xref:algorithms/dag/topological-sort.adoc[topological sort] to make sure the graph is a DAG.
GDS implementation for this algorithm is based on topological sort and takes linear time.
If the graph is not a DAG, the runtime is still linear, but the results cannot be trusted.
You can use xref:algorithms/dag/topological-sort.adoc[topological sort] to make sure the graph is a DAG.

The algorithm supports weighted and unweighted graphs. Negative weights are currently unsupported.
The algorithm supports weighted and unweighted graphs.
Negative weights are currently unsupported.


=== Usage

One example for usage of this algorithm is in the context of a supply chain graph. If edges indicate the time to supply, then the distance of the longest path to a target node is the time required to manufacture the node from decision to completion.
One example for usage of this algorithm is in the context of a supply chain graph.
If edges indicate the time to supply, then the distance of the longest path to a target node is the time required to manufacture the node from decision to completion.


== Syntax
Expand Down Expand Up @@ -76,7 +80,6 @@ include::partial$/algorithms/common-configuration/common-stream-stats-configurat
| nodeIds | List of Integer | Node ids on the path in traversal order.
| costs | List of Float | Accumulated costs for each node on the path.
| path | Path | The path represented as Cypher entity.

|===

// include-with-stream
Expand Down Expand Up @@ -110,9 +113,13 @@ CREATE
----

This graph describes a simple supply chain of constructing a table in the Table Maker workshop.
In order to have lumber for the table, the workshop processes timber, which takes 1 day to complete. Once the lumber is ready, it is already in the workshop, therefor it takes zero time to ship it. However, the screws take 3 days to be shipped to the workshop. Only after the workshop has all the requirements met, the table can be constructed, a process that takes 1 day.
In order to have lumber for the table, the workshop processes timber, which takes 1 day to complete.
Once the lumber is ready, it is already in the workshop, therefor it takes zero time to ship it.
However, the screws take 3 days to be shipped to the workshop.
Only after the workshop has all the requirements met, the table can be constructed, a process that takes 1 day.

The longest path to the table node starts with the screws, then the workshop and then the table, in total: 4 days. This is the bottleneck path, and total time that takes to manufacture the table.
The longest path to the table node starts with the screws, then the workshop and then the table, in total: 4 days.
This is the bottleneck path, and total time that takes to manufacture the table.

.The following Cypher statement will project the graph to GDS:
[source, cypher, role=noplay setup-query]
Expand Down Expand Up @@ -147,16 +154,17 @@ RETURN
nodes(path) as path
ORDER BY index
----

We use the utility function `asNode` to return the name of node instead of its ID to make results more readable.

.Results
[opts="header"]
|===
| index | sourceNode | targetNode | totalCost | nodeNames | costs | path
| 0 | "Timber" | "Timber" | 0.0 | [Timber] | [0.0] | [Node[0]]
| 1 | "Timber" | "Lumber" | 1.0 | [Timber, Lumber] | [0.0, 1.0] | [Node[0], Node[1]]
| 2 | "Screws" | "Table Maker" | 3.0 | [Screws, Table Maker] | [0.0, 3.0] | [Node[2], Node[3]]
| 3 | "Screws" | "Screws" | 0.0 | [Screws] | [0.0] | [Node[2]]
| index | sourceNode | targetNode | totalCost | nodeNames | costs | path
| 0 | "Timber" | "Timber" | 0.0 | [Timber] | [0.0] | [Node[0]]
| 1 | "Timber" | "Lumber" | 1.0 | [Timber, Lumber] | [0.0, 1.0] | [Node[0], Node[1]]
| 2 | "Screws" | "Table Maker" | 3.0 | [Screws, Table Maker] | [0.0, 3.0] | [Node[2], Node[3]]
| 3 | "Screws" | "Screws" | 0.0 | [Screws] | [0.0] | [Node[2]]
| 4 | "Screws" | "Table" | 4.0 | [Screws, Table Maker, Table] | [0.0, 3.0, 4.0] | [Node[2], Node[3], Node[4]]
|===
--
26 changes: 20 additions & 6 deletions doc/modules/ROOT/pages/algorithms/dag/topological-sort.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ include::partial$/operations-reference/alpha-note.adoc[]
A topological sorting of nodes in a graph is an ordering of the nodes in the graph where every node appears only after all the nodes pointing to it have appeared.
For example, for a graph with 4 nodes and these relations: `a->b`, `a->c`, `b->d`, `c->d`, there are two acceptable topological sorts: `a, b, c, d` and `a, c, b, d`.

The topological order of the nodes is defined only for directed acyclic graphs (DAGs). See xref:#topological-sort-cycles[below] for the expected result for graphs with cycles.
The topological order of the nodes is defined only for directed acyclic graphs (DAGs).
See xref:#topological-sort-cycles[below] for the expected result for graphs with cycles.

GDS provides an efficient parallel implementation for this algorithm.


[[topological-sort-cycles]]
=== Cycles

Running the algorithm on a graph with cycles will cause the omitting of part of the nodes from the sorting. The omitted nodes are:
Running the algorithm on a graph with cycles will cause the omitting of part of the nodes from the sorting.
The omitted nodes are:

1. Nodes that are part of a cycle (including self cycles)

Expand All @@ -43,11 +45,17 @@ image::example-graphs/{image-file}[Visualization of the example graph,align="cen

=== Usage

Topological ordering of the nodes is beneficial when you want to guarantee a node will only be processed after its dependencies were processed. This is very useful for dependency related tasks such as scheduling or calculations that derive values from their dependencies.
Topological ordering of the nodes is beneficial when you want to guarantee a node will only be processed after its dependencies were processed.
This is very useful for dependency related tasks such as scheduling or calculations that derive values from their dependencies.


==== Cycles detection

The algorithm can also be used to determine if the graph contains a cycle or not. If all the nodes in the graph appear in the sorting, there is no cycle in the graph. If some of the nodes are missing from the sorting, there is a cycle. It does not tell which nodes constitute the cycle, but it does give a clue, as described in the xref:#topological-sort-cycles[cycles] section.
The algorithm can also be used to determine if the graph contains a cycle or not.
If all the nodes in the graph appear in the sorting, there is no cycle in the graph.
If some of the nodes are missing from the sorting, there is a cycle.
It does not tell which nodes constitute the cycle, but it does give a clue, as described in the xref:#topological-sort-cycles[cycles] section.


==== Maximum distance from source

Expand Down Expand Up @@ -106,6 +114,7 @@ include::partial$/algorithms/topological-sort/specific-configuration.adoc[]
// tabbed-example
====


== Examples

:algorithm-name: Topological Sort
Expand Down Expand Up @@ -133,7 +142,8 @@ CREATE
(n5)-[:REQUIRED]->(n6)
----

This graph describes a simplified supply chain of building a house. Each part of the house cannot be worked on before its requirements are met.
This graph describes a simplified supply chain of building a house.
Each part of the house cannot be worked on before its requirements are met.
For example, we cannot build support before getting the steel, the skeleton is not ready until both support and base are ready.

.The following Cypher statement will project the graph to GDS:
Expand All @@ -145,8 +155,11 @@ WITH gds.graph.project("g", n, target, {}) AS g
RETURN g
----


=== Stream
The stream procedure streams the nodes in the graph ordered by a valid topological order. The nodes can then be processed one by one, guaranteeing that each node is processed only after its dependencies were processed.

The stream procedure streams the nodes in the graph ordered by a valid topological order.
The nodes can then be processed one by one, guaranteeing that each node is processed only after its dependencies were processed.

For more details on the stream mode in general, see xref:common-usage/running-algos.adoc#running-algos-stream[Stream].

Expand All @@ -160,6 +173,7 @@ YIELD nodeId, maxDistanceFromSource
RETURN gds.util.asNode(nodeId).name AS name, maxDistanceFromSource
ORDER BY maxDistanceFromSource, name
----

We use the utility function `asNode` to return the name of node instead of its ID to make results more readable.

.Results
Expand Down

0 comments on commit d492135

Please sign in to comment.