Finding all hamiltonian cycles - java

I'm trying to implement a method for adding all possible Hamiltonian cycles to a list using recursion. So far my stopping condition isn't sufficient and I get "OutOfMemoryError: Java heap space" in the line that adds a vertex to a list:
private boolean getHamiltonianCycles(int first, int v, int[] parent,
boolean[] isVisited, List<List<Integer>> cycles) {
isVisited[v] = true;
if (allVisited(isVisited) && neighbors.get(v).contains(new Integer(first))) {
ArrayList<Integer> cycle = new ArrayList<>();
int vertex = v;
while (vertex != -1) {
cycle.add(vertex);
vertex = parent[vertex];
}
cycles.add(cycle);
return true;
} else if (allVisited(isVisited)) {
isVisited[v] = false;
return false;
}
boolean cycleExists = false;
for (int i = 0; i < neighbors.get(v).size(); i++) {
int u = neighbors.get(v).get(i);
parent[u] = v;
if (!isVisited[u]
&& getHamiltonianCycles(first, u, parent, isVisited, cycles)) {
cycleExists = true;
}
}
//if (!cycleExists) {
isVisited[v] = false; // Backtrack
//}
return cycleExists;
}
Can someone please suggest me what I'm doing wrong or is my approach completely incorrect?
EDIT:
As suggested in comments, the culprit was the parent array, causing an infinite loop. I wasn't able to correct it and I changed the array to store the child element. Now everything seems to work:
private boolean getHamiltonianCycles(int first, int v, int[] next,
boolean[] isVisited, List<List<Integer>> cycles) {
isVisited[v] = true;
if (allVisited(isVisited) && neighbors.get(v).contains(first)) {
ArrayList<Integer> cycle = new ArrayList<>();
int vertex = first;
while (vertex != -1) {
cycle.add(vertex);
vertex = next[vertex];
}
cycles.add(cycle);
isVisited[v] = false;
return true;
}
boolean cycleExists = false;
for (int u : neighbors.get(v)) {
next[v] = u;
if (!isVisited[u]
&& getHamiltonianCycles(first, u, next, isVisited, cycles)) {
cycleExists = true;
}
}
next[v] = -1;
isVisited[v] = false; // Backtrack
return cycleExists;
}

If you is looking for Disjoint Hamiltonian Cycles here have an implementation using Backtracking.

Related

I am trying to do BFS search but get Runtime Error Index out Of Bounds Exception

Given a directed graph, the task is to do Breadth First Traversal of this graph starting from 0.
Complete the Function bfsOfGraph() to return Breadth First Traversal of given graph.
Here, V denotes the number of vertices.
Here's the problem link
class Solution
{
public ArrayList<Integer> bfsOfGraph(int V , ArrayList<ArrayList<Integer>> adj)
{
ArrayList<Integer> bfs = new ArrayList<>();
boolean vis[] = new boolean[V+1];
for( int i = 1; i < V+1 ; i++){
if(vis[i] == false){
Queue<Integer> q = new LinkedList<>();
q.add(i);
vis[i] = true;
while(!q.isEmpty()){
Integer node = q.poll();
bfs.add(node);
for(Integer it : adj.get(node)){
if(vis[it] == false){
vis[it] = true;
q.add(it);
}
}
}
}
}
return bfs;
}
}
When you know you have started (origin of the graph) from 0 then why are calling on each node (vertex) of the graph. I think you misunderstood the questions. You have to apply BFS on the Origin 0. You Might get the IndexOutOfBound Exception as well because all the vertex of the graphs is from 0 to V-1 inclusive. I can see you are treating the graph vertex as 1 to V inclusive.
public ArrayList<Integer> bfsOfGraph(int V,ArrayList<ArrayList<Integer>> adj)
{
Queue<Integer> queue = new LinkedList<>();
boolean visited[] = new boolean[V];
ArrayList<Integer> results = new ArrayList<>();
queue.add(0);
while(!queue.isEmpty()){
Integer nextNode = queue.poll();
results.add(nextNode);
visited[nextNode] = true;
if(adj.get(nextNode) != null){
for(int neighbor : adj.get(nextNode)){
if(!visited[neighbor]){
queue.add(neighbor);
visited[neighbor] = true;
}
}
}
}
return results;
}

Java - A* algorithm ends without expanding any nodes

