1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
|
/*This is a complete and correctly functioning
Shortest Path algorithm in C++ using Dijkstra's Algorithm.
For information on how Dijkstra's Algorithm works:
Visit the following link: https://www.youtube.com/watch?v=WN3Rb9wVYDY */
/*This Program was designed and constructed by (Mazhar Mustapha)*/
#include <iostream>
#include <string>
#include <cstdlib>
#include <vector>
using namespace std;
struct node { // Struct is for node or letter in the diagram, each node has a value attached to it according to Dijkstra's algorithm
char symbol;
int v;
};
struct path { // Struct is for path of each edge. Each edge has a specific length
string movement;
int L;
};
void display(node *, int, path *, int, char, char); // Neatly display results of input
void test_path(char, char, path *, node *, int); // The actual process of testing and finding the shortest path
int find_path_sub(path *, char, int); // Find subscript for path location.
int find_path_sub_two(char); // Find subscript using last character in a string.
int find_path_sub_third(char); // Find subscript using first character in a string.
string find_path(char, node *, int); // Returns the deciphered string which had lowest path value.
int main()
{
int x; char s, e;
node *ptrN; path *ptrP;
cout << "# of vertices: "; cin >> x; // Number of nodes
const int n = x;
ptrN = new node[n]; x = 97;
for (int i = 0; i < n; i++)
{
ptrN[i].symbol = x; //Assigns a letter starting 'a' and increments to the defined number of n.
x++;
}
cout << "Enter start and end: "; cin >> s >> e; // Start and Ending nodes, defined by its letter.
for (int i = 0; i < n; i++)
{
if (s == ptrN[i].symbol)
ptrN[i].v = 0; // Set starting node value to 0
else
ptrN[i].v = 9999999; // Set all other nodes to INFINITE.
}
cout << "Enter number of edges: "; cin >> x; // Number of connections
const int m = x;
ptrP = new path[m]; // Allocate number of paths needed.
for (int i = 0; i < m; i++)
{
cin.ignore(20, '\n');
cout << "[PATH] ";
if (i == 0)
{
cout << "!ALPHABETICAL ORDER {EX. ab = (a to b)}"; // It is ESSENTIAL that the inputs here are entered in Alphebetical order, otherwise there will be errors.
}
cout << "| Edge " << (i + 1) << ": ";
getline(cin, ptrP[i].movement);
cout << "Length: "; cin >> ptrP[i].L;
}
display(ptrN, n, ptrP, m, s, e);
test_path(s, e, ptrP, ptrN, m);
delete[] ptrP;
delete[] ptrN;
system("PAUSE");
return 0;
}
void display(node *PtrN, int n, path *PtrP, int m, char start, char end)
{
cout << "Vertices: ";
for (int i = 0; i < n; i++)
{
cout << PtrN[i].symbol << " ";
}
cout << endl << "Start: " << start << endl << "End: " << end << endl;
cout << "-----PATHS-----\n";
for (int i = 0; i < m; i++)
{
cout << PtrP[i].movement;
cout << " - [L] = " << PtrP[i].L;
cout << endl;
}
}
void test_path(char start, char end, path *ptr, node *Ptr, int m)
{
vector<int> record;
vector<string> final;
char begin = start;
int x, y, z, L;
bool initial = true;
string t, fpath;
while (begin != end)
{
if(initial)
x = find_path_sub(ptr, begin, m);
initial = false;
t = ptr[x].movement; // Set t with first path for while loop to activate.
while (t[0] == begin && x < m)
{
y = find_path_sub_two(t[1]);
z = find_path_sub_third(t[0]);
Ptr[y].v = ptr[x].L + Ptr[z].v;
record.push_back(Ptr[y].v);
x++;
if (x == m)
continue;
t = ptr[x].movement; // test while loop at the beginning.
}
if (record.size() != 0) {
L = record[0];
for (int i = 0; i < record.size(); i++)
{
if (record[i] < L)
L = record[i];
}
}
fpath = find_path(begin, Ptr, L);
final.push_back(fpath);
record.clear(); // Clear record for next loop.
x = 0; // x equals 0 for safety purposes.
initial = true; // Initial true for t to contain next path.
begin = fpath[1]; // Begin ewuals the last character of the string. Example: a to b, now we need to start from b.
}
cout << "Final Path: ";
for (int i = 0; i < final.size(); i++)
{
cout << final[i] << " ";
}
cout << endl;
}
int find_path_sub(path *ptr, char start, int size)
{
string temp;
for (int i = 0; i < size; i++)
{
temp = ptr[i].movement;
if (start == temp[0])
return i;
}
}
int find_path_sub_two(char last)
{
int j = 97;
char test;
for (int i = 0; ;i++)
{
test = j;
if (test == last)
return i;
j++;
}
}
int find_path_sub_third(char first)
{
int j = 97;
char test;
for (int i = 0; ;i++)
{
test = j;
if (test == first)
return i;
j++;
}
}
string find_path(char b, node *ptr, int value)
{
string f = " ";
f[0] = b;
for (int i = 0; ;i++)
{
if (value == ptr[i].v)
{
f[1] = ptr[i].symbol;
break;
}
}
return f;
}
|