Overview
Graph traversal is a search technique used to visit and explore all the nodes of a graph systematically. The primary goal of graph traversal is to uncover and examine the structure and connections of the graph. There are two common strategies for graph traversal:
- Breadth-First Seach (BFS)
- Depth-First Search (DFS)
The Depth-First Search (DFS) algorithm operates based on the backtracking principle and follows these steps:
- Create a stack (last in, first out) to keep track of visited nodes.
- Start from a selected node, push it into the stack, and mark it as visited.
- Push any unvisited neighbor of the node at the top of the stack into the stack, and mark it as visited. If there are multiple unvisited neighbors, choose one arbitrarily or based on a certain order.
- Repeat step 3 until there are no more unvisited neighbors to push into the stack.
- When there are no new nodes to visit, backtrack to the previous node (the one from which the current node was explored) by popping the top node from the stack.
- Repeat steps 3, 4 and 5 until the stack is empty.
Below is an example of traversing the graph using the DFS approach, starting from node A and assuming to visit neighbors in alphabetical order (A~Z):
Considerations
- Only nodes that are in the same connected component as the start node can be traversed. Nodes in different connect components will not be included in the traversal results.
Example Graph
To create this graph:
// Runs each row separately in order in an empty graphset
insert().into(@default).nodes([{_id:"A"}, {_id:"B"}, {_id:"C"}, {_id:"D"}, {_id:"E"}, {_id:"F"}, {_id:"G"}])
insert().into(@default).edges([{_from:"G", _to:"D"}, {_from:"A", _to:"D"}, {_from:"A", _to:"B"}, {_from:"B", _to:"E"}, {_from:"E", _to:"F"}, {_from:"F", _to:"C"}, {_from:"C", _to:"A"}])
Creating HDC Graph
To load the entire graph to the HDC server hdc-server-1
as hdc_trv
:
CALL hdc.graph.create("hdc-server-1", "hdc_trv", {
nodes: {"*": ["*"]},
edges: {"*": ["*"]},
direction: "undirected",
load_id: true,
update: "static",
query: "query",
default: false
})
hdc.graph.create("hdc_trv", {
nodes: {"*": ["*"]},
edges: {"*": ["*"]},
direction: "undirected",
load_id: true,
update: "static",
query: "query",
default: false
}).to("hdc-server-1")
Parameters
Algorithm name: traverse
Name |
Type |
Spec |
Default |
Optional |
Description |
---|---|---|---|---|---|
ids |
_id |
/ | / | No | Specifies the node to start traversal by its _id . |
uuids |
_uuid |
/ | / | No | Specifies the node to start traversal by its _uuid . |
direction |
String | in , out |
/ | Yes | Specifies to traverse through only incoming edges (in ) or outgoing edges (out ). |
traverse_type |
String | dfs |
bfs |
No | To traverse the graph in the DFS fashion, keep it as dfs . |
return_id_uuid |
String | uuid , id , both |
uuid |
Yes | Includes _uuid , _id , or both to represent nodes in the results. |
File Writeback
CALL algo.traverse.write("hdc_trv", {
params: {
return_id_uuid: "id",
ids: ['B'],
direction: 'in',
traverse_type: 'dfs'
},
return_params: {
file: {
filename: "visited_nodes"
}
}
})
algo(traverse).params({
project: "hdc_trv",
return_id_uuid: "id",
ids: ['B'],
direction: 'in',
traverse_type: 'dfs'
}).write({
file: {
filename: "visited_nodes"
}
})
Result:
nodes
B,A,C,F,E,