I have an assignment to create an A* algorithm through a road graph of the UK through a given template (all files for this assignment I have uploaded here
I think, however, that the problem is somewhere in my Planner.java file - the A* algorithm is not finding a node to expand, it just abruptly stops without expanding any nodes at all.
Here is the code for the Planner :
public class Planner implements PlannerInterface<Object> {
// declaration and instantination of our open and closed lists
private final OpenList openList = new OpenList();
private final ArrayList<SearchThroughNodes> closedList;
public boolean empty() {
int lengthOfItem = 0;
return (lengthOfItem == 0);
}
// constructor of closed list
public Planner() {
this.closedList = new ArrayList<>();
}
#Override
public List<GraphEdge> plan(RoadGraph graph, GraphNode origin, GraphNode destination) {
// Temporary costs and other data needed
SearchThroughNodes currentNode, temp1, temp2;
temp2 = new SearchThroughNodes(null, 0, 0, null);
GraphNode temp;
double temporaryCost, heuristics;
ArrayList<GraphEdge> finalResult;
finalResult = new ArrayList<>();
// check if origin and destination exist a.k.a are not set to null
boolean originExistence;
boolean destinationExistence;
destinationExistence = false;
originExistence = false;
if (origin != null && destination != null) {
originExistence = true;
destinationExistence = true;
}
// Pre-requisites for our A-Star to work
if (originExistence == true && !destination.equals(origin) && destinationExistence == true ) {
openList.add(new SearchThroughNodes(origin, 0, Utils.distanceInKM(origin, destination) / 120, null));
} else {
return null;
}
// A-star loop
while (!openList.empty()) {
// Get BEST node to expand
currentNode = (SearchThroughNodes) openList.get();
if (closedList.contains(currentNode)) {
continue;
}
// We reached the destination
// go back through nodes and read path
GraphNode checkCurrNode;
checkCurrNode = currentNode.getGraphNode();
if (destination.equals(checkCurrNode)) {
temp1 = currentNode;
temp2 = (SearchThroughNodes) currentNode.getPrecedingItem();
while (!temp2.getGraphNode().equals(origin)) {
finalResult.add(0, graph.getEdge(temp2.getGraphNode().getId(), temp1.getGraphNode().getId()) );
temp1 = temp2;
temp2 = (SearchThroughNodes) temp2.getPrecedingItem();
}
finalResult.add(0, graph.getEdge(temp2.getGraphNode().getId(), temp1.getGraphNode().getId()));
return finalResult;
}
closedList.add(currentNode);
long currentNodeId = currentNode.getGraphNode().getId();
List<GraphEdge> outEdges = graph.getNodeOutcomingEdges(currentNodeId);
//if expandable
if (outEdges != null) {
// traverse all nodes after currentNode
for (GraphEdge edge : graph.getNodeOutcomingEdges(currentNodeId)) {
long getFromEdge;
getFromEdge = edge.getToNodeId();
//Look at node at the end of the current edge
temp = graph.getNodeByNodeId(getFromEdge);
//store nodeID in tmp2 for traversal of openList
long tmp2GetID;
tmp2GetID = temp.getId();
temp2.setNodeID(tmp2GetID);
// set current edge length in kms,edge max allowed speed and current node cost to variables
// to later compute the temporary cost
double edgeLengthInKMs = edge.getLengthInMetres() / 1000;
double edgeMaxAllowSpeed = edge.getAllowedMaxSpeedInKmph();
double currCost = currentNode.getCost();
//new heuristics and cost
temporaryCost = currCost + edgeLengthInKMs / edgeMaxAllowSpeed;
heuristics = Utils.distanceInKM(temp, destination) / 120;
// Proceed here if node wasn't expanded
if (!closedList.contains(temp2)) {
// if node isn't contained currently in closedList
// if not,check and update accordingly
if (!openList.contains(temp2)) {
openList.add(new SearchThroughNodes(temp,
temporaryCost, heuristics, currentNode));
} else {
temp1 = openList.getNode(temp2);
double tempOneCost = temp1.getCost();
if (tempOneCost > temporaryCost) {
temp1.update(temporaryCost, currentNode);
}
openList.insert(temp1);
}
}
}
}
}
return null;
}
#Override
public AbstractOpenList<Object> getOpenList() {
return openList;
}
}

Recursively finding a path on a 2d array [Java]

I want to write a programm in java that finds a path on a 2d Array with recursion.
The 2d Array named "gitter" consists of Objects of the type 'field'.
Every field will be initialized with a random number in the range of 100-999. If a field was initialized with a number, in which one of the digits is a prime, it is a "trap". The fields can be imagined as squares, so i can move only in 4 directions:
public class Field {
int number;
boolean visited;
Field() {
Random rn = new Random();
this.number = rn.nextInt((999+1) - 100) + 100;
this.visited = false;
}
boolean isTrap() {
String str = String.valueOf(number);
if(str.contains("2") | str.contains("3") | str.contains("5") | str.contains("7")) {
return true;
} return false;
}
}
The start-field and the end-field of the path shall have a manhattan-distance of more than 2. The problem so far is the recursion. The more i think about it, the if cases in it are just getting longer and longer. I added also a boolean variable "visited", for not visiting the same field twice, but no success. Is the while-loop necessary for the recursion? If not (what i guess), what is the easiest way to make the recursion stop, after i found a path? i tried it with and without a while-loop, but couldn't find any solution.
public class Gitter {
Field[][] gitter = new Field[10][10];
List<Field> path = new ArrayList<Field>();
public Field[] getStartAndGoal() {
boolean notFound = true;
Field[] startGoal = new Field[2];
while(notFound) {
Random x0 = new Random();
Random y0 = new Random();
Random x1 = new Random();
Random y1 = new Random();
int row0 = x0.nextInt((9)+1);
int line0 = y0.nextInt((9)+1);
int row1 = x1.nextInt((9)+1);
int line1 = y1.nextInt((9)+1);
int distance = Math.abs(row1-row0) + Math.abs(line1-line0);
if(distance>2){
if(gitter[row0][line0].isTrap() == false && gitter[row1][line1].isTrap() ==false) {
notFound = false;
Field start = gitter[row0][line0];
Field goal = gitter[row1][line1];
startGoal[0] = start;
startGoal[1] = goal;
}
}
}
return startGoal;
}
public boolean findPath(Field start, Field goal) {
boolean solved = false;
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
if(gitter[i][j].equals(start)) {
gitter[i][j].visited=true;
while(solved==false){
if((i+1)<10 && gitter[i+1][j].isTrap()==false && gitter[i+1][j].visited == false && findPath(gitter[i+1][j], goal)){
gitter[i+1][j].visited = true;
path.add(gitter[i+1][j]);
return true;
}
if((i-1)>0 && gitter[i-1][j].isTrap()==false && gitter[i-1][j].visited == false && findPath(gitter[i-1][j], goal)){
gitter[i-1][j].visited = true;
path.add(gitter[i-1][j]);
return true;
}
if((j+1)<10 && gitter[i][j+1].isTrap()==false && gitter[i][j+1].visited == false && findPath(gitter[i][j+1], goal)){
gitter[i][j+1].visited = true;
path.add(gitter[i][j+1]);
return true;
}
if((j-1)>10 && gitter[i][j-1].isTrap()==false && gitter[i][j-1].visited == false && findPath(gitter[i][j-1], goal)){
gitter[i][j-1].visited = true;
path.add(gitter[i][j-1]);
return true;
}
for(i=0; i<path.size(); i++) {
if(path.get(i).equals(goal)){
solved = true;
break;
}
}
}
}
}
} return false;
}
Does anybody got a hint for me?
Looking at the problem, there are many variables that aren't necessarily too important to consider yet would allow me to create a simple solution quicker. If you use concepts from my solution, just take notes that there are a variety of restraints completely ignored which can easily be implemented.
Recursion
Typically recursion is used to replace the iterative behaviour of loops. With this problem you want to search every possible path if there exists a path that can take you from point A to point B, or up until you have determined there exists a path.
The more i think about it, the if cases in it are just getting longer and longer
Easy. Create a helper method that does the calculation for you so that you avoid repetitive use of the same code.
Is the while-loop necessary for the recursion?
I'm not entirely sure what you're doing with your loops, but it would definitely be possible (and much more elegant) to do away with loops altogether for this solution.
what is the easiest way to make the recursion stop, after i found a path?
Once you have found a solution, return true. The previous recursive step will receive a true value and then understand that somewhere along the line you have reached the end so it too should return true. This is where the recursive aspect can produce such an elegant solution.
Solution
public static void main (String args[]) {
int n = 10;
int[][] map = new int[n][n]; // Generate random data however you want
boolean[][] visited = new boolean[n][n]; // Defaults to false
int[2] start = new int[]{0,0}; // Top left corner
int[2] end = new int[]{n-1, n-1}; // Bottom right corner
boolean path = pathExists(map, visited, start, end);
}
public static boolean pathExists(int[][] map, boolean[][] visited, int[] current, int[] end) {
int x = current[0];
int y = current[1];
// If not in bounds, not a valid route
if (!inBounds(map, visited, current)) return false;
// If this is the end, return true!
if (current[0] == end[0] && current[1] == end[1]) return true;
// Attempt each cardinal direction. If you find a return, return true
if (pathExists(map, markPresent(visited, current), new int[]{x-1,y}, end)) return true;
if (pathExists(map, markPresent(visited, current), new int[]{x+1,y}, end)) return true;
if (pathExists(map, markPresent(visited, current), new int[]{x,y+1}, end)) return true;
if (pathExists(map, markPresent(visited, current), new int[]{x,y-1}, end)) return true;
// There is no solution down this path
return false;
}
public static boolean[][] markPresent(boolean[][] visited, int[] current) {
// Make a deep copy - Is needed to prevent interferance
boolean[][] copy = new boolean[visited.length][visited[0].length];
for (int i = 0; i < copy.length; i++)
copy[i] = Arrays.copyOf(visited[i], visited[i].length);
// Mark where you currently are
copy[current[0]][current[1]] = true;
return copy;
}
public static boolean inBounds(int[][] map, boolean[][] visited, int[] position) {
int x = position[0];
int y = position[1];
// Make sure it is within the bounds of the map
if (x < 0 || y < 0 || x >= map.length || y >= map.length) return false;
// Check if the current block is a barrier
if (isBarrier(map, position)) return false;
// If you have visited this path before, don't do it again
if (visited[x][y]) return false;
// Otherwise, check the path!
return true;
}
public static boolean isBarrier(int[][] map, int[] position) {
// Return your definition of a barrier (I used modulo 10 for testing
}
I've done minimal testing, so if you can see any glearing issues feel free to leave a comment.
From what I can gather, you are wanting to detect whether a path exists between to points. If you are wanting to detect the shortest distance (using the Manhatten metric), instance of returning boolean values you could return integer value. If you want to find the path itself, you can return an array of points and recursively append all points to another array. Here's a modified version that finds the shortest path:
public static ArrayList<int[]> findDistance(int[][] map, boolean[][] visited, int[] current, int[] end) {
int x = current[0];
int y = current[1];
ArrayList<int[]> ret = new ArrayList<>();
ret.add(current);
if (!inBounds(map, visited, current)) return new ArrayList<>(); // Return empty array
if (current[0] == end[0] && current[1] == end[1]) return ret; // Return current location
ArrayList<ArrayList<int[]>> paths = new ArrayList<>();
paths.add(findDistance(map, markPresent(visited, current), new int[]{x-1,y}, end));
paths.add(findDistance(map, markPresent(visited, current), new int[]{x+1,y}, end));
paths.add(findDistance(map, markPresent(visited, current), new int[]{x,y+1}, end));
paths.add(findDistance(map, markPresent(visited, current), new int[]{x,y-1}, end));
// Find the shortest path that leads somewhere
paths.removeIf((ArrayList<int[]> data) -> data.size() == 0);
paths.sort(Comparator.comparing(ArrayList::size));
// If the size of the paths is 0, no path was found
if (paths.size() == 0) {
return new ArrayList<>();
} else {
//Append the found path to the current location and return the list
ret.addAll(paths.get(0));
return ret;
}
}
EDIT
I had a terrible feeling I had forgotten something obvious - I had. You will need to clone the visited array so that you don't interfere with each recursive step. I've added a method to do that.
Adding some extra things to make things easier:
start and goal are attributes of Gitter class
findPath has been divided in tho methods, one public and another private
Code
public class Gitter {
Field[][] gitter = new Field[10][10];
List<Field> path = new ArrayList<Field>();
private Field start = null;
private Field goal = null;
// i've omited initializing too
public boolean findPath(Field start, Field goal) {
this.start = start;
this.goal = goal;
// Instead of having one recursive method, I divided it in two, one public and another private
for(int i = 0; i < 10; i++) {
for(int j = 0; j < 10; j++) {
if(gitter[i][j].equals(start)) {
return findPath(i,j);
}
}
} return false;
}
/*
* Check if available path exist from Field [i][j]
*/
private boolean findPath(int i, int j){
boolean solved = false;
// This check makes if-else chain cleaner
if(i < 0 || i >= 10 || j < 0 || j >= 10){
return false;
}
// Don't check already visited cells
if(!gitter[i][j].visited){
gitter[i][j].visited=true;
// If its possible to have a trap in goal Field, this check must be first
if(gitter[i][j].equals(goal)){
path.add(gitter[i][j]);
return true;
}
// If start Field mustn't be a trap, first condition should be removed
if(!gitter[i][j].equals(start) && gitter[i][j].isTrap()){
return false;
}
// Down
if(findPath(i+1,j)){
solved = true;
}
// Up
else if(findPath(i-1,j)){
solved = true;
}
// Right
else if(findPath(i,j+1)){
solved = true;
}
// Left
else if(findPath(i,j-1)){
solved = true;
}
// If any direction check found a path, this cell is part of that path
if(solved){
path.add(gitter[i][j]);
}
return solved;
}
return false;
}
}
I've tried with small numbers (from 1 to 9) and it should work
This one can not be a perfect nor efficient solution, but I've tried to make code easier to read and understand. I think with this kind of recursive problems that's a point to be highly considered.

