dijk
This commit is contained in:
parent
3b749153b8
commit
874c276723
1 changed files with 188 additions and 0 deletions
188
dijk.c
Normal file
188
dijk.c
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
|
||||
/*
|
||||
* Imbus 2025
|
||||
*
|
||||
* PQ-less dijkstra in quadratic complexity
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define DIM 26
|
||||
|
||||
#define A 0
|
||||
#define B 1
|
||||
#define C 2
|
||||
#define D 3
|
||||
#define E 4
|
||||
#define F 5
|
||||
#define G 6
|
||||
#define H 7
|
||||
#define I 8
|
||||
#define J 9
|
||||
#define K 10
|
||||
#define L 11
|
||||
#define M 12
|
||||
#define N 13
|
||||
#define O 14
|
||||
#define P 15
|
||||
#define Q 16
|
||||
#define R 17
|
||||
#define S 18
|
||||
#define T 19
|
||||
#define U 20
|
||||
#define V 21
|
||||
#define W 22
|
||||
#define X 23
|
||||
#define Y 24
|
||||
#define Z 25
|
||||
|
||||
/* Node to character */
|
||||
#define ntoch(n) ('A' + (char)(n % 26))
|
||||
|
||||
/* Some helpers */
|
||||
#define set_dist(from, to, d) g[((int)from)][((int)to)] = (int)d
|
||||
#define get_dist(from, to) g[((int)from)][((int)to)]
|
||||
|
||||
/* Adjacency matrix */
|
||||
int g[DIM][DIM] = {};
|
||||
|
||||
void printmat(int mat[DIM][DIM]) {
|
||||
printf("## ");
|
||||
for (int h = 0; h < DIM; h++) printf("%c ", ntoch(h));
|
||||
printf("\n");
|
||||
printf(" ");
|
||||
for (int h = 0; h < DIM; h++) printf("%s", "__");
|
||||
printf("\n");
|
||||
for (int i = 0; i < DIM; i++) {
|
||||
printf("%c |", ntoch(i));
|
||||
for (int j = 0; j < DIM; j++) {
|
||||
printf("%c ", ntoch(mat[i][j]));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void dijkstra(int mat[DIM][DIM], int prev[DIM], int dist[DIM], int s) {
|
||||
int visited[DIM] = {0};
|
||||
|
||||
for (int i = 0; i < DIM; i++) {
|
||||
dist[i] = INT_MAX;
|
||||
prev[i] = -1;
|
||||
}
|
||||
|
||||
dist[s] = 0;
|
||||
prev[s] = 0;
|
||||
|
||||
for (int i = 0; i < DIM; i++) {
|
||||
// Pick first unvisited with smallest dist
|
||||
int u = -1;
|
||||
int min = INT_MAX;
|
||||
|
||||
for (int j = 0; j < DIM; j++) {
|
||||
if (!visited[j] && dist[j] < min) {
|
||||
min = dist[j];
|
||||
u = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (u == -1)
|
||||
break;
|
||||
visited[u] = 1;
|
||||
|
||||
for (int v = 0; v < DIM; v++) {
|
||||
if (get_dist(u, v) > 0 && !visited[v]) {
|
||||
if (dist[u] + get_dist(u, v) < dist[v]) {
|
||||
dist[v] = dist[u] + get_dist(u, v);
|
||||
prev[v] = u;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void path_reconstruct(int prev[DIM], int dist[DIM], int s, int t) {
|
||||
if (dist[t] == INT_MAX) {
|
||||
printf("No path from %c to %c\n", ntoch(s), ntoch(t));
|
||||
return;
|
||||
}
|
||||
|
||||
int path[DIM];
|
||||
int len = 0;
|
||||
|
||||
// Walk backwards from target to source
|
||||
for (int v = t; v != -1; v = prev[v]) {
|
||||
path[len++] = v;
|
||||
if (v == s)
|
||||
break;
|
||||
}
|
||||
|
||||
if (path[len - 1] != s) {
|
||||
printf("No path from %c to %c\n", ntoch(s), ntoch(t));
|
||||
return;
|
||||
}
|
||||
|
||||
// Print path in correct order
|
||||
printf("Path (cost %d): ", dist[t]);
|
||||
for (int i = len - 1; i >= 0; i--) {
|
||||
printf("%c", ntoch(path[i]));
|
||||
if (i > 0)
|
||||
printf(" -> ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void init_graph(void) {
|
||||
set_dist(A, B, 4);
|
||||
set_dist(A, C, 9);
|
||||
set_dist(B, D, 2);
|
||||
set_dist(B, E, 5);
|
||||
set_dist(C, B, 2);
|
||||
set_dist(C, F, 7);
|
||||
set_dist(D, C, 1);
|
||||
set_dist(E, C, 2);
|
||||
set_dist(F, G, 3);
|
||||
set_dist(G, H, 6);
|
||||
set_dist(H, I, 1);
|
||||
set_dist(I, J, 8);
|
||||
set_dist(J, K, 4);
|
||||
set_dist(K, L, 5);
|
||||
set_dist(L, M, 2);
|
||||
set_dist(M, N, 3);
|
||||
set_dist(N, O, 7);
|
||||
set_dist(O, P, 1);
|
||||
set_dist(P, Q, 2);
|
||||
set_dist(Q, R, 6);
|
||||
set_dist(R, S, 3);
|
||||
set_dist(S, T, 5);
|
||||
set_dist(T, U, 2);
|
||||
set_dist(U, V, 1);
|
||||
set_dist(V, W, 4);
|
||||
set_dist(W, X, 7);
|
||||
set_dist(X, Y, 2);
|
||||
set_dist(Y, Z, 3);
|
||||
set_dist(Z, A, 8);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
for (int i = 0; i < DIM; i++) {
|
||||
for (int j = 0; j < DIM; j++) {
|
||||
g[i][j] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
init_graph();
|
||||
|
||||
printmat(g);
|
||||
|
||||
int prev[DIM] = {0};
|
||||
int dist[DIM] = {0};
|
||||
dijkstra(g, prev, dist, A);
|
||||
|
||||
for (int k = 0; k < DIM; k++) {
|
||||
printf("%c prev: %c\n", ntoch(k), ntoch(prev[k]));
|
||||
}
|
||||
|
||||
path_reconstruct(prev, dist, A, Z);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue