Skip to content

Commit 94f789c

Browse files
committed
fix: graph
1 parent 59c3ed5 commit 94f789c

5 files changed

Lines changed: 180 additions & 5 deletions

File tree

docs/algorithms/10-graphs/README.md

Lines changed: 180 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Graph
22

3-
Graphs are a type of data structures that interconnects nodes (or vertices) with edges. They are used to model relationships between objects.
3+
Graphs are a type of data structures that interconnects nodes (or vertices) with edges. They are used to model relationships between objects. This is the basics for most AI algorithms, such as pathfinding, decision making, neuron networks, and others.
4+
5+
![img_1.png](img_1.png)
46

57
## Basic Definitions
68

@@ -10,6 +12,8 @@ Graphs are a type of data structures that interconnects nodes (or vertices) with
1012
- **Path** is the sequence of edges and nodes that allows you to go from one node to another.
1113
- **Degree** of a node is the number of edges connected to it.
1214

15+
![img_2.png](img_2.png)
16+
1317
## Representation
1418

1519
A graph is composed by a set of vertices(nodes) and edges. There are multiple ways to represent a graph, and every style has its own advantages and disadvantages.
@@ -75,18 +79,189 @@ vector<Node> nodes;
7579
- **Complete graph**: A graph where every pair of nodes is connected by a unique edge.
7680
- **Regular graph**: A graph where every node has the same degree.
7781

82+
![img.png](img.png)
83+
7884
## Graph Algorithms
7985

8086
### Depth-First Search (DFS)
8187

8288
DFS is a graph traversal algorithm based on a stack data structure. Basically, the algorithm starts at a node and explores as far as possible along each branch before backtracking. It is used to find connected components, determine the connectivity of the graph, and solve many other problems.
8389

