8000 Use a hash set for the closed state list by btdubs · Pull Request #29 · justinhj/astar-algorithm-cpp · GitHub
[go: up one dir, main page]

Skip to content

Use a hash set for the closed state list#29

Closed
btdubs wants to merge 7 commits intojustinhj:masterfrom
Greenzie:btdubs/closed-set
Closed

Use a hash set for the closed state list#29
btdubs wants to merge 7 commits intojustinhj:masterfrom
Greenzie:btdubs/closed-set

Conversation

@btdubs
Copy link
Contributor
@btdubs btdubs commented Mar 23, 2023

The A* library uses a closed list which is slow to look up if a state has been visited. I've changed to a hash set via the unordered_set which speeds up search.
In my use case, this took the mean search time from 0.0141 seconds to 0.0016 seconds and the max search time from ~2.8 seconds to ~0.34 seconds.

I updated the examples to also use the hash. If there is a better way to handle the hash function let me know. I had trouble using the hash template specialization with the other templating in the library, and this way became easier.

@justinhj
Copy link
Owner

Thanks for the PR, will need some time to review it and let you know

@justinhj
Copy link
Owner

Hi @btdubs thanks again for the PR. I reviewed it today. I have a couple of reservations:

  1. It requires users of the library to add a hash function for their state
  2. We need to restrict the users to use c++11 or later since auto, hash and unordered_set are new since c++98/03

However I think it's a valuable change because it's faster. I have also been considering moving to a more recent c++ standard and c++11 provides lambdas, auto, range iteration and various smart pointers that would improve the current code somewhat.

I think the best solution for my users would be something like this:

  1. Cut a release of the current branch and share the tag in the documentation so that if users cannot upgrade to C++11 (although I think this is quite a small number of users by now), they can revert to that release
  2. Create a new release with your changes and the build files updated to specify c++11 is required
  3. Make the use of the unordered_set optional. If the user does not want to provide a hash function we can fallback to a simple list with some performance loss

I think it would be okay to provide a preprocess flag so that the use of the set instead of the list is opt-in and zero cost if you do not use it.

I think the way you handled adding the Hash function is easy to use and I have no problem with it.

Anyway just wanted to share my thinking with you. I have not decided the best way to move forward but would appreciate any ideas.

{
stream << tiles[i];
}
size_t state_digits;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may be misunderstanding but I think this should be more like:
return std::hashstd::string{}(stream.str());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each state is defined by an ordering of the tiles. Turning them into a number is a unique hash because it would be another state if it shared the same ordering of digits. The has of a size_t is just identity function I believe. Turning the string into a hash would also work but seemed less intuitive. I'm fine either way.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right. I chose to refactor it a little but it is now somewhere between your solution and mine

@btdubs
Copy link
Contributor Author
btdubs commented Mar 27, 2023

Those seem like reasonable steps although I would say for 3 the burden of creating a hash is low because even with a high collision hash function, you are likely to see performance improvements. The lookup at collisions is a search along a list which is likely the same performance as reading the closed list as a vector.
Let me know what you decide and how I can be of help. I really appreciate your work on this library.

@justinhj justinhj closed this Apr 1, 2023
@justinhj
Copy link
Owner
justinhj commented Apr 1, 2023

Thank you again for this contibution. I closed the PR rather than merging as I made some changes and merged it manually.

@btdubs
Copy link
Contributor Author
btdubs commented Apr 4, 2023

Great, thank you. Glad I could contribute back.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

0