Skip to content

Commit 9e8b329

Browse files
committed
shortest_path
1 parent 66a24e2 commit 9e8b329

File tree

3 files changed

+200
-0
lines changed

3 files changed

+200
-0
lines changed

dijkstra.cpp

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// import visualization libraries {
2+
#include "algorithm-visualizer.h"
3+
// }
4+
5+
#include <vector>
6+
#include <string>
7+
#include <limits>
8+
9+
using json = nlohmann::json;
10+
11+
// Tracers: graph, array1d (S) and log console
12+
GraphTracer tracer = GraphTracer().directed(false).weighted().layoutCircle();
13+
Array1DTracer tracerS = Array1DTracer("Distances");
14+
LogTracer logger = LogTracer("Console");
15+
16+
int main() {
17+
const int N = 5;
18+
// generate random graph like JS example: Randomize.Graph({ N: 5, ratio: 1, directed: false, weighted: true })
19+
std::vector<int> Gmat(N * N);
20+
Randomize::Integer randWeight(1, 9);
21+
Randomize::Graph<int> Ggen(N, 1.0, randWeight);
22+
// do NOT chain these methods: they return by value, which would modify a temporary
23+
// (so Ggen would keep its defaults). Call them separately to modify the original.
24+
Ggen.directed(false);
25+
Ggen.weighted(true);
26+
Ggen.fill(Gmat.data());
27+
28+
// convert to 2D vector for tracer.set
29+
std::vector<std::vector<int>> G2(N, std::vector<int>(N));
30+
for (int i = 0; i < N; ++i) {
31+
for (int j = 0; j < N; ++j) {
32+
G2[i][j] = Gmat[i * N + j];
33+
}
34+
}
35+
36+
// initialize S (distance array) with INF
37+
const int INF = std::numeric_limits<int>::max();
38+
std::vector<int> S(N, INF);
39+
40+
// layout and initial set
41+
Layout::setRoot(VerticalLayout({tracer, tracerS, logger}));
42+
tracer.log(logger);
43+
tracer.set(G2);
44+
45+
// prepare display array for tracerS: use strings for INF, numbers otherwise
46+
std::vector<json> Sdisplay(N);
47+
for (int i = 0; i < N; ++i) Sdisplay[i] = "INF";
48+
tracerS.set(Sdisplay);
49+
Tracer::delay();
50+
51+
// pick random start and end (s != e)
52+
Randomize::Integer randNode(0, N - 1);
53+
int s = randNode.create();
54+
int e;
55+
do { e = randNode.create(); } while (e == s);
56+
57+
logger.println(std::string("finding the shortest path from ") + std::to_string(s) + " to " + std::to_string(e));
58+
Tracer::delay();
59+
60+
// Dijkstra
61+
std::vector<bool> D(N, false);
62+
S[s] = 0;
63+
tracerS.patch(s, 0);
64+
Tracer::delay();
65+
tracerS.depatch(s);
66+
tracerS.select(s);
67+
68+
int k = N;
69+
while (k--) {
70+
int minIndex = -1;
71+
int minDistance = INF;
72+
for (int i = 0; i < N; ++i) {
73+
if (!D[i] && S[i] < minDistance) {
74+
minDistance = S[i];
75+
minIndex = i;
76+
}
77+
}
78+
if (minDistance == INF) break;
79+
80+
D[minIndex] = true;
81+
tracerS.select(minIndex);
82+
tracer.visit(minIndex);
83+
Tracer::delay();
84+
85+
for (int i = 0; i < N; ++i) {
86+
if (G2[minIndex][i] && S[i] > S[minIndex] + G2[minIndex][i]) {
87+
S[i] = S[minIndex] + G2[minIndex][i];
88+
tracerS.patch(i, S[i]);
89+
tracer.visit(i, minIndex, S[i]);
90+
Tracer::delay();
91+
tracerS.depatch(i);
92+
tracer.leave(i, minIndex);
93+
Tracer::delay();
94+
}
95+
}
96+
97+
tracer.leave(minIndex);
98+
Tracer::delay();
99+
}
100+
101+
if (S[e] == INF) {
102+
logger.println(std::string("there is no path from ") + std::to_string(s) + " to " + std::to_string(e));
103+
} else {
104+
logger.println(std::string("the shortest path from ") + std::to_string(s) + " to " + std::to_string(e) + " is " + std::to_string(S[e]));
105+
}
106+
107+
Tracer::delay();
108+
return 0;
109+
}

