4
votes

I'm trying to implement Best First Search using C++ on VS2013. Below is the code.

    //node for tree
    struct Node
    {
        Node(std::string const& s, std::string const& p)
            : state(s), path(p)
        {}

        const std::string state;
        const std::string path;
    };

    //heuristic functor
    struct ManhattanDistance
    {
        std::size_t operator()(std::string const& state, std::string const& goal)
        {
            std::size_t ret = 0;
            for (int index = 0; index != goal.size(); ++index)
            {
                if ('0' == state[index])
                    continue;

                auto digit = state[index] - '0';
                ret += abs(index / 3 - digit / 3) + abs(index % 3 - digit % 3);// distance(row) plus distance(col)
            }

            return ret;
        }
    };

    //functor to compare nodes using the heuristic function.
    template<typename HeuristicFunc>
    struct GreaterThan
    {
        explicit GreaterThan(HeuristicFunc h, std::string const& g = "012345678")
            : goal(g), heuristic(h)
        {}

        bool operator()(Node const& lhs, Node const& rhs) const
        {
            return heuristic(lhs.state, goal) > heuristic(rhs.state, goal);
            return true;
        }

        const std::string goal;
        const HeuristicFunc heuristic;
    };

When testing this code in Unit Test, compiler complained that :

Error 1 error C3848: expression having type 'const ai::search::ManhattanDistance' would lose some const-volatile qualifiers in order to call 'size_t ManhattanDistance::operator ()(const std::string &,const std::string &)'

How to understand this error? How to fix it?

1
Don't you mean "Depth First Search" or "Breadth First Search"? "Best First Search" is new to me...Ulrich Eckhardt
Hi @UlrichEckhardt ,not DFS or BFS. Best First Search uses a heuristic function to evaluate each node, so that we can use this value as the key to order nodes in a priority queue. This way sometimes has better performance than plain DFS or BFS. Check here for more detail : en.wikipedia.org/wiki/Best-first_searchYue Wang
Thank you, didn't know about that one.Ulrich Eckhardt

1 Answers

10
votes

Your method std::size_t ManhattanDistance::operator()(std::string const& state, std::string const& goal) is not declared const, yet you try to call it on a const ManhattanDistance object. The compiler is correctly rejecting this ill-formed program.

Change the defining line to declare the method const:

std::size_t operator()(std::string const& state, std::string const& goal) const
//                                                                        ^^^^^