3

Suppose you have a dungeon, represented by a 2D matrix. You have a start point S (x1,y1) and an end point E (x2, y2). Along the way, some cells have a number in them, which subtract from your health score. Other cells are obstacles that you can't go through. You start with 5 health points, and you need to find the shortest path from S to E where you don't die on the way.

I know that Dijikstra is used to find shortest paths. But in this case the shortest path might be one in which you die along the way. How do you find the shortest path where you don't die? Note that there is no advantage to completing the race with more health points so long as you're alive at the end.

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
Ben G
  • 26,091
  • 34
  • 103
  • 170
  • @Mark_M This won't find the fastest path, because it'd treat solving the maze with 5 health as 4 paces faster than solving with 1 health, while the 1 health solution might be faster – Ben G May 13 '18 at 19:53

2 Answers2

2

The standard approach to problems like this is sometimes called 'graph layering'. You make 5 copies of the original graph (numbered 0 through 4 in this case), where getting to a vertext v in graph n means getting to the corresponding vertex in the original graph after suffering n deaths.

If an edge in the original graph costs you a life, then it connects a vertex in each graph i to a vertex in graph i+1, and otherwise it connects vertices in the same version of the graph just like the original.

After constructing this graph, use Dijkstra's algorithm to find the shortest path to the terminal vertex in any layer.

Matt Timmermans
  • 53,709
  • 3
  • 46
  • 87
  • Seems very space intensive. if k=1000 instead of 5 you have a huge number of copies of the graph. – Ben G May 14 '18 at 01:42
  • 1
    Yes. In practice you don't actually need to copy the graph, but you remember (vertex,layer) in every state except just the vertex. Even so, the worst-case space and time required by Dijkstra's algorithm is multiplied by k. That's why these problems are always given with small numbers :) – Matt Timmermans May 14 '18 at 04:22
0

Just use A*, moreover decrease health every move accordingly, but consider every move that would cause health to reach 0, as if that case were an obstacle case.

Edit: for OP convenience, I will enclose a link to articles about A*: this and this and this

Explainatory Note: It might be tricky to see, A* tries greedy first, but then backtraces and will eventually find the shortest possible route. Here I am not suggesting that a case is forever labelled as an obstacle, but merely locally considered equivalent to obstacle for the current selection if it causes a death. After finding the first path, this extended A* should not stop, but use the length of this path as upper bound and backtrace, in a decisional tree, checking all open paths. It will work.

Attersson
  • 4,755
  • 1
  • 15
  • 29
  • This does not work! You can end up in a dead end even if you reject moves that make you run out of health at a given point – Ben G May 13 '18 at 19:43
  • 1
    Why not? You will take a different path in the decisional tree, until you find a possible and the best among possibles. Do you know A* ? I did NOT say Dijikstra . – Attersson May 13 '18 at 19:44
  • 1
    Since when does a properly implemented A* search terminate without a solution when one is possible? – Thomas M. DuBuisson May 13 '18 at 19:46
  • @ThomasM.DuBuisson Thanks Thomas. I appreciate your understanding. – Attersson May 13 '18 at 19:49
  • Maybe I'm misunderstanding A*. I thought that A* was basically djikstra but without regarding moves that would make you run out of health as neighbors. So I presumed it could reach a dead end if something seemed workable earlier on but lowers health too much later to work – Ben G May 13 '18 at 19:53
  • 1
    No problem then. Glad to help – Attersson May 13 '18 at 20:06
  • Please elaborate? – Attersson May 13 '18 at 22:21
  • Lets say that every path to the destination goes through vertex X. The shortest path to X costs 1 life, but there is a death-free path that is just a little bit longer. A* will find the one-death path. The if the best 3-death path from X path to the destination is much longer than the best 4-death path, then you will fail to choose the best path (that incorporates the 4-death path from X to destination), because your algorithm won't reconsider the path to X. – Matt Timmermans May 13 '18 at 22:28
  • @MattTimmermans You are confusing it with Dijikstra. A* will consider ALL paths.So it will succeed. – Attersson May 13 '18 at 22:31
  • No, I am not, and no it won't – Matt Timmermans May 13 '18 at 22:31
  • 1
    I guess something on how I mean to establish the heuristic, which is an extension of the A* really, was not really clear in the answer. It is possible to be done though and will evaluate paths not to miss any. It will backtrace – Attersson May 13 '18 at 22:35