Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dijkstra's algorithm OOP implementation #5

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Dijkstra/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Dijkstra's Algorithm

This is an OOP implementation of Dijkstra's Algorithm.

Dijk class takes an object of class WtGraph in its constructor.

```findSPT``` method takes in source vertex as argument and computes the Shortest Path Tree.

```retSPT``` method prints the distances from the source to every other vertex and returns a WtGraph containing the shortest path tree

```tracePath``` method takes destination as argument and prints the path from the source to that destination along with the total distance of the path.
75 changes: 75 additions & 0 deletions Dijkstra/dijk.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "dijk.h"
#include <limits.h>
#include <vector>
#include <stack>
using namespace std;
Dijk::Dijk(WtGraph& g){
graph = g;
SPT = WtGraph(g.getSize());
from = vector<int> (g.getSize()+1, -1);
dist = vector<int> (g.getSize()+1, INT_MAX);
}

void Dijk::findSPT(int source){
vector<int> tmpV;
vector<int> tmpWt;
from[source]=-1;
dist[source] = 0;
for(int i=1;i<=graph.getSize();i++){
tmpV.push_back(i);
tmpWt.push_back(dist[i]);
}

heap.buildHeap(tmpV,tmpWt);

while(!heap.empty()){
int u = heap.retTop();
heap.deleteMin();
for(int v=1;v<=graph.getSize();v++){
int weight = graph.getWt(u,v);
//cout<<u<<" "<<v<<" "<<weight<<endl;
if(weight!=0 && dist[u]!=INT_MAX && dist[v]>dist[u]+weight && heap.inHeap(v)){
dist[v] = dist[u]+weight;
heap.decreaseKey(v,dist[v]);
from[v]=u;
}
}
}
}

WtGraph Dijk::retSPT(){
for(int i=1;i<from.size();i++){
if(dist[i]!=INT_MAX){
cout<<i<<" "<<dist[i]<<endl;
SPT.addDirEdge(i,from[i],dist[i]);
}
else{
cout<<i<<" "<<"INF"<<endl;
}

}
return SPT;
}

void Dijk::tracePath(int dest){
int i = dest;
int total = 0;
if(dist[i]==INT_MAX){
cout<<"No Path Exists\n";
return;
}
stack<int> tmp;
while(from[i]!=-1){
tmp.push(i);
total+=dist[i];
i = from[i];
}
tmp.push(i);

while(!tmp.empty()){
cout<<tmp.top()<<' ';
tmp.pop();
}
cout<<endl;
cout<<"Total Distance: "<<total<<endl;
}
23 changes: 23 additions & 0 deletions Dijkstra/dijk.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "heap.h"
#include "wtgraph.h"
#include <vector>
using namespace std;

#ifndef DIJK_H
#define DIJK_H

class Dijk{
public:
Dijk(WtGraph& g);
void findSPT(int source);
void tracePath(int dest);
WtGraph retSPT();
private:

Heap heap;
WtGraph graph;
WtGraph SPT;
vector<int> from;
vector<int> dist;
};
#endif
119 changes: 119 additions & 0 deletions Dijkstra/heap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
#include "heap.h"
#include <iostream>
using namespace std;

Heap::Heap(){
heap.push_back(-1);
vertices.push_back(-1);
position = vector<int> (1000,-1);
size = 0;
}

void display(vector<int>& a){
for(int i=0;i<a.size();i++){
cout<<i<<" : "<<a[i]<<endl;
}
cout<<endl;
}

int Heap::retTop(){
return vertices[1];

}

void Heap::percolateUp(int i){
while(i>1){
if(heap[i]<heap[i/2]){
int tmp = heap[i];
int tmp2 = vertices[i];
position[tmp2] = i/2;
position[vertices[i/2]] = i;
heap[i] = heap[i/2];
vertices[i] = vertices[i/2];
heap[i/2] = tmp;
vertices[i/2] = tmp2;
i/=2;

}
else{
break;
}
}
}

