Skip to content

Commit

Permalink
Merge pull request LearnProgramming#16 from jgulotta/master
Browse files Browse the repository at this point in the history
Update README with more info and a small example
  • Loading branch information
jgulotta committed Dec 21, 2012
2 parents 277beed + 1e351a4 commit e6d99b8
Showing 1 changed file with 86 additions and 0 deletions.
86 changes: 86 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,89 @@ for help with your particular setup, e.g. to create Visual Studio a project.

See the wiki for documentation on each example.

# Installing

The command

sudo make install

will install the header files to `${CMAKE_INSTALL_PREFIX}/include/astar`.
By default, `CMAKE_INSTALL_PREFIX = /usr/local` on Linux systems.

# Using the library

A\* requires 6 things, all of which must be provided by the user.

1. A way to represent state
2. A starting state
3. An ending state
4. A way to get from one state to others, a `Generator` function
5. A way to measure distance/cost between one state and the next, a `Distance` function
6. A way to estimate distance/cost from one state to the goal, an `Estimator` function

A state can be represented by any type `T` so long as the functions can operate on the state as described below.
States must be comparable through `operator<`. That is, `bool operator<(const T& left, const T& right)` must be defined.

A `Generator` function is any callable (function, lambda, functor) that takes one state and returns
a `std::vector` of "next", "nearest", or "neighbor" states.
That is, a `Generator` function `g` must support the expression `std::vector<T> v = g(t)` for any `t` of type `const T&`.

A `Distance` is any callable that takes two states and returns the distance between or cost to get from the first state to the second.
The representation of that distance can be anything. Typical types are `int` or `double` but user defined types are also permitted.
Therefore a `Distance` function `d` must support the expression `G g = d(from, to)`,
where `from` and `to` are both of type `const T&`.

An `Estimator` is any callable that takes two states and returns the distance between or cost to get from the first state to the second.
The representation of that distance can be anything. Typical types are `int` or `double` but user defined types are also permitted.
Therefore an `Estimator` function `e` must support the expression `H h = e(from, to)`,
where `from` and `to` are both of type `const T&`.

The return types of the `Distance` and `Estimator` functions do not need to be the same but they do need to be compatible
through `operator+`. That is, there should exist a function `J operator+(const G&, const H&)`.
Two instances of type `J` must be comparable through `operator>`, meaning `bool operator>(const J& left, const J& right)`
must be defined.

The `Generator` is used to create the next potential nodes to evaluate. At the time they are generated,
the `Distance` function will be called for each with the current state as the first parameter and the potential as the second.
Similarly, the `Estimator` function will be called for each with the potential as the first parameter and the
provided ending state as the second.

These can all be passed to the convenience function `make_solver` which has the partial signature

make_solver(const T& start, const T& goal, Generator, Distance, Estimator)

and will instantiate an appropriate solver of type `AStarSolver<T,G,H>`.

It is recommended to use `auto` for type deduction as this will allow the implementation to change with minimal
impact to client code. Ideally the interface will not change too drastically but backwards compatibility is not
a priority at this stage.

After instantiation, simply call `solve()`.

Presently the only way to see the solution is to call `print_solution`, which will write the backtrace to the
specified `std::ostream`, defaulting to `std::cout`. This function requires `operator<<` to exist for both
`T` and `J`. Specifically, `std::ostream& operator<<(std::ostream&, const T&)` must be defined for each type.

# Minimal example

```cpp
/*
assume anything not explicitly defined below is appropriately defined,
specifically that Type exists and has a get_neighbors() method returning a std::vector<Type>,
that get_start() and get_end() each return the expected Type,
and that operator< and operator<< are both supplied for Type comparison and output
*/
#include <astar/solver.h>

Type start = get_start();
Type end = get_end();
auto gen = [](const Type& t) { return t.get_neighbors(); };
auto dist = [](const Type& from, const Type& to) { return 1; };
auto est = [](const Type& from, const Type& to) { return 0; };

auto solver = make_solver(start, end, gen, dist, est);

solver.solve();

solver.print_solution();
```

0 comments on commit e6d99b8

Please sign in to comment.