This commit is contained in:
Imbus 2025-12-27 02:08:44 +01:00
parent 3b749153b8
commit 874c276723

188
dijk.c Normal file
View 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);
}