Skip to content
This repository was archived by the owner on Apr 22, 2020. It is now read-only.

Commit 32cad11

Browse files
jjaderbergmneedham
authored andcommitted
Prepare to publish docs (#641)
* Add new search; update some CSS * Add abstracts to chapters * Add task to generate complete toc / content map * Chunk from content map * Provide section IDs; alight content map * Fix broken xref * Add more IDs * Format source properly; and some content fixes
1 parent c5f007a commit 32cad11

21 files changed

+1092
-835
lines changed

doc/asciidoc/algorithms.adoc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
[[algorithms]]
22
= Algorithms
33

4+
ifdef::env-docs[]
5+
[abstract]
6+
--
7+
This chapter provides explanations and examples for each of the algorithms in the Neo4j Graph Algorithms library.
8+
--
9+
endif::env-docs[]
10+
411
Graph algorithms are used to compute metrics for graphs, nodes, or relationships.
512

613
They can provide insights on relevant entities in the graph (centralities, ranking), or inherent structures like communities (community-detection, graph-partitioning, clustering).
Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
[[algorithm-all-pairs-shortest-path]]
12
= The All Pairs Shortest Path algorithm
23

34
// tag::introduction[]
45
The All Pairs Shortest Path (APSP) calculates the shortest (weighted) path between all pairs of nodes.
56
This algorithm has optimisations that make it quicker than calling the Single Source Shortest Path algorithm for every pair of nodes in the graph.
6-
77
// end::introduction[]
88

9+
10+
[[algorithm-all-pairs-shortest-path-context]]
911
== History and explanation
1012

1113
// tag::explanation[]
@@ -15,38 +17,34 @@ In this scenario, the algorithm will return `Infinity` value as a result between
1517

1618
Plain cypher does not support filtering `Infinity` values, so `algo.isFinite` function was added to help filter `Infinity` values from results.
1719

20+
21+
[[algorithm-all-pairs-shortest-path-usecase]]
1822
== Use-cases - when to use the All Pairs Shortest Path algorithm
1923

2024
// tag::use-case[]
2125

2226
* The All Pairs Shortest Path algorithm is used in urban service system problems, such as the location of urban facilities or the distribution or delivery of goods.
23-
One example of this is determining the traffic load expected on different segments of a transportation grid.
24-
For more information, see http://web.mit.edu/urban_or_book/www/book/[Urban Operations Research^].
25-
27+
One example of this is determining the traffic load expected on different segments of a transportation grid.
28+
For more information, see http://web.mit.edu/urban_or_book/www/book/[Urban Operations Research^].
2629
* All pairs shortest path is used as part of the REWIRE data center design algorithm that finds a network with maximum bandwidth and minimal latency.
27-
There are more details about this approach in https://cs.uwaterloo.ca/research/tr/2011/CS-2011-21.pdf["REWIRE: An Optimization-based Framework for Data Center Network Design"^]
30+
There are more details about this approach in https://cs.uwaterloo.ca/research/tr/2011/CS-2011-21.pdf["REWIRE: An Optimization-based Framework for Data Center Network Design"^]
2831

2932
// end::use-case[]
3033

31-
// == Constraints - when not to use the All Pairs Shortest Path algorithm
32-
33-
// tag::constraint[]
34-
35-
// end::constraint[]
36-
3734

35+
[[algorithm-all-pairs-shortest-path-sample]]
3836
== All Pairs Shortest Path algorithm sample
3937

4038
image::sssp.png[]
4139

4240
.The following will create a sample graph:
43-
[source,cypher]
41+
[source, cypher]
4442
----
4543
include::scripts/single-shortest-path.cypher[tag=create-sample-graph]
4644
----
4745

4846
.The following will run the algorithm and stream results:
49-
[source,cypher]
47+
[source, cypher]
5048
----
5149
include::scripts/single-shortest-path.cypher[tag=all-pairs-sample-graph]
5250
----
@@ -56,19 +54,17 @@ include::scripts/single-shortest-path.cypher[tag=all-pairs-sample-graph]
5654
[opts="header",cols="1,1,1"]
5755
|===
5856
| Source | Target | Cost
59-
| A | F | 100
60-
| C | F | 90
61-
| B | F | 90
62-
| A | E | 80
63-
| C | E | 70
64-
| B | E | 80
65-
| A | B | 50
66-
| D | F | 50
67-
| A | C | 50
68-
| A | D | 50
69-
57+
| A | F | 100
58+
| C | F | 90
59+
| B | F | 90
60+
| A | E | 80
61+
| C | E | 70
62+
| B | E | 80
63+
| A | B | 50
64+
| D | F | 50
65+
| A | C | 50
66+
| A | D | 50
7067
|===
71-
7268
// end::all-pairs-stream-sample-graph-result[]
7369

7470
// tag::all-pairs-stream-sample-graph-explanation[]
@@ -84,22 +80,24 @@ Note that relationship query does not specify direction of the relationship.
8480
This is applicable to all other algorithms that use Cypher loading.
8581

8682
.The following will run the algorithm, treating the graph as undirected:
87-
[source,cypher]
83+
[source, cypher]
8884
----
8985
include::scripts/single-shortest-path.cypher[tag=all-pairs-bidirected-graph]
9086
----
9187

88+
9289
== Huge graph projection
9390

9491
If our projected graph contains more than 2 billion nodes or relationships, we need to use huge graph projection, as the default label and relationship-type projection has a limitation of 2 billion nodes and 2 billion relationships.
9592

9693
.Set `graph:'huge'` in the config:
9794

98-
[source,cypher]
95+
[source, cypher]
9996
----
10097
include::scripts/single-shortest-path.cypher[tag=all-pairs-huge-projection]
10198
----
10299

100+
103101
== Implementations
104102

105103
`algo.allShortestPaths.stream`
@@ -112,6 +110,7 @@ include::scripts/single-shortest-path.cypher[tag=all-pairs-huge-projection]
112110
ifdef::implementation[]
113111
// tag::implementation[]
114112

113+
115114
ifndef::env-docs[]
116115
== References
117116

@@ -121,25 +120,25 @@ ifndef::env-docs[]
121120
// end::references[]
122121
endif::env-docs[]
123122

123+
124124
== Implementation details
125125

126126
:leveloffset: +1
127127

128+
128129
== Details
129130

131+
130132
=== algo.allShortestPaths.stream
131133

132-
- returns a stream of source-target node to distance tuples for each pair of nodes
133-
- Since all nodeId's have already been ordered by the idMapping we can use an integer
134-
instead of a queue which just count's up for each startNodeId as long as it is
135-
< nodeCount.
134+
- Returns a stream of source-target node to distance tuples for each pair of nodes
135+
- Since all nodeId's have already been ordered by the idMapping we can use an integer instead of a queue which just counts up for each startNodeId as long as it is < nodeCount.
136136
- Each thread tries to take one int from the counter at one time and starts its computation on it.
137137
- The {@link AllShortestPaths#concurrency} value determines the count of workers that should be spawned.
138-
- Due to the high memory footprint the result set would have we emit each result into
139-
a blocking queue. The result stream takes elements from the queue while the workers
140-
add elements to it.
138+
- Due to the high memory footprint the result set would have we emit each result into a blocking queue.
139+
The result stream takes elements from the queue while the workers add elements to it.
141140
- The result stream is limited by N^2. If the stream gets closed prematurely the workers get closed too.
142-
- writeback not supported!
141+
- Writeback not supported!
143142

144143
// end::implementation[]
145144
endif::implementation[]

doc/asciidoc/astar.adoc

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1+
[[algorithms-a_star]]
12
= The A* algorithm
23

34
// tag::introduction[]
4-
55
The A* (pronounced “A-star”) algorithm improves on the classic Dijkstra algorithm.
66
It is based upon the observation that some searches are informed, and that by being informed we can make better choices over which paths to take through the graph.
7-
87
// end::introduction[]
98

9+
10+
[[algorithms-a_star-context]]
1011
== History and explanation
1112

1213
// tag::explanation[]
13-
1414
The A* algorithm was first described in 1968 by Peter Hart, Nils Nilsson, and Bertram Raphael.
1515
For more information, see https://ieeexplore.ieee.org/document/4082128/[A Formal Basis for the Heuristic Determination of Minimum Cost Paths].
1616

@@ -25,33 +25,28 @@ In A*, we split the path cost into two parts:
2525
The A* algorithm balances `g(n)` and `h(n)` as it iterates the graph, thereby ensuring that at each iteration it chooses the node with the lowest overall cost `f(n) = g(n) + h(n)`.
2626

2727
In our implementation, geospatial distance is used as heurestic.
28-
2928
// end::explanation[]
3029

30+
31+
[[algorithms-a_star-usecase]]
3132
== Use-cases - when to use the A* algorithm
3233

3334
// tag::use-case[]
34-
3535
* The A* algorithm can be used to find shortest paths between single pairs of locations, where GPS coordinates are known.
36-
3736
// end::use-case[]
3837

39-
// == Constraints - when not to use the A* algorithm
40-
41-
// tag::constraint[]
42-
43-
// end::constraint[]
4438

39+
[[algorithms-a_star-sample]]
4540
== A* algorithm sample
4641

4742
.The following will create a sample graph:
48-
[source,cypher]
43+
[source, cypher]
4944
----
5045
include::scripts/astar.cypher[tag=create-sample-graph]
5146
----
5247

5348
.The following will run the algorithm and stream results:
54-
[source,cypher]
49+
[source, cypher]
5550
----
5651
include::scripts/astar.cypher[tag=stream-sample-graph]
5752
----
@@ -60,47 +55,50 @@ include::scripts/astar.cypher[tag=stream-sample-graph]
6055
.Results
6156
[opts="header",cols="1,1"]
6257
|===
63-
| Name | Cost
58+
| Name | Cost
6459
| King's Cross St. Pancras | 0
65-
| Euston | 2
66-
| Camden Town | 5
67-
| Kentish Town | 7
60+
| Euston | 2
61+
| Camden Town | 5
62+
| Kentish Town | 7
6863
|===
6964
// end::stream-sample-graph-result[]
7065

66+
67+
[[algorithms-a_star-syntax]]
7168
== Syntax
7269

7370
.The following will run the algorithm and stream results:
74-
[source,cypher]
71+
[source, cypher]
7572
----
7673
CALL algo.shortestPath.astar.stream((startNode:Node, endNode:Node, weightProperty:String, propertyKeyLat:String,
77-
propertyKeyLon:String, {nodeQuery:'labelName', relationshipQuery:'relationshipName', direction:'BOTH', defaultValue:1.0})
74+
propertyKeyLon:String, {nodeQuery:'labelName', relationshipQuery:'relationshipName', direction:'BOTH', defaultValue:1.0})
7875
YIELD nodeId, cost - yields a stream of {nodeId, cost} from start to end (inclusive)
7976
----
8077

8178
.Parameters
8279
[opts="header",cols="1,1,1,1,4"]
8380
|===
84-
| Name | Type | Default | Optional | Description
85-
| startNode | node | null | no | The start node
86-
| endNode | node | null | no | The end node
87-
| weightProperty | string | null | yes | The property name that contains weight
88-
| propertyKeyLat | string | null | no | The property name that contains latitude coordinate
89-
| propertyKeyLon | string | null | no | The property name that contains longitude coordinate
90-
| nodeQuery | string | null | yes | The label to load from the graph. If null, load all nodes
91-
| relationshipQuery | string | null | yes | The relationship-type to load from the graph. If null, load all nodes
92-
| defaultValue | float | null | yes | The default value of the weight in case it is missing or invalid
93-
| direction | string | outgoing | yes | The relationship direction to load from the graph. If 'both', treats the relationships as undirected
81+
| Name | Type | Default | Optional | Description
82+
| startNode | node | null | no | The start node
83+
| endNode | node | null | no | The end node
84+
| weightProperty | string | null | yes | The property name that contains weight
85+
| propertyKeyLat | string | null | no | The property name that contains latitude coordinate
86+
| propertyKeyLon | string | null | no | The property name that contains longitude coordinate
87+
| nodeQuery | string | null | yes | The label to load from the graph. If null, load all nodes
88+
| relationshipQuery | string | null | yes | The relationship-type to load from the graph. If null, load all nodes
89+
| defaultValue | float | null | yes | The default value of the weight in case it is missing or invalid
90+
| direction | string | outgoing | yes | The relationship direction to load from the graph. If 'both', treats the relationships as undirected
9491
|===
9592

9693
.Results
9794
[opts="header"]
9895
|===
99-
| Name | Type | Description
100-
| nodeId | int | Node ID
101-
| cost | int | The cost it takes to get from start node to specific node
96+
| Name | Type | Description
97+
| nodeId | int | Node ID
98+
| cost | int | The cost it takes to get from start node to specific node
10299
|===
103100

101+
104102
== Cypher projection
105103

106104
If label and relationship-type are not selective enough to describe your subgraph to run the algorithm on, you can use Cypher statements to load or project subsets of your graph.
@@ -113,26 +111,21 @@ This can also be used to run algorithms on a virtual graph.
113111
include::scripts/astar.cypher[tag=cypher-loading]
114112
----
115113

114+
116115
== Versions
117116

118117
We support the following versions of the shortest path algorithms:
119118

120119
* [x] directed, unweighted:
121-
122120
** direction: 'OUTGOING' or INCOMING, weightProperty: null
123-
124121
* [x] directed, weighted
125-
126122
** direction: 'OUTGOING' or INCOMING, weightProperty: 'cost'
127-
128123
* [x] undirected, unweighted
129-
130124
** direction: 'BOTH', weightProperty: null
131-
132125
* [x] undirected, weighted
133-
134126
** direction: 'BOTH', weightProperty: 'cost'
135127

128+
136129
== Implementations
137130

138131
`algo.shortestPath.astar.stream()`
@@ -150,6 +143,7 @@ We support the following versions of the shortest path algorithms:
150143
ifdef::implementation[]
151144
// tag::implementation[]
152145

146+
153147
== Implementation details
154148

155149
:leveloffset: +1
@@ -169,6 +163,7 @@ ifdef::implementation[]
169163

170164
== Details
171165

166+
172167
=== algo.shortestPath.astar.stream()
173168

174169
- implementation of A* heuristic function is for geospatial distances.

0 commit comments

Comments
 (0)