out.exe

485 KB
Binary file not shown.

test.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// import visualization libraries {
2+
#include "algorithm-visualizer.h"
3+
// }
4+
5+
#include <vector>
6+
#include <string>
7+
#include <limits>
8+
9+
using namespace std;
10+
11+
int main() {
12+
// define tracer variables
13+
GraphTracer tracer = GraphTracer("Graph").weighted();
14+
LogTracer logger = LogTracer("Console");
15+
Layout::setRoot(VerticalLayout({tracer, logger}));
16+
tracer.log(logger);
17+
18+
// create random weighted graph
19+
const int N = 5;
20+
const double ratio = 1.0; // fully connected
21+
Randomize::Graph<int> rg(N, ratio);
22+
rg.weighted(true);
23+
vector<int> G(N * N);
24+
rg.fill(G.data());
25+
26+
// convert adjacency matrix to json and set tracer
27+
nlohmann::json jG = nlohmann::json::array();
28+
for (int i = 0; i < N; i++) {
29+
nlohmann::json row = nlohmann::json::array();
30+
for (int j = 0; j < N; j++) {
31+
row.push_back(G[i * N + j]);
32+
}
33+
jG.push_back(row);
34+
}
35+
tracer.set(jG);
36+
Tracer::delay();
37+
38+
// Floyd--Warshall
39+
const double MAX_VALUE = numeric_limits<double>::infinity();
40+
vector<vector<double>> S(N, vector<double>(N));
41+
for (int i = 0; i < N; i++) {
42+
for (int j = 0; j < N; j++) {
43+
if (i == j) S[i][j] = 0;
44+
else if (G[i * N + j] > 0) S[i][j] = G[i * N + j];
45+
else S[i][j] = MAX_VALUE;
46+
}
47+
}
48+
49+
logger.println("finding the shortest paths from and to all nodes");
50+
51+
for (int k = 0; k < N; k++) {
52+
for (int i = 0; i < N; i++) {
53+
if (k == i) continue;
54+
// visualize
55+
tracer.visit(k, i);
56+
Tracer::delay();
57+
for (int j = 0; j < N; j++) {
58+
if (i == j || j == k) continue;
59+
// visualize
60+
tracer.visit(j, k);
61+
Tracer::delay();
62+
if (S[i][j] > S[i][k] + S[k][j]) {
63+
// visualize
64+
tracer.visit(j, i, S[i][j]);
65+
Tracer::delay();
66+
S[i][j] = S[i][k] + S[k][j];
67+
// visualize
68+
tracer.leave(j, i, S[i][j]);
69+
}
70+
// visualize
71+
tracer.leave(j, k);
72+
}
73+
// visualize
74+
tracer.leave(k, i);
75+
Tracer::delay();
76+
}
77+
}
78+
79+
// logger output
80+
for (int i = 0; i < N; i++) {
81+
for (int j = 0; j < N; j++) {
82+
if (S[i][j] == MAX_VALUE) {
83+
logger.println(string("there is no path from ") + to_string(i) + " to " + to_string(j));
84+
} else {
85+
logger.println(string("the shortest path from ") + to_string(i) + " to " + to_string(j) + " is " + to_string(S[i][j]));
86+
}
87+
}
88+
}
89+
90+
return 0;
91+
}

0 commit comments

Comments
 (0)