-
Notifications
You must be signed in to change notification settings - Fork 472
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #76 from Singhal1808/add-graph-algorithms
Add Graph Algorithms: Dijkstra, Kruskal, Prim, Bellman-Ford, Floyd-Warshall, DFS, and BFS
- Loading branch information
Showing
17 changed files
with
425 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Graph Algorithms | ||
|
||
This directory contains several important graph algorithms implemented in C++. These algorithms are widely used in computer science for pathfinding, graph traversal, and analysis. | ||
|
||
## Included Algorithms | ||
|
||
1. **Dijkstra's Algorithm**: | ||
- Finds the shortest path in a weighted graph. | ||
- Suitable for graphs with non-negative weights. | ||
|
||
2. **Kruskal’s Algorithm**: | ||
- Greedy approach to finding the Minimum Spanning Tree (MST). | ||
- Works well for sparse graphs. | ||
|
||
3. **Prim's Algorithm**: | ||
- Another method for finding the MST, better suited for dense graphs. | ||
|
||
4. **Bellman-Ford Algorithm**: | ||
- Finds the shortest path in graphs with negative weights. | ||
- Detects negative weight cycles. | ||
|
||
5. **Floyd-Warshall Algorithm**: | ||
- Finds shortest paths between all pairs of vertices. | ||
|
||
6. **Depth-First Search (DFS)**: | ||
- Explores graph depth-wise. | ||
|
||
7. **Breadth-First Search (BFS)**: | ||
- Explores graph level-wise. | ||
|
||
## How to Run | ||
|
||
Each algorithm is implemented in its respective `.cpp` file. You can compile and run the programs using a C++ compiler, for example: | ||
|
||
```bash | ||
g++ dijkstra.cpp -o dijkstra | ||
./dijkstra |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <queue> | ||
#include <cmath> | ||
#include <unordered_map> | ||
|
||
using namespace std; | ||
|
||
typedef pair<int, int> pii; | ||
|
||
struct Node { | ||
int vertex; | ||
int cost; | ||
int heuristic; | ||
int total; | ||
|
||
bool operator>(const Node& other) const { | ||
return total > other.total; | ||
} | ||
}; | ||
|
||
int heuristic(int a, int b) { | ||
return abs(a - b); // Example heuristic | ||
} | ||
|
||
void a_star(int source, int goal, const vector<vector<pii>>& graph) { | ||
priority_queue<Node, vector<Node>, greater<Node>> pq; | ||
unordered_map<int, int> cost; | ||
pq.push({source, 0, heuristic(source, goal), 0}); | ||
cost[source] = 0; | ||
|
||
while (!pq.empty()) { | ||
Node current = pq.top(); | ||
pq.pop(); | ||
|
||
if (current.vertex == goal) { | ||
cout << "Path found with cost: " << current.cost << endl; | ||
return; | ||
} | ||
|
||
for (const auto& edge : graph[current.vertex]) { | ||
int next_vertex = edge.first; | ||
int weight = edge.second; | ||
|
||
int new_cost = current.cost + weight; | ||
if (cost.find(next_vertex) == cost.end() || new_cost < cost[next_vertex]) { | ||
cost[next_vertex] = new_cost; | ||
pq.push({next_vertex, new_cost, heuristic(next_vertex, goal), new_cost + heuristic(next_vertex, goal)}); | ||
} | ||
} | ||
} | ||
cout << "Path not found" << endl; | ||
} | ||
|
||
int main() { | ||
vector<vector<pii>> graph = { | ||
{{1, 1}, {2, 4}}, | ||
{{0, 1}, {2, 2}, {3, 5}}, | ||
{{0, 4}, {1, 2}, {3, 1}}, | ||
{{1, 5}, {2, 1}} | ||
}; | ||
|
||
a_star(0, 3, graph); | ||
return 0; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <climits> | ||
|
||
using namespace std; | ||
|
||
struct Edge { | ||
int src, dest, weight; | ||
}; | ||
|
||
void bellman_ford(int vertices, int edges, const vector<Edge>& graph, int source) { | ||
vector<int> dist(vertices, INT_MAX); | ||
dist[source] = 0; | ||
|
||
for (int i = 1; i <= vertices - 1; i++) { | ||
for (const auto& edge : graph) { | ||
if (dist[edge.src] != INT_MAX && dist[edge.src] + edge.weight < dist[edge.dest]) { | ||
dist[edge.dest] = dist[edge.src] + edge.weight; | ||
} | ||
} | ||
} | ||
|
||
// Check for negative weight cycles | ||
for (const auto& edge : graph) { | ||
if (dist[edge.src] != INT_MAX && dist[edge.src] + edge.weight < dist[edge.dest]) { | ||
cout << "Graph contains negative weight cycle" << endl; | ||
return; | ||
} | ||
} | ||
|
||
// Print distances | ||
for (int i = 0; i < vertices; i++) { | ||
cout << "Distance from source " << source << " to " << i << " is " << dist[i] << endl; | ||
} | ||
} | ||
|
||
int main() { | ||
vector<Edge> graph = { | ||
{0, 1, -1}, {0, 2, 4}, | ||
{1, 2, 3}, {1, 3, 2}, | ||
{1, 4, 2}, {3, 1, 1}, | ||
{3, 2, 5}, {4, 3, -3} | ||
}; | ||
|
||
int vertices = 5; | ||
int edges = graph.size(); | ||
bellman_ford(vertices, edges, graph, 0); | ||
return 0; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <queue> | ||
|
||
using namespace std; | ||
|
||
void bfs(int start, const vector<vector<int>>& graph) { | ||
vector<bool> visited(graph.size(), false); | ||
queue<int> q; | ||
|
||
visited[start] = true; | ||
q.push(start); | ||
|
||
while (!q.empty()) { | ||
int vertex = q.front(); | ||
q.pop(); | ||
cout << vertex << " "; | ||
|
||
for (int neighbor : graph[vertex]) { | ||
if (!visited[neighbor]) { | ||
visited[neighbor] = true; | ||
q.push(neighbor); | ||
} | ||
} | ||
} | ||
} | ||
|
||
int main() { | ||
vector<vector<int>> graph = { | ||
{1, 2}, // Edges from vertex 0 | ||
{0, 3, 4}, // Edges from vertex 1 | ||
{0, 5}, // Edges from vertex 2 | ||
{1}, // Edges from vertex 3 | ||
{1, 5}, // Edges from vertex 4 | ||
{2, 4} // Edges from vertex 5 | ||
}; | ||
|
||
cout << "BFS traversal starting from vertex 0: "; | ||
bfs(0, graph); | ||
return 0; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#include <iostream> | ||
#include <vector> | ||
|
||
using namespace std; | ||
|
||
void dfs(int vertex, vector<bool>& visited, const vector<vector<int>>& graph) { | ||
visited[vertex] = true; | ||
cout << vertex << " "; | ||
|
||
for (int neighbor : graph[vertex]) { | ||
if (!visited[neighbor]) { | ||
dfs(neighbor, visited, graph); | ||
} | ||
} | ||
} | ||
|
||
int main() { | ||
vector<vector<int>> graph = { | ||
{1, 2}, // Edges from vertex 0 | ||
{0, 3, 4}, // Edges from vertex 1 | ||
{0, 5}, // Edges from vertex 2 | ||
{1}, // Edges from vertex 3 | ||
{1, 5}, // Edges from vertex 4 | ||
{2, 4} // Edges from vertex 5 | ||
}; | ||
|
||
vector<bool> visited(graph.size(), false); | ||
cout << "DFS traversal starting from vertex 0: "; | ||
dfs(0, visited, graph); | ||
return 0; | ||
} | ||
|
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <queue> | ||
#include <climits> | ||
|
||
using namespace std; | ||
|
||
typedef pair<int, int> pii; | ||
|
||
void dijkstra(int source, const vector<vector<pii>>& graph) { | ||
int n = graph.size(); | ||
vector<int> dist(n, INT_MAX); | ||
priority_queue<pii, vector<pii>, greater<pii>> pq; | ||
|
||
dist[source] = 0; | ||
pq.push({0, source}); | ||
|
||
while (!pq.empty()) { | ||
int u = pq.top().second; | ||
pq.pop(); | ||
|
||
for (const auto& edge : graph[u]) { | ||
int v = edge.first; | ||
int weight = edge.second; | ||
|
||
if (dist[u] + weight < dist[v]) { | ||
dist[v] = dist[u] + weight; | ||
pq.push({dist[v], v}); | ||
} | ||
} | ||
} | ||
|
||
// Print the distance from source to each vertex | ||
for (int i = 0; i < n; i++) { | ||
cout << "Distance from source " << source << " to " << i << " is " << dist[i] << endl; | ||
} | ||
} | ||
|
||
int main() { | ||
// Example graph as an adjacency list | ||
vector<vector<pii>> graph = { | ||
{{1, 4}, {2, 1}}, // Edges from vertex 0 | ||
{{0, 4}, {2, 2}, {3, 1}}, // Edges from vertex 1 | ||
{{0, 1}, {1, 2}, {3, 5}}, // Edges from vertex 2 | ||
{{1, 1}, {2, 5}} // Edges from vertex 3 | ||
}; | ||
|
||
dijkstra(0, graph); // Run Dijkstra's algorithm from vertex 0 | ||
return 0; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <climits> | ||
|
||
using namespace std; | ||
|
||
void floyd_warshall(vector<vector<int>>& graph) { | ||
int vertices = graph.size(); | ||
|
||
for (int k = 0; k < vertices; k++) { | ||
for (int i = 0; i < vertices; i++) { | ||
for (int j = 0; j < vertices; j++) { | ||
if (graph[i][k] != INT_MAX && graph[k][j] != INT_MAX && | ||
graph[i][j] > graph[i][k] + graph[k][j]) { | ||
graph[i][j] = graph[i][k] + graph[k][j]; | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Print the distance matrix | ||
for (const auto& row : graph) { | ||
for (const auto& dist : row) { | ||
if (dist == INT_MAX) cout << "INF "; | ||
else cout << dist << " "; | ||
} | ||
cout << endl; | ||
} | ||
} | ||
|
||
int main() { | ||
vector<vector<int>> graph = { | ||
{0, 5, INT_MAX, 10}, | ||
{INT_MAX, 0, 3, INT_MAX}, | ||
{INT_MAX, INT_MAX, 0, 1}, | ||
{INT_MAX, INT_MAX, INT_MAX, 0} | ||
}; | ||
|
||
floyd_warshall(graph); | ||
return 0; | ||
} |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
#include <iostream> | ||
#include <vector> | ||
#include <algorithm> | ||
|
||
using namespace std; | ||
|
||
struct Edge { | ||
int src, dest, weight; | ||
}; | ||
|
||
bool compare(Edge a, Edge b) { | ||
return a.weight < b.weight; | ||
} | ||
|
||
int findParent(int v, vector<int>& parent) { | ||
if (parent[v] == -1) return v; | ||
return findParent(parent[v], parent); | ||
} | ||
|
||
void unionNodes(int u, int v, vector<int>& parent) { | ||
parent[u] = v; | ||
} | ||
|
||
void kruskal(int vertices, const vector<Edge>& edges) { | ||
vector<int> parent(vertices, -1); | ||
vector<Edge> mst; | ||
|
||
for (const auto& edge : edges) { | ||
int u = findParent(edge.src, parent); | ||
int v = findParent(edge.dest, parent); | ||
|
||
if (u != v) { | ||
mst.push_back(edge); | ||
unionNodes(u, v, parent); | ||
} | ||
} | ||
|
||
cout << "Edges in Minimum Spanning Tree:" << endl; | ||
for (const auto& edge : mst) { | ||
cout << edge.src << " -- " << edge.dest << " == " << edge.weight << endl; | ||
} | ||
} | ||
|
||
int main() { | ||
vector<Edge> edges = { | ||
{0, 1, 10}, | ||
{0, 2, 6}, | ||
{0, 3, 5}, | ||
{1, 3, 15}, | ||
{2, 3, 4} | ||
}; | ||
|
||
int vertices = 4; | ||
sort(edges.begin(), edges.end(), compare); | ||
kruskal(vertices, edges); | ||
return 0; | ||
} |
Binary file not shown.
Oops, something went wrong.