diff --git a/graphX/BFS.java b/graphX/BFS.java new file mode 100644 index 0000000..c714549 --- /dev/null +++ b/graphX/BFS.java @@ -0,0 +1,98 @@ +package com.graphX.graphX; + +import com.graphX.graphX.helper.Pair; +import com.graphX.graphX.helper.Triple; + +import java.util.*; + +public class BFS { + List minDistanceFromSource; + List visited; + + Graph graph; + int n; + + public BFS(Graph graph) { + this.graph = graph; + this.n = graph.n; + } + + public void clear() { + minDistanceFromSource = new ArrayList<>(Collections.nCopies(n, -1)); + visited = new ArrayList<>(Collections.nCopies(n, false)); + } + + public void run(int sourceR) { + int source = graph.h.hash(sourceR); + bfs(source); + } + + public void run(Pair sourceR) { + int source = graph.h.hash(sourceR); + bfs(source); + } + + public void run(Triple sourceR) { + int source = graph.h.hash(sourceR); + bfs(source); + } + + public int minDistance(int targetR) { + int target = graph.h.hash(targetR); + return minDistInternal(target); + } + + public int minDistance(Pair targetR) { + int target = graph.h.hash(targetR); + return minDistInternal(target); + } + + public int minDistance(Triple targetR) { + int target = graph.h.hash(targetR); + return minDistInternal(target); + } + + public boolean isVisited(int source) { + return isVisitedInternal(source); + } + public boolean isVisited(Pair sourceR) { + int source = graph.h.hash(sourceR); + return isVisitedInternal(source); + } + public boolean isVisited(Triple sourceR) { + int source = graph.h.hash(sourceR); + return isVisitedInternal(source); + } + + + private void bfs(int source) { + Queue queue = new LinkedList<>(); + queue.add(source); + + minDistanceFromSource.set(source, 0); + + while (!queue.isEmpty()) { + int current = queue.peek(); + + for (int i = 0; i < graph.adjacencyList.get(current).size(); i++) { + int adjNode = graph.adjacencyList.get(current).get(i).first; + if (!visited.get(adjNode)) { + visited.set(adjNode, true); + minDistanceFromSource.set(adjNode, minDistanceFromSource.get(current) + 1); + queue.add(adjNode); + } + } + + queue.poll(); + } + } + + private int minDistInternal(int target) { + return minDistanceFromSource.get(target); + } + + private boolean isVisitedInternal(int target) { + return visited.get(target); + } + +} diff --git a/graphX/Graph.java b/graphX/Graph.java new file mode 100644 index 0000000..1d10689 --- /dev/null +++ b/graphX/Graph.java @@ -0,0 +1,95 @@ +package com.graphX.graphX; + +import com.graphX.graphX.helper.Pair; +import com.graphX.graphX.helper.Triple; + +import java.util.ArrayList; +import java.util.List; + +public class Graph { + boolean isDirected; + + public List>> adjacencyList; + public int n; + public Hash h; + + public Graph(int n) { + this.n = n; + this.isDirected = true; + initialize(); + } + + public Graph(int n, boolean isDirected) { + this.n = n; + this.isDirected = isDirected; + initialize(); + } + + public int hash(int u, int v) { + return h.hash(new Pair<>(u, v)); + } + + public int hash(int u, int v, int k) { + return h.hash(new Triple<>(u, v, k)); + } + + public void addEdge(int u, int v) { + addEdge(u, v, 0); + } + + public void addEdge(Pair u, Pair v) { + addEdge(u, v, 0); + } + + public void addEdge(Triple u, Triple v) { + addEdge(u, v, 0); + } + + public void addEdge(int uR, int vR, int w) { + int u = h.hash(uR); + int v = h.hash(vR); + + addEdgeInternal(u, v, w); + } + + public void addEdge(Pair uR, Pair vR, int w) { + int u = h.hash(uR); + int v = h.hash(vR); + + addEdgeInternal(u, v, w); + } + + public void addEdge(Triple uR, Triple vR, int w) { + int u = h.hash(uR); + int v = h.hash(vR); + + addEdgeInternal(u, v, w); + } + + private void initialize() { + adjacencyList = new ArrayList<>(); + for (int i = 0; i < n; i++) { + adjacencyList.add(new ArrayList<>()); + } + + h = new Hash(); + + } + + private void addEdgeInternal(int u, int v) { + addEdgeInternal(u, v, 0); + } + + private void addEdgeInternal(int u, int v, int w) { + addEdgeWeightedUndirected(u, v, w); + if (!isDirected) { + addEdgeWeightedUndirected(v, u, w); + } + } + + private void addEdgeWeightedUndirected(int u, int v, int w) { + Pair p = new Pair<>(v, w); + adjacencyList.get(u).add(p); + } + +} diff --git a/graphX/Hash.java b/graphX/Hash.java new file mode 100644 index 0000000..7759366 --- /dev/null +++ b/graphX/Hash.java @@ -0,0 +1,31 @@ +package com.graphX.graphX; + +import com.graphX.graphX.helper.Pair; +import com.graphX.graphX.helper.Triple; + +import java.util.Map; +import java.util.HashMap; + +public class Hash{ + private final Map hashTable = new HashMap<>(); + + public Hash() { + } + + public int hash(int x) { + return hash(new Triple<>(x,0,0)); + } + + public int hash(Pair pair) { + return hash(new Triple<>(pair.first, pair.second, 0)); + } + + public int hash(Triple triple) { + if (hashTable.containsKey(triple)) { + return hashTable.get(triple); + } + int hashVal = hashTable.size(); + hashTable.put(triple, hashVal); + return hashVal; + } +} diff --git a/graphX/helper/Pair.java b/graphX/helper/Pair.java new file mode 100644 index 0000000..08d76d8 --- /dev/null +++ b/graphX/helper/Pair.java @@ -0,0 +1,32 @@ +package com.graphX.graphX.helper; + +import java.util.Objects; + +public class Pair { + public final A first; + public final B second; + + public Pair(A first, B second) { + this.first = first; + this.second = second; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof Pair pair)) return false; + return Objects.equals(first, pair.first) && + Objects.equals(second, pair.second); + } + + @Override + public int hashCode() { + return Objects.hash(first, second); + } + + @Override + public String toString() { + return "(" + first + ", " + second + ")"; + } +} + diff --git a/graphX/helper/Triple.java b/graphX/helper/Triple.java new file mode 100644 index 0000000..810f61f --- /dev/null +++ b/graphX/helper/Triple.java @@ -0,0 +1,33 @@ +package com.graphX.graphX.helper; + +import java.util.Objects; + +public class Triple { + private final A first; + private final B second; + private final C third; + + public Triple(A first, B second, C third) { + this.first = first; + this.second = second; + this.third = third; + } + + @Override + public boolean equals(Object object) { + if (this == object) return true; + if (!(object instanceof Triple triple)) return false; + + return first == triple.first && second == triple.second && third == triple.third; + } + + @Override + public int hashCode() { + return Objects.hash(first, second, third); + } + + @Override + public String toString() { + return "(" + first + ", " + second + ", " + third + ")"; + } +}