84-
<iframe scrolling="no" style="position:relative;top:0px;width:100%;height:500px;" src="https://www.cs.usfca.edu/~galles/visualization/DFS.html"></iframe>
85-
<a href="https://www.cs.usfca.edu/~galles/visualization/DFS.html">source</a>
90+
<a href="https://www.cs.usfca.edu/~galles/visualization/DFS.html">DFS visualization</a>
91+
92+
```c++
93+
#include <iostream>
94+
#include <vector>
95+
#include <unordered_set>
96+
#include <unordered_map>
97+
#include <string>
98+
99+
// graph is represented as an adjacency list
100+
std::unordered_map<std::string, std::unordered_set<std::string>> graph;
101+
std::unordered_set<std::string> visited;
102+
103+
// dfs recursive version
104+
// it exploits the call stack to store the nodes to visit
105+
// you might want to use the iterative version if you have a large graph
106+
// for that, use std::stack data structure and producer-consumer pattern
107+
void dfs(const std::string& node) {
108+
std::cout << node << std::endl;
109+
visited.insert(node);
110+
for (const auto& neighbor : graph[node])
111+
if (!visited.contains(neighbor))
112+
dfs(neighbor);
113+
}
114+
115+
void dfs_interactive(const std::string& node) {
116+
std::stack<std::string> stack;
117+
// produce the first node
118+
stack.push(node);
119+
while (!stack.empty()) {
120+
// consume the node
121+
std::string current = stack.top();
122+
stack.pop();
123+
// avoid visiting the same node twice
124+
if (visited.contains(current))
125+
continue;
126+
// mark as visited
127+
visited.insert(current);
128+
129+
// visit the node
130+
std::cout << current << std::endl;
131+
132+
// produce the next node to visit
133+
for (const auto& neighbor : graph[current]) {
134+
if (!visited.contains(neighbor)) {
135+
stack.push(neighbor);
136+
break; // is this break necessary?
137+
}
138+
}
139+
}
140+
}
141+
142+
int main() {
143+
std::cout << "Write one node string per line. When you are done, add an empty line." << std::endl;
144+
std::string node;
145+
while (std::getline(std::cin, node) && !node.empty())
146+
graph[node] = {};
147+
std::cout << "Write the edges as 'node1;node2'. When you are done, add an empty line." << std::endl;
148+
std::string edge;
149+
while (std::getline(std::cin, edge) && !edge.empty()) {
150+
auto pos = edge.find(';');
151+
// Bidirectional
152+
std::string source = edge.substr(0, pos);
153+
std::string destination = edge.substr(pos + 1);
154+
graph[source].insert(destination);
155+
graph[destination].insert(source);
156+
}
157+
std::cout << "Write the starting node." << std::endl;
158+
std::string start;
159+
std::cin >> start;
160+
dfs(start);
161+
return 0;
162+
}
163+
```
86164
87165
### Breadth-First Search (BFS)
88166
89167
BFS is a graph traversal algorithm based on a queue data structure. It starts at a node and explores all of its neighbours before moving on to the next level of neighbours by enqueing them. It is used to find the shortest path, determine the connectivity of the graph, and others.
90168
91-
<iframe scrolling="no" style="position:relative;top:0px;width:100%;height:500px;" src="https://www.cs.usfca.edu/~galles/visualization/BFS.html"></iframe>
92-
<a href="https://www.cs.usfca.edu/~galles/visualization/BFS.html">source</a>
169+
<a href="https://www.cs.usfca.edu/~galles/visualization/BFS.html">BFS visualization</a>
170+
171+
```c++
172+
#include <iostream>
173+
#include <vector>
174+
#include <unordered_set>
175+
#include <unordered_map>
176+
#include <string>
177+
#include <queue>
178+
179+
// graph is represented as an adjacency list
180+
std::unordered_map<std::string, std::unordered_set<std::string>> graph;
181+
std::unordered_set<std::string> visited;
182+
183+
// bfs
184+
void bfs(const std::string& node) {
185+
std::queue<std::string> queue;
186+
// produce the first node
187+
queue.push(node);
188+
while (!queue.empty()) {
189+
// consume the node
190+
std::string current = queue.front();
191+
queue.pop();
192+
// avoid visiting the same node twice
193+
if (visited.contains(current))
194+
continue;
195+
// mark as visited
196+
visited.insert(current);
197+
198+
// visit the node
199+
std::cout << current << std::endl;
200+
201+
// produce the next node to visit
202+
for (const auto& neighbor : graph[current]) {
203+
if (!visited.contains(neighbor))
204+
queue.push(neighbor);
205+
}
206+
}
207+
}
208+
209+
void dfs_interactive(const std::string& node) {
210+
std::stack<std::string> stack;
211+
// produce the first node
212+
stack.push(node);
213+
while (!stack.empty()) {
214+
// consume the node
215+
std::string current = stack.top();
216+
stack.pop();
217+
// avoid visiting the same node twice
218+
if (visited.contains(current))
219+
continue;
220+
// mark as visited
221+
visited.insert(current);
222+
223+
// visit the node
224+
std::cout << current << std::endl;
225+
226+
// produce the next node to visit
227+
for (const auto& neighbor : graph[current]) {
228+
if (!visited.contains(neighbor)) {
229+
stack.push(neighbor);
230+
break; // is this break necessary?
231+
}
232+
}
233+
}
234+
}
235+
236+
int main() {
237+
std::cout << "Write one node string per line. When you are done, add an empty line." << std::endl;
238+
std::string node;
239+
while (std::getline(std::cin, node) && !node.empty())
240+
graph[node] = {};
241+
std::cout << "Write the edges as 'node1;node2'. When you are done, add an empty line." << std::endl;
242+
std::string edge;
243+
while (std::getline(std::cin, edge) && !edge.empty()) {
244+
auto pos = edge.find(';');
245+
// Bidirectional
246+
std::string source = edge.substr(0, pos);
247+
std::string destination = edge.substr(pos + 1);
248+
graph[source].insert(destination);
249+
graph[destination].insert(source);
250+
}
251+
std::cout << "Write the starting node." << std::endl;
252+
std::string start;
253+
std::cin >> start;
254+
// dfs(start);
255+
dfs_interactive(start);
256+
return 0;
257+
}
258+
```
259+
260+
![img_3.png](img_3.png) [source](https://www.deviantart.com/eleew/art/Carl-Graph-Theory-D8-208366409)
261+
262+
263+
https://www.redblobgames.com/pathfinding/grids/graphs.html
264+
265+
https://www.redblobgames.com/pathfinding/a-star/introduction.html
266+
267+
https://qiao.github.io/PathFinding.js/visual/

docs/algorithms/10-graphs/img.png

288 KB
Loading
612 KB
Loading
41.3 KB
Loading
291 KB
Loading

0 commit comments

Comments
 (0)