How to store each node in a binary search tree in a list?

I am trying to write a function in a binary search tree class that will return the number of nodes in the tree that have values greater than n in the form public int greater (int n). I figured it might be easier to store all the values in a list and then iterate over the list and increment count each time a number is found to be greater than n. How would I go about implementing this?
This is my class so far:
public class BST
{ private BTNode<Integer> root;
private int count = 0;
List<Integer> arr = new ArrayList<>();
private BST right = new BST();
private BST left = new BST();
public BST()
{ root = null;
}
public boolean find(Integer i)
{ BTNode<Integer> n = root;
boolean found = false;
while (n!=null && !found)
{ int comp = i.compareTo(n.data);
if (comp==0)
found = true;
else if (comp<0)
n = n.left;
else
n = n.right;
}
return found;
}
public boolean insert(Integer i)
{ BTNode<Integer> parent = root, child = root;
boolean goneLeft = false;
while (child!=null && i.compareTo(child.data)!=0)
{ parent = child;
if (i.compareTo(child.data)<0)
{ child = child.left;
goneLeft = true;
}
else
{ child = child.right;
goneLeft = false;
}
}
if (child!=null)
return false; // number already present
else
{ BTNode<Integer> leaf = new BTNode<Integer>(i);
if (parent==null) // tree was empty
root = leaf;
else if (goneLeft)
parent.left = leaf;
else
parent.right = leaf;
return true;
}
}
public int greater(int n){ //TODO
return 0;
}
}
class BTNode<T>
{ T data;
BTNode<T> left, right;
BTNode(T o)
{ data = o; left = right = null;
}
}
I would not use a list as temporary storage.
There is a concept called Tree Traversal allowing you to visit each node of your tree.
Here is some pseudo code:
preorder(node)
if (node = null)
return
visit(node)
preorder(node.left)
preorder(node.right)
The visit function here is executed exactly once at each node.
For a specialized traversal like the counting you described, you could just replace visit with the functionality you want, like:
if (node.data > n) {
count += 1
}
Even better would be if you implement a Preorder class which you can extend to provide it with a custom visit function.

