Advertisement

A* class

Started by March 08, 2008 05:19 PM
3 comments, last by Decrius 16 years, 8 months ago
So, I made a class that will calculate the shortest path. And I will release it here to anyone who would like to use it. Any advice/comments: I'd love to hear some, the code can prolly be optimized and it would be great if I learn from my faults ;). You can download it here: Astar.zip ~ 3KiB (code is ~9KiB) Thanks for your time. If I did not properly applied A*, let me know and I'm willing to fix it ;). Decrius
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
As it stands, the code is not quite usable. A few improvements:
  • Remove references to mouse.x and mouse.y.
  • Let the user parametrize the system with the map width, the map height, the distance function and the heuristic, instead of hardcoding them.
  • Define a coordinate type (this can be as simple as typedef std::pair<int,int> coord;) or reuse your Path structure to make your argument definitions shorter.
  • Provide a function find_path(iter, start, dest) which accepts an iterator as argument and outputs the nodes in the path.


I would reduce the public interface of the class to:

template <typename D, typename H>class AStar{public:  typedef D distance_type;  typedef H heuristic_type;  // Define a new object working on a map represented by distance  // 'distance' (which returns infinity to mark impassable objects)  // and a heuristic 'heuristic'. You don't need width/height as  // these are implied by the return values of the distance  // function.  AStar(D distance, H heuristic);  // Find the shortest path between two points and append it  // to the provided iterator as a sequence of coordinates which  // includes the first and last points. Returns whether the   // function was successful in finding a point.  template<typename It>  bool find(It out, const point2d &from, const point2d &to);};
Advertisement
Ah I see :). I'm just a beginner and never published code, but I see the point that the usage could be simplyfied.

But for the iterator part...I found using iterators quite useless...but that could be me. And for the argument passing: yes, but doesn't that take more time? It first has to fill the struct and then pass it to the function, instead of just passing it to the funtion...

Thanks for looking at the code :), I will improve it.
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora
Quote: Original post by Decrius
But for the iterator part...I found using iterators quite useless...


I wish to be able to store the output of your function
  • In an std::vector
  • In an std::list
  • In an std::deque
  • The three above, but with the elements in reverse order.
  • The three above, but appending the result at the end of an existing container instead of an initially empty one.
  • Directly to standard output.


I don't know yet which of these will be useful and which won't. I also don't want to rewrite the function to handle different kinds of input (if, for instance, I happen to need two different places to store this) or if I must change my storage approach.

If you know of a solution to this problem that is more elegant than iterators, please tell me about it.

Quote: And for the argument passing: yes, but doesn't that take more time? It first has to fill the struct and then pass it to the function, instead of just passing it to the funtion...


If you group together values which are often used together, then you actually gain time. For instance:
void third(const point &a) { fourth(a); }void second(const point &a) { third(a); }void first(const point &a) { second(a); }


It doesn't happen very often that only one coordinate of a point is passed to a function. Therefore, the point structure will only have to be created once, and it will be reused wherever that particular point happens to be processed, instead of having to pass two arguments around every single time.

Besides, don't forget that integers can represent counts, indices, coordinates, and many other concepts. Labeling an argument as an "integer" doesn't tell you much about what that integer represents. By contrast, using a point argument is quite explicit.
Ah, I get the point. So using templates, using less function arguments and using iterators should fix those items?

I will keep that in mind when I publish code again, thanks! :)
[size="2"]SignatureShuffle: [size="2"]Random signature images on fora

This topic is closed to new replies.

Advertisement