void Heap::percolateDown(int i){
while(2*i<heap.size()){
int minChild = 2*i;
if(2*i+1 < heap.size() && heap[2*i]>heap[2*i+1]){
minChild = 2*i+1;
}
if(heap[i]>heap[minChild]){
int tmp = heap[i];
int tmp2 = vertices[i];

position[tmp2] = minChild;
position[vertices[minChild]] = i;

heap[i] = heap[minChild];
vertices[i] = vertices[minChild];
heap[minChild] = tmp;
vertices[minChild] = tmp2;
}
i=minChild;
}
}
bool Heap::insert(int wt,int node){
heap.push_back(wt);
vertices.push_back(node);
size++;
int i = heap.size()-1;
position[node]=i;
percolateUp(i);
}

void Heap::decreaseKey(int node, int ne){
int i = position[node];
heap[i] = ne;
percolateUp(i);
}

bool Heap::deleteMin(){
int last = heap.size()-1;

int tmp = heap[1];
heap[1] = heap[last];
heap[last] = tmp;

position[vertices[last]]=1;
int tmp2 = vertices[1];
vertices[1] = vertices[last];
vertices[last] = tmp2;


heap.pop_back();
vertices.pop_back();

percolateDown(1);
position[tmp2] = -1;
size--;
}



void Heap::buildHeap(vector<int>& vt, vector<int>& wt){
heap.clear();
vertices.clear();
heap.push_back(-1);
vertices.push_back(-1);
for(int i=0;i<vt.size();i++){
heap.push_back(wt[i]);
vertices.push_back(vt[i]);
position[vt[i]] = i+1;
}
size = vt.size();


for(int i = heap.size()/2; i>0;i--){
percolateDown(i);
}
}
31 changes: 31 additions & 0 deletions Dijkstra/heap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <iostream>
#include <vector>
using namespace std;

#ifndef HEAP_H
#define HEAP_H


class Heap{
public:
Heap();
bool insert(int wt, int node);
int retTop();
inline bool empty(){
return size==0;
}
inline bool inHeap(int node){
return position[node]!=-1;
}
bool deleteMin();
void decreaseKey(int key, int ne);
void buildHeap(vector<int>& vt, vector<int>& wt);
private:
void percolateUp(int i);
void percolateDown(int i);
vector<int> heap;
vector<int> vertices;
vector<int> position;
int size;
};
#endif
70 changes: 70 additions & 0 deletions Dijkstra/wtgraph.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <iostream>
#include <vector>
#include <queue>
#include "wtgraph.h"
using namespace std;

WtGraph::WtGraph(){
size=0;
}

WtGraph::WtGraph(int n){
size = n;
visited= vector<bool> (n+1,0);
adjMat = vector<vector<int> >(n+1, vector<int> (n+1,0));
}

WtGraph::WtGraph(const WtGraph& from){
size = from.size;
visited= vector<bool> (from.size+1,0);
adjMat = from.adjMat;
}

void WtGraph::operator= (const WtGraph& from){
size = from.size;
visited= vector<bool> (from.size+1,0);
adjMat = from.adjMat;
}

void WtGraph::addEdge(int u, int v, int wt){
adjMat[u][v]= wt;
adjMat[v][u]= wt;
}
void WtGraph::addDirEdge(int u, int v, int wt){
adjMat[u][v]= wt;
}
void WtGraph::bfs(int source){
queue<int> que;
que.push(source);
visited[source] = true;
visit(source);
while(!que.empty()){
int u = que.front();
que.pop();
for(int v=1;v<=size;v++){
if(adjMat[u][v]!=0 && !visited[v]){
visit(v);
visited[v] = true;
que.push(v);
}
}
}

}

void WtGraph::bfs(){
for(int i=1;i<=size;i++){
if(!visited[i]){
bfs(i);
}
}
clear();
}

void WtGraph::clear(){
visited = vector<bool> (size+1,0);
}

void WtGraph::visit(int src){
cout<<src<<endl;
}
30 changes: 30 additions & 0 deletions Dijkstra/wtgraph.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <vector>
using namespace std;
#ifndef WTGRAPH_H
#define WTGRAPH_H

class WtGraph{
public:
WtGraph();
WtGraph(int n);
WtGraph(const WtGraph &from);
void operator = (const WtGraph & from);
void addEdge(int u, int v, int wt);
void addDirEdge(int u, int v, int wt);
inline int getSize(){
return size;
}
inline int getWt(int u, int v){
return adjMat[u][v];
}
void bfs(int source);
void bfs();
void visit(int src);
void clear();
private:
vector<vector<int> > adjMat;
vector<bool> visited;
int size;

};
#endif