13

I have a grid with a start, finish, and some walls. Units take the shortest path (moving only up/down/left/right) from the start to the finish, without passing through walls.

shortest path

The user is allowed to add as many extra walls as they want to change the path.

adding walls

However, notice that no matter how many walls are added or where they're added, there are some squares that can never be part of the shortest path!

These squares can never be part of the shortest path!
These squares can never be part of the shortest path!

I'm looking for a way to detect which squares can never be part of the shortest path.


The above cases are easy enough to find; but there are more complex cases. Consider:

None of the squares with red-dots can ever be part of the best-path

In the above image, none of the squares with red dots can ever be part of the best path, because there's only one entrance to that area, and it's only two spaces wide. If it were three spaces wide, or if any one of the walls were removed, most of those squares could potentially be part of the best path.

I've been trying to figure out a way to detect cases like the above (mostly using min-cuts and flood-fills), but without success. Does anyone know of a way to solve this problem?

BlueRaja - Danny Pflughoeft
  • 84,206
  • 33
  • 197
  • 283
  • 1
    One common feature that both your examples share is having a [clique separator](http://en.wikipedia.org/wiki/Vertex_separator) of size 1 or 2. Can you think of an example where this is not the case ? – krjampani Sep 13 '12 at 22:27
  • 1
    @jkraju, I haven't thought of an example where dead cells (ie cells that cannot be part of any shortest path) don't have separators of size 1 or 2; but it *is* easy to think of examples with separators of size 2 for not-dead cells. – James Waldby - jwpat7 Sep 13 '12 at 23:47
  • @jwpat7 I was only considering separators that keep s and f in the same component. Perhaps you were thinking of 2-clique separators that separate s from f ? I agree that it is easy to construct such an example. – krjampani Sep 14 '12 at 01:13

2 Answers2

4

Consider any path from S to F. That path could be a shortest path (if you delete every other square) unless you can take "shortcuts" using only those tiles. This only happens when you have two adjacent squares that aren't adjacent in the path. So you need to consider all pairs of adjacent squares; anything they disconnect from S or F (without disconnecting S from F) can't be part of a shortest path. Also, tiles that can be disconnected by a single square can't be part of any path (that doesn't repeat vertices) from S to F, so they need to go too.

Let N be the number of squares in the grid. For any particular pair of squares (there are O(N) of them), what gets disconnected can be computed in O(N) time with a floodfill, so this is O(N^2). Which is cheaper than min-cut, which you mentioned trying, so I assume its cheap enough for you.

Jonathan Paulson
  • 1,048
  • 6
  • 15
  • 1
    Dang, I was so close to this solution *(see @Topro's answer)*! I like both answers, but I chose this one because of the convincing proof that there are no other cases to consider. Thank you both - I've now implemented this, and it works great! – BlueRaja - Danny Pflughoeft Sep 14 '12 at 10:35
  • nice way of explaining it. My answer is basically the same technique but attempts to do it in O(N) - however implementation would be much tougher. – Rusty Rob Sep 15 '12 at 05:21
1

first we see that, the areas can be blocked by one or two adjacent grids will never be in any shortest path.

see the case in your example, it's those two yellow grids who make the dots blocked.

enter image description here

blocked by one grid is easy to understand. When blocked by two:

  1. if not adjacent, we may add extra walls to make it the only path, go in through one and go out from the other one, so we may need the inside ones.
  2. if adjacent, we can always go from one directly to the other, so we still don't need the grids inside that area.

So here's comes the algorithm:

enumerate each empty grid

  1. put a wall on it and use flood-fill to find the blocked areas, they are of no use.
  2. try put a wall on one of it's four adjacent grid(if empty), use flood-fill to find the blocked areas, they are of no use.
iloahz
  • 4,491
  • 8
  • 23
  • 31
  • Hmm, I think you are right with this *(with the caveat that we need to flood individual squares also, to find squares that start out unreachable. Also, you only need to check two neighbors, not four)*. I was confusing myself this whole time because the yellow squares in your image can be part of the best path, but I just realized that after we flood-fill, we don't consider the two squares we placed walls in as part of that unreachable area. Do'h! – BlueRaja - Danny Pflughoeft Sep 14 '12 at 10:36