Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Day15b runtime can be improved by bucket queue #8

Open
JLHwung opened this issue Dec 17, 2021 · 6 comments
Open

Day15b runtime can be improved by bucket queue #8

JLHwung opened this issue Dec 17, 2021 · 6 comments
Labels
enhancement New feature or request

Comments

@JLHwung
Copy link

JLHwung commented Dec 17, 2021

The pathfinding library implements classic dijkstra's algorithm by a BinaryHeap.

It can be further improved, some of my thoughts are:

  1. We can use a bucket queue because all weights are small integer, so the cost must be an integer between (0, 9 * V), where V is the number of vertex.
  2. We can pre-compute a tighter cost upper bound than 9 * V thanks to the graph setup. Generally we don't know the path from start to end without traversing. However in the aoc setup, we do know a path from start to end: so we can sum up the risk from (0, 0) -- (W - 1, 0) -- (W - 1, H - 1) and use that as the bucket size.

I implemented the bucket queue dijkstra and it's around 20% faster than the binary heap approach on day15b setup.

@timvisee
Copy link
Owner

Fantastic suggestion. Thanks so much for sharing this.

I wasn't aware of the bucket queue structure.

I'd like to focus on the other days first. I'll likely try to implement this afterwards. Feel free to PR in the mean time.

@timvisee timvisee added the enhancement New feature or request label Dec 17, 2021
@benschneider
Copy link

Nice one solution! I can actually also recommend using the astar method (from the same library), got a 2x speedup over Dijkstra. (finds the same path) ;)
Had fun testing this over much larger maps.

@timvisee
Copy link
Owner

Interesting. I got slightly slower times while using A*. I actually started with A*, but switched to Dijkstra due to better timings.

I wonder what may have caused this. Maybe my implementation was broken. But it could also be hardware configuration related.

@benschneider
Copy link

hmm, could it be due to distance calculations?

@timvisee
Copy link
Owner

Possibly. What did you use?

@benschneider
Copy link

fn distance(&self, other: &Pos) -> i32 {
        let square_dist = (self.0 - other.0).abs().pow(2) + (self.1 - other.1).abs().pow(2);
        (square_dist as f64).sqrt() as i32
    }

But I wonder if it would be possible to profile the timing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants