I have a graph where its nodes are in the following structure:
Class Node:
int source;
int next;
So, I have the following nodes: [(1,2), (2,3), (3,4), (1,4)]
I wanted to list all possible paths from 1 to 3 it would list: [[(1,2),(2,3)],[(1,4),(4,3)].
I'm trying with this code, but I'm missing something:
public List<Node> getNodeNeighbors(Node n) {
List<Node> filteredNodes = new ArrayList<Node>();
List<Node> allNodes = (List<Node>) nodesRepository.findAll();
for (Node node: allNodes) {
if (node.source == n.next) {
filteredNodes.add(node);
}
}
return filteredNodes;
}
public List<Node> bfs(Node n, String destinationNodeNumber, List<Node> path) {
visitedX.add(n); //visitedX is a global List to control visited nodes
path.add(n); //local path to be listed
List<Node> neighbors = getNodeNeighbors(n); //function to get node neighbors
if (n.next.equals(destinationNodeNumber)) {
allPaths.add(paths); //all paths to be listed
path.remove(n);
}
for (Node nNode: neighbors) {
if(!visitedX.contains(nNode)) {
bfs(nNode, destinationNodeNumber, path);
}
}
return null;
}
There are many flaws in your code:
Node
is misleading: Edge
would be a better name,getNodeNeighbors
only considers one direction of each edgeaCompany
and anotherCompany
? i assume you meant source
and next
?Contract
?destinationNodeNumber
is a String
; it should be an int
.visitedX
set prevents two paths from using a same edge; you just need to ensure that an edge doesn't appear more that once in a single path.path
to allPaths
; you should make a copy instead.Here is a class Edge
:
public class Edge {
final int source;
final int next;
Edge(int source, int next) {
this.source = source;
this.next = next;
}
@Override
public String toString() {
return "(" + source + "," + next + ')';
}
}
Then the class Graph
that contains the search algorithm:
public class Graph {
private final Iterable<Edge> allNodes;
public Graph(Iterable<Edge> allNodes) {
this.allNodes = allNodes;
}
public List<Edge> edgesFrom(int vertex) {
List<Edge> filteredNodes = new ArrayList<Edge>();
for (Edge node : allNodes) {
if (node.source == vertex || node.next == vertex) {
filteredNodes.add(node);
}
}
return filteredNodes;
}
public List<List<Edge>> allPaths(int source, int dest) {
List<Edge> path = new ArrayList<>();
List<List<Edge>> allPaths = new ArrayList<>();
for (Edge n: edgesFrom(source)) {
searchPaths(n, source, dest, path, allPaths);
}
return allPaths;
}
private void searchPaths(Edge n, int source, int dest, List<Edge> path,
List<List<Edge>> allPaths) {
path.add(n); //local path to be listed
int next = n.source == source ? n.next : n.source;
List<Edge> neighbors = edgesFrom(next); //function to get node neighbors
if (next == dest) {
allPaths.add(new ArrayList<>(path)); //all paths to be listed
}
for (Edge nNode : neighbors) {
if (!path.contains(nNode)) {
searchPaths(nNode, next, dest, path, allPaths);
}
}
path.remove(n);
}
}
And here is the example that uses these classes:
Graph graph = new Graph(Arrays.asList(
new Edge(1,2), new Edge(2,3), new Edge(3,4), new Edge(1,4)));
List<List<Edge>> allPaths = graph.allPaths(1,3);
for (List<Edge> path: allPaths) {
System.out.println(path);
}