code wiki / _hdl_build / nx_geo_route.nx
nx_geo_route.nx source
↩ module page · 74 lines · 2930 B
1// nx_geo_route.nx -- LIB: GEO-008 routing -- INTEGER-EXACT Dijkstra shortest path on a weighted
2// graph (road network). Edge weights are integer meters (from GEO-003 geo_distance), so the path is
3// EXACT and DETERMINISTIC -- the marquee exceed angle vs float routers (OSRM/Valhalla/Google), whose
4// float weights admit non-deterministic tie-breaking. Adjacency-matrix form (clear + small-graph
5// fast; a heap is the scale rung, GEO-008b). Composes the rungs below; production road graphs ride
6// the sovereign store (OSM as last-mile DATA). license_tier: ORIGINAL
7import "nx_syscalls.nx"
8const GEO_MAGIC_1024: i64 = 1024
9
10const GEO_INF: i64 = 1099511627776 // 2^40 -- "unreachable" sentinel (well above any earth path in m)
11
12// Dijkstra from `src` over an n-node graph. adj is a flat n*n matrix; adj[u*n+v] > 0 is the weight
13// of edge u->v, 0 means no edge. Writes shortest distances to dist[] and predecessors to prev[]
14// (prev[src] = -1; prev[unreachable] = -1, dist = GEO_INF).
15func geo_dijkstra(adj: *i64, n: i64, src: i64, dist: *i64, prev: *i64) -> i64 {
16 let visited: *i64 = sys_mmap(8 * n) as *i64
17 var i: i64 = 0
18 while i < n { dist[i] = GEO_INF; prev[i] = 0 - 1; visited[i] = 0; i = i + 1 }
19 dist[src] = 0
20 var iter: i64 = 0
21 while iter < n {
22 var u: i64 = 0 - 1
23 var best: i64 = GEO_INF
24 var j: i64 = 0
25 while j < n {
26 if visited[j] == 0 { if dist[j] < best { best = dist[j]; u = j } }
27 j = j + 1
28 }
29 if u < 0 { iter = n } else {
30 visited[u] = 1
31 var v: i64 = 0
32 while v < n {
33 let w: i64 = adj[u * n + v]
34 if w > 0 {
35 let nd: i64 = dist[u] + w
36 if nd < dist[v] { dist[v] = nd; prev[v] = u }
37 }
38 v = v + 1
39 }
40 iter = iter + 1
41 }
42 }
43 return 0
44}
45
46// reconstruct the path src->dest from prev[] into path[] (src first); returns hop count (0 if no path).
47func geo_path(prev: *i64, src: i64, dest: i64, path: *i64) -> i64 {
48 let tmp: *i64 = sys_mmap(8 * GEO_MAGIC_1024) as *i64
49 var k: i64 = 0
50 var cur: i64 = dest
51 var go: i64 = 1
52 while go == 1 {
53 tmp[k] = cur
54 k = k + 1
55 if cur == src { go = 0 } else {
56 if prev[cur] < 0 { go = 0; k = 0 } else { cur = prev[cur] } // no path -> empty
57 }
58 }
59 var i: i64 = 0
60 while i < k { path[i] = tmp[k - 1 - i]; i = i + 1 }
61 return k
62}
63
64// ISOCHRONE: indices of all nodes reachable within `budget` cost from the source (dist[] from
65// geo_dijkstra). The "what's reachable within X" query. Returns count; writes indices to out_idx.
66func geo_isochrone(dist: *i64, n: i64, budget: i64, out_idx: *i64) -> i64 {
67 var c: i64 = 0
68 var i: i64 = 0
69 while i < n {
70 if dist[i] <= budget { out_idx[c] = i; c = c + 1 }
71 i = i + 1
72 }
73 return c
74}