cycle detection in undirected graph using disjointsets?

I am implementing the code for cycle detection in undirected graph using find/union methods of disjointsets.
Here is the implementation:
public boolean isCyclicundirected(){
int k;
ArrayDisjointSet set = new ArrayDisjointSet(5);
//Set<Vertex> parents = new HashSet<Vertex>();
System.out.println(vertexMap);
Set<String> allVertices = vertexMap.keySet();
for (String v : allVertices){
Iterator<Edge> e = vertexMap.get(v).adj.iterator();
while (e.hasNext()){
int i = Integer.parseInt(vertexMap.get(v).name);
int j = Integer.parseInt(e.next().target.name);
if (set.isConnected(i, j))
return true;
else
k = set.join(i, j);
System.out.println(set);
}
}
return false;
}
and here is the isConnected of disjoinset
public boolean isConnected(int i, int j){
return find(i)==find(j);
}
if two nodes have the same root, (returned by find), that indicates there is a cycle.
For a graph like this which has no cycles (1,2),(2,3),(3,4), my method returns true.
I am failing to understand what is wrong.
EDIT latest: After suggestions below:
public boolean isCyclicundirected() {
int k;
HashSet<HashSet<Vertex>> vertexpairs = new HashSet<HashSet<Vertex>>();
ArrayDisjointSet set = new ArrayDisjointSet(100);
Set<String> allVertices = vertexMap.keySet();
for (String v : allVertices) {
Vertex current = vertexMap.get(v);
for (Edge e : current.adj){
Vertex nextVertex = e.target;
HashSet<Vertex> temp = new HashSet<Vertex>();
temp.add(nextVertex);
temp.add(current);
if (!vertexpairs.contains(temp)) {
vertexpairs.add(temp);
int i = Integer.parseInt(current.name);
int j = Integer.parseInt(nextVertex.name);
if (set.isConnected(i, j))
return true;
else
k = set.join(i, j);
System.out.println(set);
}
}
}
return false;
}
I get node:java.util.NoSuchElementException
You iterate over each edge twice, once from each side. You need to only consider any edge once.

Categories