I'm making a robot maze in java in which the robot uses the depth-first search algorithm to traverse the maze and reach the target. This works fine in a maze with no loops, but when those are introduced the algorithm fails. Is there any way to make depth-first search work with loopy mazes? If so, how does one go about doing that?
I have two separate implementations of this maze - one records each junction and stores it in an array while the other one uses a stack to push a new junction and pop it off when it has finished exploring that junction. A solution using any one of these implementations is acceptable.
You need to mark visited nodes and treat them as "additional" walls.
That way, you can avoid searching loops. It will no longer find the shortest path though.
See Dijkstra's algorithm for details. For an even more advanced - directed - version, look at A* search. On difficult mazes, it shouldn't gain you a lot though. A* is more interesting for open areas.
Related
Consider a problem similar to this: Ice Sliding Puzzle Path Finding
Except that I wish to find the optimal shortest path algorithm. I've looked into it and found that BFS, A* and Djikstra's are all viable algorithms, but I need some advice on which would be best for my scenario or if there's a better choice.
My scenario being where an ice maze similar to the one in the stackoverflow question exists and is in a txt file. For the data structure holding the grid I thought to use a 2D char array since I thought it would perform best but maybe simplicity isn't the way to go here.But I'm clueless as to whether more fitting data structures exist
With that taken into account which of the three algorithms do you guys think would perform best on one of these mazes given that they'd be say max 2560x250 in size with varying complexities in the possible paths.
Concerns with BFS - non-optimal path storage approach, considers each tile moved a step so one path could be sliding along step by step while another is taking steps in different directions with shorter slides ( don't know the performance impact it will have)
Concerns with A* & Dijkstra's - Forming all possible nodes and edges with weights could be a heavy process
simple example maze txt (0 - wall, S - Start, F - Finish)
.0...00...
.0F0......
..0..0....
.0.0.....0
..........
..........
....0.0.0.
.0.0......
0........0
S.0.....00
I need some advise in an approach I may need to take to solve a gaming problem which is a puzzle (NxN), the puzzle consists of positive numbers and stored in a two dimensional array. For simplistic reasons is i´ll list a simple example
2 1 2 2
1 3 2 1
1 0 2 1
3 1 2 0
So the starting point is at (0,0) => 2 and the goal location is to (3,3) => 0
The number in the array location tells you how far to move. (0,0)=> 2 can move to either (0,2) or (2,0) and so on (moves allowed left, right, up, or down)
So you end up with a solution like this for example (0,2)=>(2,2)=>(2,0)=>(3,0)=>(3,3).
so my question is what sort of algorithm i should be looking into and whether any of you have done something similar to this?
You have plenty of solutions here:
A* algorithm
Dijkstra
Depth-first
Breadth-first
The first two will give you an optimal solution if one exists. A* is typically faster than Dijkstra if the heuristic is well chosen. Breadth- first will also give you an optimal implementation. Depth-first may give you non-optimal solutions in this problem.
The main difference between A* and Djisktra is that A* defines a heuristic, namely a function that tries to estimate if a move is better than another one.
The main difference between depth-first and breadth-first is the order in which they explore the space of solutions. Breadth-first will start by looking for all solutions of length 1 then all solutions of length 2, etc, while depth-first will fully explore an entire path until it either cannot go any further or finds a solution.
A* and Dijkstra are typically implemented in imperative style and are probably more sophisticated than the other two, especially A*. Breadth-first is also naturally expressed in imperative style. Depth-first is generally expressed recursively, which can be a problem if your solutions can exceed a length of several thousands moves (depending on the size of your stack, you will generally only be able to make 7-10k recursive calls before you get a StackOverflowError).
To sum up:
A* is generally the most efficient of the algorithms listed below
A* is the most difficult to implement
Dijkstra is a special case of A* with similar performance but potentially less efficient
Breadth-first is straightforward to implement and is resilient to long solutions
Depth-first is straightforward to implement but it is limited by the length of the longest possible path if it is implemented recursively
All these algorithms except depth-first guarantee an optimal solution
Code example:
I found this Scala implementation of A* in one of my repositories. Might help.
I have some grid search algorithms (Best-First, Breadth-First, Depth-First) implemented here in Object Pascal (Delphi), that you could easily adapt to Java if this was a classic grid search:
https://github.com/Zoomicon/GridSearchDemo/tree/master/Object%20Pascal/algorithms
You can try the GridSearchDemo application here to see how those algorithms behave when searching in a grid with start and target point and obstacles in various grid cells (you can set them):
https://github.com/Zoomicon/GridSearchDemo/releases
In general, I prefer the A* algorithm, which is an example of a Best-First algorithm (https://en.wikipedia.org/wiki/Best-first_search)
In your case, this is not a grid really, but a graph, since you seem to have jump links to other cells (or at least this is how you explain the number in your question, although you call it "how far" at first)
I have written a program in java to solve this problem. It uses A*-algorithm with heuristic functions Manhatten and hamming. It depends on the person whether he uses hamming or manhatten distance but Manhatten is better.
Here is my code in java: 8-puzzle
Btw it's not an easy approach and many problems can't be solved.
I've coded a depth first search from a graph using euler algorithm of getting a cycle and splice subcicles into the result.
The problem is, to very large data, it isn't fast enough to find the correct path, namely on the dfs worst case scenario.
I've ordered the adjacency list and start at a given point, to finish at the same starting point. My idea to improve was to make the search bidirectional but that adds alot of complexity dealing with the dead ends when I want to add order to the result.
My question is basically if there is some other way to get around the worst case scenario or how to properly deal with dead ends on bidirectional search so the result will stay numericly ordered?
Any input is welcome.
I have this project where I have to come up with Java source code implementing the Hamiltonian cycle.
I searched on google and at least now I know what a Hamiltonian cycle is, path that passes through all vertices just once except the starting vertex because it's also the last vertex (tell me if I'm wrong).
The problem is I don't know how to implement it. Basically, my questions are:
How, where do you implement a Hamiltonian cycle?
What is the application of a Hamiltonian Cycle (so that it helps to understand why it's so important)
You don't implement a Hamiltonian cycle, you find it (or find out that none exists for your given graph). Since this is an NP-complete problem, which means this is probably no efficient solution, I'd just implement a simple backtracking algorithm. Since you're looking for a cycle, it does not matter at which node you start.
Hamiltonian cycles can be used in cryptography for zero-knowledge proofs.
I'm not sure whether this is still just research or whether it's being actively used in any cryptographic protocol.
Is this homework? If so please tag it as such.
It is easy to implement it if you can use recursion (not the case if the graph gets too large). What you do is write a function that takes as argument the graph (there are different representations for this), the function checks whether the graph consists of only the starting-point, if so it returns, if it didnt return it calls itself recursively for each node N that is still in the graph and gives the graph minus the node N as arguments.
The simplest way is to start with one node, "tag it", choose the next reachable "untagged" node, "tag it", and continue until either:
you reach the starting node, thus you found Hamiltonian cycle. Repeat the cycle for every node to find each and every Hamiltonian cycle in that graph.
You cannot choose another "untagged" node, which means that there is no Hamiltonian cycle for that starting node (but you found a Hamiltonian Path, anyway).
That algorithm can be optimized in several ways, but I let you that to you. Any solution you find will be NP-complete.
As for they uses, I only saw them in Graph theory and AI classes (this is a particular travelsman problem, where each edge has a cost of 1) and they never told me real-life uses for that.
(B) Practical Application
Determining most efficient switching network for phone systems
Best bus routes, postal routes, meter checking routes
I'm doing an AI for 8 puzzle that develop on java. I have 1 class that keep the 2 dimension array of string that is a 8 puzzle board. This class also keep other necessary information. The question what is an appropriate tree that i will use to keep each object.
I can't see why you would want to use a tree.
If you're after solving an 8-puzzle in as few moves as possible, what you're after is actually finding the shortest path from the current configuration to the "solved" configuration in a graph where vertices are configurations and edges are moves.
The shortest path can be solved with for instance a breadth-first search.
I think this code explains it fairly well: http://www.dreamincode.net/code/snippet1914.htm
The (implicit) graph could mentally be pictured as a tree, but what is being depicted is more like the control flow of the algorithm.
You may want to consider using A* search for this. A good explanation of the algorithm can be found here.