How do you find the start and end of a recursive backtracking maze? - maze

How do you find the start and end of a maze generated with recursive backtracking?
It seems like it would be hard to figure it out, as the maze never ends. Would it be the point where you first start backtracking? The start point could be where you start, but sometimes there is a better spot.

When you generate a maze with recursive backtracking like this:
http://weblog.jamisbuck.org/2010/12/27/maze-generation-recursive-backtracking
then all the cells are connected, and there's exactly one way to travel between any two cells without retracing your steps.
You can pick any start and end points you like!
Note that a graph that is connected like the maze cells are, i.e., so that there is exactly one path from any vertex to any other vertex, is an undirected tree. If you want to find the two points that are furthest apart, so that you can use them as the start and end points, then you need to find the diameter of this tree.
There lots of ways to do that, but the simplest is:
1) Pick a random vertex to start at, and use BFS to find the/a vertex that is farthest from it. That will be your start point.
2) Use BFS to find the/a vertex that is farthest from the start vertex. That is your end point.
The start and end points will be as far apart as possible.
The answer to this question explains why that always works: Proof of correctness: Algorithm for diameter of a tree in graph theory
Note that the points that are furthest apart aren't necessarily on the edges. I find that picking random points on the edges works fine when that's what you need: https://mtimmerm.github.io/webStuff/maze.html

Related

Multiple Source Multiple Destination shortest path

Let's say we have a maze, which has a width of W and a height of H. In this maze there are multiple people and multiple towers. The people are the sources (S) and the towers (D) are the destinations. It should be known that we have an omniscient view of the maze. My question is then this:
If I want to find the shortest path between any of the different SD combinations, how do I go about this?
At first, I can think of a naive solution that involves breaking this down into SD different OSOD operations, the problem is that this is quite time-consuming.
The second option would be to break it down into S different OSMD operations. But this I suspect is still too time inefficient for what I'm looking for.
I need an algorithm that can perform the pathfinding in O(WH) time. I've not been able to find anything that gives me the shortest path in O(WH) time and which is MSMD based. Hopefully, someone can point me in the right direction.
Imagine a graph that includes the maze as well as start and end vertexes outside the maze, with an edge from the start vertex to every S, and an edge from every D to the end vertex.
Now breadth-first search (since there are no weights) to find the shortest path from the single start to the single end.
I say 'imagine' that graph, because you don't actually have to build it. This ends up being a simple breadth-first search with minor modifications -- you start with all the S nodes in the root level, and stop when you reach any D.

Dijkstra Algorithm with Chebyshev Distance

