From f0ceb19a7ca63712f665a39c31e625e6d47ac0a7 Mon Sep 17 00:00:00 2001 From: ParadoxPD Date: Sun, 14 Dec 2025 19:40:30 +0530 Subject: [PATCH 1/2] Added java implementation of GraphX with Dijkstra --- GraphX.java | 206 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 GraphX.java diff --git a/GraphX.java b/GraphX.java new file mode 100644 index 0000000..db7d3fe --- /dev/null +++ b/GraphX.java @@ -0,0 +1,206 @@ +import java.util.*; + +final class NodeKey { + private final int[] coords; + private final int hash; + + NodeKey(int... coords) { + this.coords = coords; + this.hash = Arrays.hashCode(coords); + } + + @Override + public int hashCode() { + return hash; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof NodeKey)) return false; + return Arrays.equals(coords, ((NodeKey) o).coords); + } +} + +final class NodeIndexer { + private final Map map = new HashMap<>(); + + int getOrCreate(int... coords) { + return map.computeIfAbsent(new NodeKey(coords), k -> map.size()); + } + + Integer get(int... coords) { + return map.get(new NodeKey(coords)); + } + + int size() { + return map.size(); + } +} + +class Graph { + static class Edge { + final int to; + final long w; + + Edge(int t, long w) { + this.to = t; + this.w = w; + } + } + + private final boolean directed; + private final NodeIndexer indexer = new NodeIndexer(); + private final List> adj = new ArrayList<>(); + + public Graph(boolean directed) { + this.directed = directed; + } + + private void ensure(int u) { + while (adj.size() <= u) adj.add(new ArrayList<>()); + } + + public void addEdge(int from, int to, int w) { + addEdge(new int[] {from}, new int[] {to}, w); + } + + public void addEdge(int[] from, int[] to, long w) { + int u = indexer.getOrCreate(from); + int v = indexer.getOrCreate(to); + + ensure(u); + ensure(v); + + adj.get(u).add(new Edge(v, w)); + if (!directed) adj.get(v).add(new Edge(u, w)); + } + + public void addEdge(int[] from, int[] to) { + addEdge(from, to, 0); + } + + public void addEdge(int from, int to) { + addEdge(from, to, 0); + } + + int idOf(int... node) { + Integer id = indexer.get(node); + if (id == null) throw new IllegalArgumentException("Node not present"); + return id; + } + + int size() { + return indexer.size(); + } + + List edges(int u) { + return adj.get(u); + } +} + +class Dijkstra { + private final Graph g; + private long[] dist; + private boolean[] visited; + + public Dijkstra(Graph g) { + this.g = g; + } + + public void run(int... source) { + int s = g.idOf(source); + int n = g.size(); + + dist = new long[n]; + visited = new boolean[n]; + Arrays.fill(dist, Long.MAX_VALUE); + + PriorityQueue pq = new PriorityQueue<>(Comparator.comparingLong(a -> a[1])); + dist[s] = 0; + pq.add(new long[] {s, 0}); + + while (!pq.isEmpty()) { + long[] cur = pq.poll(); + int u = (int) cur[0]; + + if (visited[u]) continue; + visited[u] = true; + + for (Graph.Edge e : g.edges(u)) { + if (!visited[e.to] && dist[u] + e.w < dist[e.to]) { + dist[e.to] = dist[u] + e.w; + pq.add(new long[] {e.to, dist[e.to]}); + } + } + } + } + + public long minDist(int... target) { + return dist[g.idOf(target)]; + } +} + +class BFS { + private final Graph g; + private int[] dist; + + public BFS(Graph g) { + this.g = g; + } + + public void run(int... source) { + int s = g.idOf(source); + int n = g.size(); + + dist = new int[n]; + Arrays.fill(dist, -1); + + ArrayDeque q = new ArrayDeque<>(); + q.add(s); + dist[s] = 0; + + while (!q.isEmpty()) { + int u = q.poll(); + for (Graph.Edge e : g.edges(u)) { + if (dist[e.to] == -1) { + dist[e.to] = dist[u] + 1; + q.add(e.to); + } + } + } + } + + public int minDist(int... target) { + return dist[g.idOf(target)]; + } +} + +public class GraphXBetter { + public static void main(String[] args) { + Graph g = new Graph(true); + + // Add weighted edges + g.addEdge(1, 2, 5); + g.addEdge(1, 3, 3); + g.addEdge(2, 4, 6); + g.addEdge(3, 4, 2); + g.addEdge(4, 5, 8); + + // Run BFS from node 1 + BFS bfs = new BFS(g); + bfs.run(1); + System.out.println("BFS Distance from 1 to 5: " + bfs.minDist(5)); + + // Run Dijkstra from node 1 + Dijkstra dijkstra = new Dijkstra(g); + dijkstra.run(1); + System.out.println("Dijkstra Distance from 1 to 5: " + dijkstra.minDist(5)); + + // Example with tuple-like nodes (using coordinates) + g.addEdge(new int[] {0, 0}, new int[] {0, 1}, 10); + g.addEdge(new int[] {0, 1}, new int[] {1, 1}, 15); + + dijkstra.run(0, 0); + System.out.println("Distance to (1,1): " + dijkstra.minDist(1, 1)); + } +} From 4cfb992b2f4cb6245d40b3d839ad0f886a836062 Mon Sep 17 00:00:00 2001 From: ParadoxPD Date: Mon, 15 Dec 2025 21:13:22 +0530 Subject: [PATCH 2/2] Added python implementation of GraphX with Dijkstra --- GraphX.py | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 GraphX.py diff --git a/GraphX.py b/GraphX.py new file mode 100644 index 0000000..ba08202 --- /dev/null +++ b/GraphX.py @@ -0,0 +1,160 @@ +import heapq +from collections import deque + + +class NodeIndexer: + __slots__ = ("map",) + + def __init__(self): + self.map = {} + + def get_or_create(self, key): + idx = self.map.get(key) + if idx is None: + idx = len(self.map) + self.map[key] = idx + return idx + + def get(self, key): + return self.map.get(key) + + def size(self): + return len(self.map) + + +class Graph: + __slots__ = ("directed", "indexer", "adj") + + def __init__(self, directed=True): + self.directed = directed + self.indexer = NodeIndexer() + self.adj = [] + + def _ensure(self, u): + if u >= len(self.adj): + self.adj.extend([] for _ in range(u + 1 - len(self.adj))) + + def add_edge(self, u, v, w=0): + # normalize nodes → tuple + if not isinstance(u, tuple): + u = (u,) + if not isinstance(v, tuple): + v = (v,) + + ui = self.indexer.get_or_create(u) + vi = self.indexer.get_or_create(v) + + self._ensure(ui) + self._ensure(vi) + + self.adj[ui].append((vi, w)) + if not self.directed: + self.adj[vi].append((ui, w)) + + def id_of(self, node): + if not isinstance(node, tuple): + node = (node,) + idx = self.indexer.get(node) + if idx is None: + raise ValueError("Node not present") + return idx + + def size(self): + return self.indexer.size() + + +class BFS: + __slots__ = ("g", "dist") + + def __init__(self, g): + self.g = g + self.dist = [] + + def run(self, source): + if not isinstance(source, tuple): + source = (source,) + s = self.g.id_of(source) + n = self.g.size() + + dist = [-1] * n + dist[s] = 0 + q = deque([s]) + + while q: + u = q.popleft() + for v, _ in self.g.adj[u]: + if dist[v] == -1: + dist[v] = dist[u] + 1 + q.append(v) + + self.dist = dist + + def min_dist(self, target): + if not isinstance(target, tuple): + target = (target,) + return self.dist[self.g.id_of(target)] + + +class Dijkstra: + __slots__ = ("g", "dist") + + def __init__(self, g): + self.g = g + self.dist = [] + + def run(self, source): + if not isinstance(source, tuple): + source = (source,) + s = self.g.id_of(source) + n = self.g.size() + + dist = [float("inf")] * n + dist[s] = 0 + pq = [(0, s)] + + while pq: + d, u = heapq.heappop(pq) + + if d != dist[u]: + continue + + for v, w in self.g.adj[u]: + nd = d + w + if nd < dist[v]: + dist[v] = nd + heapq.heappush(pq, (nd, v)) + + self.dist = dist + + def min_dist(self, target): + if not isinstance(target, tuple): + target = (target,) + return self.dist[self.g.id_of(target)] + + +# ====================== +# Example +# ====================== + +if __name__ == "__main__": + g = Graph(directed=True) + + g.add_edge(1, 2, 5) + g.add_edge(1, 3, 3) + g.add_edge(2, 4, 6) + g.add_edge(3, 4, 2) + g.add_edge(4, 5, 8) + + bfs = BFS(g) + bfs.run(1) + print("BFS 1 → 5:", bfs.min_dist(5)) + + d = Dijkstra(g) + d.run(1) + print("Dijkstra 1 → 5:", d.min_dist(5)) + + g.add_edge((0, 0), (0, 1), 10) + g.add_edge((0, 1), (1, 1), 15) + + d.run((0, 0)) + print("Distance to (1,1):", d.min_dist((1, 1)))