-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bda6810
commit 683c558
Showing
3 changed files
with
506 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,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; | ||
} |
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,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) |
Oops, something went wrong.