Skip to content

Commit

Permalink
add dijkstra three solutions
Browse files Browse the repository at this point in the history
  • Loading branch information
nickleefly committed Nov 9, 2013
1 parent bda6810 commit 683c558
Show file tree
Hide file tree
Showing 3 changed files with 506 additions and 0 deletions.
230 changes: 230 additions & 0 deletions cpp/dijkstra_solution1.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <ctime>
#include <cstdlib>
#include <fstream>

const int DEBUG = 0;

// Homework Inputs

const int GSIZE = 50;
const float GRAPH_DENSITY = 0.4;

// Global variable declarations

double ** grfLen;
bool ** grf;

using namespace std;

double prob() {
// REFERENCE: Lecture video 4.14
return (static_cast<double>(rand())/RAND_MAX);
}

// Djikstra shortest path algorithm

class Dijkstra
{

private:
int nNodes;
int nEdges;
double dist[GSIZE];
bool visited[GSIZE];
int previous[GSIZE];
int Q[GSIZE];
int iQ;
public:
int shortestPath (int source, int destination);
void showVisited ();
void showdist();
void showQ();


};
void Dijkstra::showVisited(){ // printout visited array for debugging
if (DEBUG==0) return;
for (int i=0;i<GSIZE;i++) {
cout<<"visited["<<i<<"]="<<visited[i]<<endl;
}
}
void Dijkstra::showQ() { // printout Q array for debugging
if (DEBUG==0) return;
for (int i=0;i<iQ;i++)
cout<<"Q["<<i<<"]="<<Q[i]<<endl;
}
void Dijkstra::showdist() { // printout dist array for debugging
if (DEBUG==0) return;
for (int i=0;i<GSIZE;i++) {
cout<<"dist["<<i<<"]="<<dist[i]<<endl;
}
}
int Dijkstra::shortestPath (int source, int destination) {

// as described in http://en.wikipedia.org/wiki/Dijkstra's_algorithm

int u;
// initilization
if (DEBUG) cout<<"1 - INITIALIZATION"<<endl;
iQ = 0;
for (int i=0;i<GSIZE;i++) {
dist[i] = 1000000;
visited[i] = false;
previous[i] = -1; // undefined
}
dist[source] = 0;
Q[iQ] = source;
iQ++;
showQ();
//cout<<"iQ:" <<iQ<<endl;
//cout<<"Q:" <<Q[1]<<endl;
if (DEBUG) cout<<"2 - START LOOP"<<endl;
while (iQ!=0) {
// Q is not empty
if (DEBUG) cout<<"Q is not empty"<<endl;

if (DEBUG) cout<<"3 - Copy dist to tmpDist"<<endl;
float tmpDist[iQ];
for (int i=0;i<iQ;i++) {
tmpDist[i] = dist[Q[i]];
//cout<<"tmpDist:" <<tmpDist[0]<<endl;
}
if (DEBUG) cout<<"4 - Find vertex in Q with the smallest distance in dist[] and has not been visited"<<endl;
float smallest = tmpDist[0];
int k=0;
while (k<iQ) {
if ( tmpDist[k]<=smallest && !visited[Q[k]]) {
//cout<<"tmpDist:" <<tmpDist[0]<<endl;
smallest = tmpDist[k];
u = Q[k];
if (DEBUG) {cout<<"u=" <<u<<endl;}
}
k++;

}
//cout<<"smallest:" <<smallest<<endl;
showQ();
if (DEBUG) cout<<"uFinal=" <<u<<endl;
if (u==destination) {
cout<<"destination reached="<<u<<" Shortest distance from source="<<dist[u]<<endl;

return(dist[u]);

}

// remove u from Q
// first copy to a temporary array
if (DEBUG) cout<<"5 - Remove u from Q and add it to visited"<<endl;
float tmpQ[iQ];
for (int i=0; i<iQ;i++ ) {
tmpQ[i] = Q[i];
}

// recreat Q array with u removed
int j = 0;
for (int i=0;i<iQ;i++) {
if (tmpQ[i] != u) {
Q[j] = tmpQ[i];
j++;
}
}
iQ--;
if (DEBUG) cout<<"Removed node "<<u<<" from Q"<<endl;
showQ();
if (DEBUG) cout<<"Added node "<<u<<" to visited"<<endl;
visited[u] = true;
showVisited();

// process neighbors (use grfLen)
if (DEBUG) cout<<"6 - Processing neighbors"<<endl;
if (DEBUG) {
for (int i=0;i<GSIZE;i++)
if (grfLen[i][j] != 0)
cout<<"Original: grfLen["<<i<<"]["<<j<<"]"<<grfLen[i][j]<<endl;
}

if (DEBUG) cout<<"7 - Accumulate shortest distance from source"<<endl;
for (int i=0;i<GSIZE;i++) {

if (grfLen[i][u] != 0.0) {
double alt = dist[u]+grfLen[i][u];
if (DEBUG) cout<<"i:"<<i<<" alt:="<<alt<<endl;
if (alt<=dist[i] && !visited[i]) {
if (DEBUG) cout<<"alt="<<alt<<" is less than dist["<<i<<"]="<<dist[i]<<endl;
dist[i] = alt;
previous[i] = u;
Q[iQ]=i;
iQ++;
showQ();
showdist();
}
}

}

}
return(0);
}


