0

I have a quite tricky task to solve:

You are given a N * M board (1 <= N, M <= 256). You can move from each field to it's neighbouring field (moving diagonally is not allowed). At the beginning, there are two types of fields: active and blocked. You can pass through active field, but you can't go on the blocked one. You have Q queries (1 <= Q <= 200). There are two types of queries:

1) find the next field (neighbouring to A) that lies on the shortest path from field A to B

2) change field A from active to blocked or conversly.

The first type query can be easily solved with simple BFS in O(N * M) time. We can represent active and blocked fields as 0 or 1, so the second query could be done in constant time.

The total time of that algorithm would be O(Q (number of queries) * N * M).

So what's the problem? I have a 1/60 second to solve all the queries. If we consider 1 second as 10^8 calculations, we are left with about 1,5 * 10^6 calculations. One BFS may take up to N * M * 4 time, which is about 2,5 * 10^5. So if Q is 200, the needed calculations may be up to 5 * 10^7, which is way too slow.

As far as I know, there is no better pathfinding algorithms than BFS in this case (well, I could go for an A*, but I'm not sure if it's much quicker than BFS, it's still worst-case O(|E|) - according to Wikipedia ). So there's not much to optimize in this area. However, I could change my graph in some way to reduce the amount of edges that the algorithm would have to process (I don't need to know the full shortest path, only the next move I should make, so the rest of the shortest path can be very simplified). I was thinking about some preprocessing - grouping vertices in a groups and making a graph of graphs, but I'm not sure how to handle the blocked fields in that way.

How can I optimize it better? Or is it even possible?

EDIT: The actual problem: I have some units on the board. I want to start moving them to the selected destination. Units can't share the same field, so one can block others' paths or open a new, better paths for them. There can be a lot of units, that's why I need a better optimization.

Maras
  • 972
  • 7
  • 15
  • 1
    A* will probably save you about 3/4 of nodes to examine. Give it a try and see what timings you get. However, such tasks are usually about clever pre-processing. – Nico Schertler Jul 06 '18 at 15:23
  • 1
    Jump point search is a further optimization on uniform cost grids and can give a ~10x speedup over A*: https://harablog.wordpress.com/2011/09/07/jump-point-search/ – c2huc2hu Jul 06 '18 at 16:50
  • Thanks, I'll check that out! – Maras Jul 06 '18 at 17:21

1 Answers1

0

If I understand the problem correctly, you want to find the shortest path on a grid from A to B, with the added ability that your path-finder can remove walls for an additional movement cost?

You can treat this as a directed graph problem, where you can move into any wall-node for a cost of 2, and into any normal node for a cost of 1. Then just use any directed-graph pathfinding algorithm such as Dijkstra's or A* (the usual heuristic, manhatten distance, will still work)

BlueRaja - Danny Pflughoeft
  • 75,675
  • 28
  • 177
  • 259
  • Well, not really. I want to be able to remove or add wall any time, plus have faster complexity than O(|E|) for a query (finding path, or at least, finding next move I should make to get closer to my destination). By "faster than O(|E|)" I mean that the time complexity should be smaller than O(|E|), where |E| is a number of edges in initial graph, in this case, number of fields * 4. – Maras Jul 06 '18 at 17:16
  • 1
    @Executor1909: I don't believe it's possible to do better than that in the worst case, but the term you're looking for is "incremental algorithms" (specifically [LPA\*](https://cstheory.stackexchange.com/questions/11855)), which are able to find the shortest path after adding/removing walls without recomputing the entire path from start to finish. However you still haven't explained what your **actual** problem is; there's likely a better way. – BlueRaja - Danny Pflughoeft Jul 06 '18 at 17:29