I have been using Dijkstra Algorithm to find the shortest path in the Graph API which is given by the Princeton University Algorithm Part 2, and I have figured out how to find the path with Chebyshev Distance.
Even though Chebyshev can move to any side of the node with the cost of only 1, there is no impact on the Total Cost, but according to the graph, the red circle, why does the path finding line moves zigzag without moving straight?
Will the same thing will repeat if I use A* Algorithm?
If you want to prioritize "straight lines" you should take the direction of previous step into account. One possible way is to create a graph G'(V', E') where V' consists of all neighbour pairs of vertices. For example, vertex v = (v_prev, v_cur) would define a vertex in the path where v_cur is the last vertex of the path and v_prev is the previous vertex. Then on "updating distances" step of the shortest path algorithm you could choose the best distance with the best (non-changing) direction.
Also we can add additional property to the distance equal to the number of changing a direction and find the minimal distance way with minimal number of direction changes.
It shouldn't be straight in particular, according to Dijkstra or A*, as you say it has no impact on the total cost. I'll assume, by the way, that you want to prevent useless zig-zagging in particular, and have no particular preference in general for a move that goes in the same direction as the previous move.
Dijkstra and A* do not have a built-in dislike for "weird paths", they only explicitly care about the cost, implicitly that means they also care about how you handle equal costs. There are a couple of things you can do about that:
Use tie-breaking to make them prefer straight moves whenever two nodes have equal cost (G or F, depending on whether you're doing Dijkstra or A*). This gives some trouble around obstacles because two choices that eventually lead to equal-length paths do not necessarily have the same F score, so they might not get tie-broken. It'll never give you a sub-optimal path though.
Slightly increase your diagonal cost, it doesn't have to be a whole lot, say 10 for straight and 11 for diagonal. This will just avoid any diagonal move that isn't a shortcut. But obviously: if that doesn't match the actual cost, you can now find sub-optimal paths. The bigger the cost difference, the more that will happen. In practice it's relatively rare, and paths have to be long enough (accumulating enough cost-difference that it becomes worth an entire extra move) before it happens.

How to search through different parts of a graph?

Recently I met a coding problem that asks you on a given graph to find out how many different "closed" sub-graphs there are. And after you have found that out you need to search each sub-graph and find how many element are there in each sub-graph. So now to define sub-graph. Let's say we're given
.#####.
#.....#
#.E##.#
#.#.#.#
#.#####
#E..#E#
.#####.
Think of it like a maze where dots represents moving space, while the hashtags are walls and you can move horizontally or vertically. So let's say you are at one point in the graph. All the points you can reach by moving horizontally or vertically are part of a that particular "closed" sub-graph. So for the given example we have 3 "closed" sub-graphs
1#####1
#11111#
#11##1#
#1#2#1#
#1#####
#111#3#
1#####3
Also there are 2 elements in the first sub-graph, no elements in the second and one in the 3rd.
I guess it really doesn't matter what searching method you use, so I used BFS starting from the first entered dot in the line. So once I've reach all possible points starting from that particular point I have found one sub-graph and I have counted how many elements there are in the sub-graph. But the problem now is how to find the starting point of the next sub-graph. I can not think of another way than iterating through the graph until you find a non-visited point and the apply the BFS repeateadly until you have visited all the points. But this method proves to be too much time-consuming, so is there any way I can efficiently find the sub-graphs? For example is there a way to stack at least a point from each sub-graph in a queue, while you're entering the line?
Instead of iterating through the entire graph to find non-visited points you could try iterating though just the walls adjacent to your known sub-groups and look for non-visited points adjacent to those walls. You would be able to compile the list of walls during the bfs.
You can first iterate the graph and find all possible "starting point", hold these elements in a set data structure, and when you do a BFS - for each point you find - remove it from the set of entry points.
Now, at each iteration - all you have to do is choose a random entry point from the set (which is guaranteed to be unvisited yet), and do a new BFS.

Algorithm for shortest path through all edges

Here's an interesting problem/riddle a friend asked me recently:
You are painting the lines of a tennis court. You have a machine to paint straight lines, but once it is turned on, you can't stop it until the job is done. Clearly you will need to go over some lines twice. What is the smallest amount of extra paint you have to use, in feet?
The dimensions of a court:
The sum of all lines is 480ft. I happen to know that the answer is 63ft extra (543ft total), but I can't help but wonder what the best algorithm is to solve this.
It seems similar to the traveling salesman problem, where each line on the court is represented by a vertex in a graph and junctions of court-lines translate to edges. (Otherwise, if lines were edges and corners were vertices, it would require a path that goes through all edges, and I don't know of any algorithms for that). Maybe you need to be more clever about how junctions of lines are represented and I have some ideas about that, but nothing has really worked yet.
I think the problem is small enough, though, that it can be brute-force-checked with all paths through the line graph. How would you code that?
An undirected graph has an Eulerian trail if and only if at most two vertices have odd degree, and if all of its vertices with nonzero degree belong to a single connected component. ( Found from http://en.wikipedia.org/wiki/Eulerian_path )
When we get a non-Eulerian graph, we can change it to an Eulerian by adding edges to the odd degree vertices.
So, this problem is turned to: find the lowest cost to turn the graph to a Eulerian.
The algorithm should be:
list all vertices with odd degree , suggest it is a list_vodd[];
find the shortest edge between the vertices in list_vodd[], get two vertices of the edge: pa, pb;
add an edge between pa,pb ( which means this edge should be paint twice );
delete pa,pb from list_vodd[];
goto 2 until there are only two vertices in list_vodd[].
use any existing algorithm to find out a Eulerian router in the new graph with the added edges.
I'm a little late to the game here, but I came across this when I was trying to find an algorithm to determine the shortest path to hike every trail in a state park. Here's a sketch that explains why the answer is 63
As Richard mentioned, this is a Chinese Postman problem. Since the problem didn't specify that we have to start and end in the same location we can use a semi-eulerian graph, which is why all the nodes have an even number, except the start and end points which share a common edge.
Here is a very nice video that explains how to graph and solve this type of problem.
https://www.youtube.com/watch?v=spaUY8PlyYA

Random walk for find the path with higher cost

I have a acyclic directed graph with a start vertice and an end vertice and some unknown number of vertices in between. A path starts from start vertice and end at end vertice. It is known that the number of vertices along the any paths between the start vertice and end vertice <100, but the number of possible vertices could be very large. Each vertice has a cost assigned to it, and the cost of the path is summation of the cost of vertices in between. Is there a way to use the random walk or any other means (this is to avoid explore all the vertices) to find for the path that has the highest (or near-highest) cost?
This problem is solved on Geekviewpoint.com with detailed explanation. It augments Dijkstra's algorithm. http://www.geekviewpoint.com/java/graph/dijkstra_constrained
EDIT: to account for 100 vertices between each path.
Originally your problem said there were 100 paths between the start and finish vertices. But by your correction, it's actually 100 vertices on the path. In that case your optimization is straightforward using DFS.
As you try to assemble a path, track the number of vertices you have seen. If the number reaches 99 and does not link start to finish, abort that path and try another one unit you get the answer if it exists. The algorithm you need to modify is DFS for cycle detection. Any algorithm textbook will have one of those. Since you also need to pick the best path among those found, you should also look at http://www.geekviewpoint.com/java/graph/count_paths.
I don't know if I should tell you how to do the obvious, but you will track the past path you have found similar to how you would find the maximum element in an array. The code is not difficult, you just have to combine a few small ideas:
DFS (similar to cycle detection and similar to counting paths, the two overlap)
track the best path you have seen: a one entry map where the idea is map which you keep replacing if you find a shorter path.

Resources