int main()
{
//double ** grfLen;
//bool ** grf;
Dijkstra d;

srand(time(0)); // seed rand()
grf = new bool*[GSIZE];
grfLen = new double*[GSIZE];
for (int i=0;i<GSIZE;i++) {
grf [i] = new bool[GSIZE];
grfLen[i] = new double[GSIZE];
}
int actEdges = 0;
for (int i=0;i<GSIZE;i++)
{
for (int j=i;j<GSIZE;j++) {
if (i==j) {
grf[i][j] = false;
grfLen[i][j] = 0.0;
}
else {
grf[i][j] = grf[j][i] = (prob()<GRAPH_DENSITY);
if (grf[i][j] == 1) {
grfLen[i][j] = grfLen[j][i] = float(rand() % 10 + 1);
actEdges++;
}
//cout<<"i="<<i<<" j="<<j<<" edge="<<grf[i][j]<<" length="<<grfLen[i][j]<<endl;
}
}
}
cout<<"actual Edges: "<<actEdges*2<<endl;

for (int i=0;i<GSIZE;i++)
for (int j=i;j<GSIZE;j++)
cout<<"grfLen["<<i<<"]["<<j<<"]="<<grfLen[i][j]<<endl;

// calculate shortest paths and average
int pathLength[GSIZE];
for (int i=0;i<GSIZE;i++) {
pathLength [i] = d.shortestPath(0, i);
cout<<"i="<<i<<" len="<<pathLength [i]<<endl;
}
// average
int k=0;
double total = 0.0;
for (int i=0;i<GSIZE;i++) {
if (pathLength[i] != 0) {
// cout<<pathLength[i]<<endl;
total = total + float(pathLength[i]);
k++;
}
}
double path_average = total/float(k);
cout << "Average: "<<path_average<<endl;

return 0;
}
100 changes: 100 additions & 0 deletions cpp/dijkstra_solution2.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// dijkstra.cpp : Defines the entry point for the console application.
/////
//s->v 1
//s->w 4
//v->w 2
//v->T 6
//w->T 3

#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std ;

//object of this class will be passed to priority_queue so that min element is returned, not max element.
class Comweight{
public:
bool operator()(int& t1, int& t2) // Returns true if t2 is smallerthan t1
{
if (t1 > t2 ) return true;
return false;
}
} ;
priority_queue<int, vector<int>,Comweight > pq ; //the vector<int> will be vecor of edge weights

map< pair<char, char> , int> edge_map ; // maps a pair of nodes(chars ) i.e. an edge to it's weight (an int )
map<char, int> A ;// this map maps a node (a char) to it's shortest distance (an int ) from start node 's'
map<int, pair<char, char> > rev_edge_map ;// maps a weight (an int ) to a pair of nodes(chars )

vector< pair<char, char> > edge_vec ; // vector of pairs of nodes i.e. of edges
vector<char> nodes(4); //vector of nodes (chars)
vector<char> X(4); //vector of nodes ( chars ) whose shortest distance from source has been computed

int main() {

vector<char>::iterator n; //iterator for vector nodes
vector< pair<char, char> > ::iterator e; //iterator for vector edge_vec

A['S'] = 0 ; // 's' is the name of the start node ; shortest path from start node to itself is zero.
X.push_back('S');// 's' is the name of the start node ; it's shortest path from itself has been noted & therefore, it is marked as seen

//Making graph

//nodes
nodes.push_back('S');
nodes.push_back('V');
nodes.push_back('W');
nodes.push_back('T');
//edges
edge_vec.push_back( make_pair('S', 'V') ); edge_vec.push_back( make_pair('V', 'T') ) ;
edge_vec.push_back( make_pair('V', 'W') ); edge_vec.push_back( make_pair('S', 'W') );
edge_vec.push_back( make_pair('W', 'T') ) ;
//edge weights
edge_map [make_pair('S', 'V') ] = 1 ;
edge_map [make_pair('V', 'W') ] = 2 ;
edge_map [make_pair('S', 'W') ] = 4 ;
edge_map [make_pair('V', 'T' ) ] = 6 ;
edge_map [make_pair('W', 'T' ) ] = 3 ;



//cout<<"Edge (s,v) has weight "<<edge_map[make_pair('S', 'V') ]<<endl ;
//cout<<"Edge (v,w) has weight "<<edge_map[make_pair('V', 'W') ]<<endl ;
//cout<<"Edge (s,w) has weight "<<edge_map[make_pair('S', 'W') ]<<endl ;
//cout<<"Edge (v,t) has weight "<<edge_map[make_pair('V', 'T') ]<<endl ;
//cout<<"Edge (w, t) has weight "<<edge_map[make_pair('W', 'T') ]<<endl ;

//cout<<edge_vec.size() ;

pair <char, char > shortest_edge ;

while(X != nodes){

while (! pq.empty()) {
//cout<< pq.top() << endl ;
pq.pop() ;//cleaning pq for next iteration
}
for(e = edge_vec.begin(); e != edge_vec.end() ; e++){
if ( ( binary_search(X.begin(), X.end(), e -> first) && !(binary_search(X.begin(), X.end(), e -> second) ) ) )
{
//put every candidate wieght on the min heap
pq.push( edge_map[ (*e) ] + A[ e->first ] ) ;
rev_edge_map [ edge_map[ (*e) ] + A[ e->first ] ] = *e ;
}
}
//extract the candidate with minimum weight
//cout<< pq.top() << endl ;
shortest_edge = rev_edge_map [ pq.top() ] ;
cout<< shortest_edge.first << shortest_edge.second<<endl ;
pq.pop() ;

X .push_back( shortest_edge.second ) ;
A[ shortest_edge.second ] = edge_map[ shortest_edge ] + A[ shortest_edge.first ] ;
}

return 0 ;
}

// binary_search(u.begin(), u.end(), 5)
Loading

0 comments on commit 683c558

Please sign in to comment.