Skip to content

Commit 8f87e66

Browse files
authored
Merge pull request #37 from Debashis08/feature-graph-implementation
feature-test: dijkstra logic, test added
2 parents 601924d + e91d2f5 commit 8f87e66

File tree

5 files changed

+201
-0
lines changed

5 files changed

+201
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#pragma once
2+
3+
#include<map>
4+
#include<vector>
5+
#include<set>
6+
using namespace std;
7+
8+
namespace SingleSourceShortestPathDijkstra
9+
{
10+
class Node
11+
{
12+
public:
13+
int data;
14+
int distance;
15+
Node* parent;
16+
Node(int data);
17+
};
18+
19+
class Edge
20+
{
21+
public:
22+
Node* nodeU;
23+
Node* nodeV;
24+
int weight;
25+
Edge(Node* nodeU, Node* nodeV, int weight);
26+
};
27+
28+
class CompareNodeDistance
29+
{
30+
public:
31+
bool operator()(const Node* nodeU, const Node* nodeV) const
32+
{
33+
return nodeU->distance < nodeV->distance;
34+
}
35+
};
36+
37+
class Graph
38+
{
39+
private:
40+
map<Node*, vector<Node*>> _adjlist;
41+
map<int, Node*> _nodeMap;
42+
map<Node*, vector<Edge*>> _edgeMap;
43+
multiset<Node*, CompareNodeDistance> _operationalSet;
44+
Node* MakeOrFindNode(int data);
45+
void InitializeSingleSource(Node* sourceNode);
46+
void Relax(Edge* edge);
47+
void Dijkstra(Node* source);
48+
void GetShortestPath(Node* node, vector<int>& path);
49+
50+
public:
51+
void PushDirectedEdge(int valueU, int valueV, int weight);
52+
void FindShortestPathDijkstra(int data);
53+
vector<int> GetDijkstraShortestPath(int data);
54+
};
55+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#include "../Headers/0003_Graph/0011_SingleSourceShortestPathDijkstra.h"
2+
#include<climits>
3+
#include<algorithm>
4+
using namespace std;
5+
6+
namespace SingleSourceShortestPathDijkstra
7+
{
8+
Node::Node(int data)
9+
{
10+
this->data = data;
11+
this->distance = INT_MAX;
12+
this->parent = nullptr;
13+
}
14+
15+
Edge::Edge(Node* nodeU, Node* nodeV, int weight)
16+
{
17+
this->nodeU = nodeU;
18+
this->nodeV = nodeV;
19+
this->weight = weight;
20+
}
21+
22+
// Graph Private Member Methods
23+
Node* Graph::MakeOrFindNode(int data)
24+
{
25+
Node* node = nullptr;
26+
if (this->_nodeMap.find(data) == this->_nodeMap.end())
27+
{
28+
node = new Node(data);
29+
this->_nodeMap[data] = node;
30+
}
31+
else
32+
{
33+
node = this->_nodeMap[data];
34+
}
35+
return node;
36+
}
37+
38+
void Graph::InitializeSingleSource(Node* sourceNode)
39+
{
40+
for (auto& iterator : this->_nodeMap)
41+
{
42+
iterator.second->distance = INT_MAX;
43+
iterator.second->parent = nullptr;
44+
}
45+
sourceNode->distance = 0;
46+
}
47+
48+
void Graph::Relax(Edge* edge)
49+
{
50+
if (edge->nodeU->distance != INT_MAX && (edge->nodeV->distance > (edge->nodeU->distance + edge->weight)))
51+
{
52+
this->_operationalSet.erase(edge->nodeV);
53+
edge->nodeV->distance = edge->nodeU->distance + edge->weight;
54+
edge->nodeV->parent = edge->nodeU;
55+
this->_operationalSet.insert(edge->nodeV);
56+
}
57+
}
58+
59+
void Graph::Dijkstra(Node* source)
60+
{
61+
this->InitializeSingleSource(source);
62+
63+
for (auto& node : this->_nodeMap)
64+
{
65+
this->_operationalSet.insert(node.second);
66+
}
67+
68+
while (!this->_operationalSet.empty())
69+
{
70+
Node* nodeU = *(this->_operationalSet.begin());
71+
this->_operationalSet.erase(nodeU);
72+
73+
for (auto& edge : this->_edgeMap[nodeU])
74+
{
75+
this->Relax(edge);
76+
}
77+
}
78+
}
79+
80+
void Graph::GetShortestPath(Node* node, vector<int>& path)
81+
{
82+
path.push_back(node->data);
83+
if (node->parent != nullptr)
84+
{
85+
this->GetShortestPath(node->parent, path);
86+
}
87+
}
88+
89+
// Graph Public Member Methods
90+
void Graph::PushDirectedEdge(int dataU, int dataV, int weight)
91+
{
92+
Node* nodeU = this->MakeOrFindNode(dataU);
93+
Node* nodeV = this->MakeOrFindNode(dataV);
94+
95+
this->_adjlist[nodeU].push_back(nodeV);
96+
this->_edgeMap[nodeU].push_back(new Edge(nodeU, nodeV, weight));
97+
}
98+
99+
void Graph::FindShortestPathDijkstra(int data)
100+
{
101+
Node* source = this->_nodeMap[data];
102+
this->Dijkstra(source);
103+
}
104+
105+
vector<int> Graph::GetDijkstraShortestPath(int data)
106+
{
107+
vector<int> path = {};
108+
Node* node = this->_nodeMap[data];
109+
this->GetShortestPath(node, path);
110+
reverse(path.begin(), path.end());
111+
return path;
112+
}
113+
}

SourceCodes/0003_Graph/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ set(0003GRAPH_SOURCES
1010
0008_MinimumSpanningTreePrimAlgorithm.cc
1111
0009_SingleSourceShortestPathBellmanFord.cc
1212
0010_DirectedAcyclicGraphShortestPath.cc
13+
0011_SingleSourceShortestPathDijkstra.cc
1314

1415
)
1516

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include<gtest/gtest.h>
2+
#include "../Headers/0003_Graph/0011_SingleSourceShortestPathDijkstra.h"
3+
#include "../0000_CommonUtilities/UnitTestHelper.h"
4+
5+
namespace SingleSourceShortestPathDijkstra
6+
{
7+
UnitTestHelper unitTestHelper;
8+
9+
// Test for Simple Graph
10+
TEST(DijkstraTest, SimpleGraph)
11+
{
12+
Graph graph;
13+
14+
graph.PushDirectedEdge(0, 1, 10);
15+
graph.PushDirectedEdge(0, 3, 5);
16+
graph.PushDirectedEdge(1, 2, 1);
17+
graph.PushDirectedEdge(1, 3, 2);
18+
graph.PushDirectedEdge(2, 4, 4);
19+
graph.PushDirectedEdge(3, 1, 3);
20+
graph.PushDirectedEdge(3, 2, 9);
21+
graph.PushDirectedEdge(3, 4, 2);
22+
graph.PushDirectedEdge(4, 2, 6);
23+
graph.PushDirectedEdge(4, 0, 7);
24+
25+
graph.FindShortestPathDijkstra(0);
26+
27+
string expectedPath = "0 3 1 2";
28+
29+
ASSERT_EQ(unitTestHelper.SerializeVectorToString(graph.GetDijkstraShortestPath(2)), expectedPath);
30+
}
31+
}

Tests/0003_Graph/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_executable(
2222
0008_MinimumSpanningTreePrimAlgorithmTest.cc
2323
0009_SingleSourceShortestPathBellmanFordTest.cc
2424
0010_DirectedAcyclicGraphShortestPathTest.cc
25+
0011_SingleSourceShortestPathDijkstraTest.cc
2526
)
2627

2728
target_link_libraries(

0 commit comments

Comments
 (0)