0% found this document useful (0 votes)
16 views

Project Report Graph Algorithm Simulator .

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Project Report Graph Algorithm Simulator .

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

[Graph Algorithms Simulator]

Project submitted for the partial fulfillment of the requirements for the course

CSE 207L: Design Analysis and Algorithm Lab

Offered by the

Department Computer Science and Engineering

School of Engineering and Sciences

Submitted by

1) Saksham Saini , AP22110010136

2) Shivam Kumar , AP22110010178

SRM University–AP
Neerukonda, Mangalagiri, Guntur

Andhra Pradesh – 522 240

[Month, Year]
Contents:
1. Introduction
• Purpose of the project
2. Background
• Relevance of the project
• Possible ways to solve it
3. Proposed Approach
• Explanation of the approach
• Algorithm and flowchart 3.3 System design
4. Algorithms and Pseudo-Code.
5. Sample Output.
6. References
7. Conclusion.
1. Introduction :

1.1 Purpose of the project:

The purpose of this project is to develop a graph algorithms simulator that enables users to
visualize and apply various graph algorithms such as Breadth-First Search (BFS), Depth-First
Search (DFS), Topological Sort, Shortest Path Algorithms (Dijkstra's, Bellman-Ford, FloydWarshall),
and Maximum Flow (Ford-Fulkerson). The simulator provides an interactive platform for users to
create graphs, run algorithms, and analyze the results. By implementing this simulator, users can
gain a better understanding of graph algorithms and their applications.
2. Background
2.1 Relevance of the project:

Graph algorithms play a crucial role in various real-world applications such as social networks,
transportation networks, and computer networks. For example, BFS and DFS are fundamental
algorithms used for traversing graphs and solving problems like finding connected components
or detecting cycles. Dijkstra's algorithm is widely used in route planning and network
optimization, while maximum flow algorithms are essential for solving flow network problems
like network flow optimization and traffic management.

2.2 Possible ways to solve it:

There are multiple ways to implement a graph algorithms simulator. One approach is to use an
object-oriented programming language like C++ to represent graphs and algorithms as classes.
Another approach is to use a graph visualization library such as GraphViz or NetworkX in
Python to visualize graphs and apply algorithms. Additionally, web-based tools and applications
can be developed using JavaScript libraries like D3.js or Vis.js for interactive graph visualization.
3. Proposed Approach
3.1 Explanation of the approach:

The proposed approach involves developing a graph algorithms simulator using C++. The
simulator will allow users to create graphs, add edges with weights, and apply various graph
algorithms. The graph will be represented using an adjacency list data structure, and different
algorithms will be implemented as member functions of the graph class. Users will interact
with the simulator through a command-line interface, where they can choose the desired
algorithm and input parameters.

3.2 Algorithm and flowchart:

The algorithms implemented in the simulator include Breadth-First Search (BFS), DepthFirst
Search (DFS), Topological Sort, Dijkstra's Algorithm, Bellman-Ford Algorithm, FloydWarshall
Algorithm, and Ford-Fulkerson Algorithm. Each algorithm will be accompanied by a flowchart
illustrating its workflow and key steps.

3.3 System design:

The system design will consist of a main program that interacts with the user, a graph class for
representing graphs and implementing algorithms, and separate functions for each algorithm.
The graph class will include methods for adding edges, performing traversals, and calculating
shortest paths and maximum flow. Additionally, the system will incorporate error handling
mechanisms to handle invalid inputs and edge cases.
Code :
#include <iostream>
#include <vector>
#include <queue>
#include <stack> #include
<limits> using namespace
std;
class Graph { int V; // Number of vertices vector<vector<pair<int,
int>>> adj; // Adjacency list for weighted graph
public:
Graph(int vertices) : V(vertices) {
adj.resize(V);
}

// Function to add an edge to the graph void


addEdge(int u, int v, int weight) {
adj[u].push_back({v, weight});
}

// Visualize the graph (Simple line-based visualization)


void visualizeGraph() { cout << "Graph Visualization:\n";
for (int u = 0; u < V; ++u) { cout << u << " -> ";
for (const auto& pair : adj[u]) { int v =
pair.first; int weight = pair.second;
cout << v << "(" << weight << ") ";
}
cout << endl;
}
}

// Breadth-First Search traversal


void BFS(int start) { vector<bool>
visited(V, false); queue<int> q;
visited[start] = true;
q.push(start);
while (!q.empty()) {
int u = q.front();
q.pop();
cout << u << " ";

for (const auto& pair : adj[u]) {


int v = pair.first;
if (!visited[v]) {
visited[v] = true;
q.push(v);
}
} }
cout << endl;
}
// Depth-First Search traversal void
DFS(int start) { vector<bool>
visited(V, false); stack<int> stk;
visited[start] = true;
stk.push(start);
while (!stk.empty()) {
int u = stk.top();
stk.pop(); cout << u <<
" ";
for (const auto& pair : adj[u]) {
int v = pair.first; if
(!visited[v]) { visited[v] =
true; stk.push(v);
}
}
}
cout << endl; }

// Topological Sort void


topologicalSort() { vector<int>
inDegree(V, 0); for (int u = 0; u <
V; ++u) { for (const auto&
pair : adj[u]) { int v
= pair.first;
inDegree[v]++;
}
}

queue<int> q;
for (int u = 0; u < V; ++u) {
if (inDegree[u] == 0) {
q.push(u);
}
} while
(!q.empty()) { int u =
q.front();
q.pop();
cout << u << " ";
for (const auto& pair : adj[u]) {
int v = pair.first; if (--
inDegree[v] == 0) {
q.push(v);
}
}
}
cout << endl;
}

// Dijkstra's Algorithm for Single Source Shortest Paths


void dijkstra(int start) { vector<int> dist(V,
numeric_limits<int>::max()); vector<bool> visited(V,
false); dist[start] = 0;

for (int i = 0; i < V - 1; ++i) {


int u = minDistance(dist, visited);
visited[u] = true;
for (const auto& pair : adj[u]) {
int v = pair.first; int weight =
pair.second;
if (!visited[v] && dist[u] != numeric_limits<int>::max() &&
dist[u] + weight < dist[v]) { dist[v] = dist[u] + weight;
}
} }

cout << "Shortest distances from vertex " << start << ":\n"; for (int
i = 0; i < V; ++i) {
cout << "Vertex " << i << ": " << dist[i] << endl; }
}

// Utility function to find the vertex with minimum distance value int
minDistance(const vector<int>& dist, const vector<bool>& visited) { int
minDist = numeric_limits<int>::max(), minIndex; for (int v = 0; v < V;
++v) { if (!visited[v] && dist[v] <= minDist) {
minDist = dist[v]; minIndex = v;
} }
return minIndex;
}

// Bellman-Ford Algorithm for Single Source Shortest Paths with negative


weight edges void bellmanFord(int start) { vector<int> dist(V,
numeric_limits<int>::max()); dist[start] = 0;
for (int i = 0; i < V - 1; ++i) {
for (int u = 0; u < V; ++u) { for
(const auto& pair : adj[u]) { int
v = pair.first; int weight =
pair.second;
if (dist[u] != numeric_limits<int>::max() && dist[u] + weight
< dist[v]) {
dist[v] = dist[u] + weight;
}
}
}
}

cout << "Shortest distances from vertex " << start << ":\n";
for (int i = 0; i < V; ++i) { cout << "Vertex " << i << ": " <<
dist[i] << endl;
}
}
// Floyd-Warshall Algorithm for All Pairs Shortest Paths void floydWarshall() {
vector<vector<int>> dist(V, vector<int>(V, numeric_limits<int>::max()));
// Initialize distances for
(int u = 0; u < V; ++u) {
dist[u][u] = 0; for (const
auto& pair : adj[u]) { int v =
pair.first; int weight =
pair.second; dist[u][v] = weight;
}
}

// Update distances for (int k = 0; k < V; ++k) {


for (int i = 0; i < V; ++i) { for (int j = 0; j < V;
++j) { if (dist[i][k] != numeric_limits<int>::max()
&& dist[k][j] != numeric_limits<int>::max() &&
dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}

// Print distances cout << "Shortest distances between all


pairs of vertices:\n"; for (int i = 0; i < V; ++i) {
for (int j = 0; j < V; ++j) {
if (dist[i][j] == numeric_limits<int>::max()) {
cout << "INF\t";
} else { cout <<
dist[i][j] << "\t";
}
} cout
<< endl;
}
}

// Ford-Fulkerson Algorithm for Maximum Flow in a flow network int


fordFulkerson(int source, int sink) { vector<vector<int>>
residualGraph(V, vector<int>(V));
for (int u = 0; u < V; ++u) { for
(const auto& pair : adj[u]) { int
v = pair.first; int weight =
pair.second; residualGraph[u][v] =
weight;
}
} vector<int>
parent(V); int maxFlow = 0;
while (bfs(residualGraph, source, sink, parent)) {
int pathFlow = numeric_limits<int>::max(); for (int v =
sink; v != source; v = parent[v]) { int u =
parent[v]; pathFlow = min(pathFlow,
residualGraph[u][v]);
}
for (int v = sink; v != source; v = parent[v]) {
int u = parent[v]; residualGraph[u][v] -=
pathFlow; residualGraph[v][u] += pathFlow;
}
maxFlow += pathFlow;
} return
maxFlow;
}

// Breadth-First Search for finding augmenting paths in Ford-Fulkerson


Algorithm
bool bfs(const vector<vector<int>>& rGraph, int source, int sink, vector<int>&
parent) {
vector<bool> visited(V, false);
queue<int> q;

visited[source] = true;
q.push(source);
parent[source] = -1;

while (!q.empty()) { int


u = q.front(); q.pop();
for (int v = 0; v < V; ++v) { if
(!visited[v] && rGraph[u][v] > 0) { if
(v == sink) { parent[v] = u;
return true;
}
visited[v] = true;
q.push(v);
parent[v] = u;
}
}
} return
false;
}
}; int main() { cout <<
"*******************************************\n"; cout << "*
Welcome to Graph Algorithms Simulator *\n"; cout <<
"*******************************************\n"; int V, E;
cout << "Enter the number of vertices and edges: "; cin >> V
>> E;

Graph g(V);
cout << "Enter the edges (source, destination, weight):\n";
for (int i = 0; i < E; ++i) { int u, v, weight; cin
>> u >> v >> weight; g.addEdge(u, v, weight);
}

// Visualize the graph


g.visualizeGraph();
int choice;
do { cout <<
"\nMenu:\n";
cout << "1. Breadth-First Search (BFS)\n";
cout << "2. Depth-First Search (DFS)\n"; cout <<
"3. Topological Sort\n"; cout << "4. Dijkstra's
Algorithm\n"; cout << "5. Bellman-Ford
Algorithm\n";
cout << "6. Floyd-Warshall Algorithm\n"; cout << "7. Ford-
Fulkerson Algorithm for Maximum Flow\n"; cout << "8. Exit\n";
cout << "Enter your choice: "; cin >> choice;

int start;
switch (choice) {
case 1:
cout << "Enter the starting vertex for BFS: ";
cin >> start; cout << "BFS Traversal: ";
g.BFS(start);
break; case 2:
cout << "Enter the starting vertex for DFS: ";
cin >> start; cout << "DFS Traversal: ";
g.DFS(start);
break; case 3:
cout << "Topological Sort: ";
g.topologicalSort();
break; case 4:
cout << "Enter the starting vertex for Dijkstra's Algorithm: ";
cin >> start;
g.dijkstra(start);
break; case 5:
cout << "Enter the starting vertex for Bellman-Ford Algorithm: ";
cin >> start;
g.bellmanFord(start);
break; case 6:
cout << "Floyd-Warshall Algorithm:\n";
g.floydWarshall();
break; case 7:
int source, sink;
cout << "Enter the source and sink vertices for Ford-Fulkerson
Algorithm: "; cin >> source >> sink; cout << "Maximum
Flow: " << g.fordFulkerson(source, sink) << endl;
break; case 8:
cout << "Exiting...\n";
break; default:
cout << "Invalid choice. Please enter a number from 1 to 8.\n";
}
} while (choice != 8);

return 0;
}
4.Algorithms and Pseudo-Code:
1. Breadth-First Search (BFS):
o Initialize a visited array and a queue
o Mark the starting vertex as visited and enqueue it
o While the queue is not empty:
▪ Dequeue a vertex from the queue
▪ Process the vertex (e.g., print it)
▪ For each unvisited neighbor of the vertex:
▪ Mark it as visited and enqueue it
2. Depth-First Search (DFS):
o Initialize a visited array and a stack
o Mark the starting vertex as visited and push it onto the stack
o While the stack is not empty:
▪ Pop a vertex from the stack
▪ Process the vertex (e.g., print it)
▪ For each unvisited neighbor of the vertex:
▪ Mark it as visited and push it onto the stack
3. Topological Sort:
o Calculate the in-degree of each vertex
o Enqueue all vertices with in-degree 0
o While the queue is not empty:
▪ Dequeue a vertex from the queue
▪ Process the vertex (e.g., print it)
▪ For each neighbor of the vertex:
▪ Decrement its in-degree
▪ If its in-degree becomes 0, enqueue it
4. Dijkstra's Algorithm:
o Initialize distances from the source to all other vertices as infinity
o Set the distance from the source to itself as 0
o Create a set to track unvisited vertices
o While the set is not empty:
▪ Select the unvisited vertex with the minimum distance
▪ For each unvisited neighbor of the selected vertex:
▪ Calculate the tentative distance through the selected vertex
▪ Update the neighbor's distance if the tentative distance is smaller
5. Bellman-Ford Algorithm:
o Initialize distances from the source to all other vertices as infinity
o Set the distance from the source to itself as 0
o Repeat V-1 times:
▪ For each vertex:
▪ For each neighbor of the vertex:
▪ If the sum of the vertex's distance and the edge weight is
smaller than the neighbor's distance:
▪ Update the neighbor's distance
6. Floyd-Warshall Algorithm:
o Initialize the distance matrix with edge weights (infinity for no edge)
o Set the diagonal elements to 0 (distance from a vertex to itself)
o For each intermediate vertex k:
▪ For each source vertex i:
▪ For each destination vertex j:
▪ If the distance from i to j is greater than the sum of distances
from i to k and k to j:
▪ Update the distance from i to j
7. Ford-Fulkerson Algorithm for Maximum Flow:
o Create a residual graph representing the flow network
o While there is an augmenting path from source to sink:
▪ Find the bottleneck capacity on the path
▪ Update the residual graph by subtracting the bottleneck capacity from
edges on the path
▪ Add the bottleneck capacity to the reverse edges
▪ Increment the maximum flow by the bottleneck capacity
Data Structure Used: The graph is represented using an adjacency list data structure, which is
a vector of vectors. Each inner vector represents the neighbors of a vertex, and each neighbor
is stored as a pair containing the neighbor's vertex index and the weight of the edge
connecting them.
Time Complexity Analysis:
• BFS and DFS: O(V + E), where V is the number of vertices and E is the number of edges
• Topological Sort: O(V + E)
• Dijkstra's Algorithm: O(V^2 + E log V) using a binary heap for the priority queue
• Bellman-Ford Algorithm: O(V * E)
• Floyd-Warshall Algorithm: O(V^3)
• Ford-Fulkerson Algorithm for Maximum Flow: O(V * E^2)
5.Sample Output:
The program prompts the user to enter the number of vertices and edges, followed by the
edges themselves (source, destination, weight). After creating the graph, it displays a menu of
algorithms to choose from. The user can select an algorithm, provide any required inputs (e.g.,
starting vertex), and the program will execute the algorithm and display the output (e.g.,
traversal order, shortest distances, maximum flow).
Here's an example output:
6. Results & Discussion:

The results obtained from running the graph algorithms simulator will be discussed in this
section. The effectiveness and efficiency of each algorithm will be evaluated based on their
performance in different scenarios. The discussion will also include any limitations or drawbacks
observed during the testing phase and potential improvements for future iterations of the
simulator.

7.Conclusion
In conclusion, the graph algorithms simulator provides a valuable tool for learning and exploring
various graph algorithms. Through this project, we have achieved the goal of developing an
interactive platform for visualizing and applying graph algorithms. However, there are certain
limitations such as the lack of a graphical user interface (GUI) and limited support for complex
graph operations. Future work could focus on enhancing the user interface, adding more
algorithms and features, and optimizing the performance of existing algorithms

8.References
[1] Cormen, T. H., Leiserson, C. E., Rivest, R. L., & Stein, C. (2009). Introduction to Algorithms (3rd ed.).
MIT Press.

[2] Sedgewick, R., & Wayne, K. (2011). Algorithms (4th ed.). Addison-Wesley.

[3] Eppstein, D. (2012). Graph Algorithms in the Language of Linear Algebra. University of California,
Irvine.

[4] Skiena, S. S. (2008). The Algorithm Design Manual (2nd ed.). Springer.

You might also like