Boost DFS: Serial to Parallel

So, I implemented path overlapping on the graph using custom A * using boost::graph, but everything is designed from scratch.

What is road blocking is simple. Given the graph of the letters ( 'A'-> 'C', ...) and the word HELLO, I need to find the best match, starting with 'H'in the graph, ending with 'O'(if it exists or ends when the path length is reached). “Best” refers to how candidate nodes are selected, simply by examining a letter that is closer to the current one in the word. Therefore, the weights of the graphs are dynamic; they depend on the input word. See the following example:

/*
 *    B          H
 *   / \        /
 *  A---D---F---G---I
 *   \ /\
 *    C  E
 *
 *  input:  A E I O U
 *  result: A D F G I
 */

: DFS, . , : boost::depth_first_search.

: node. , 8 , 100 , . Parallel BGL.

?

, , BGL, , astar_search, depth_first_search. node, , , - .

, , , Parallel BGL.

!

#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
#include <utility>
#include <list>

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/astar_search.hpp>

// Funky
std::unordered_map<char, int> letters;
auto getletter = [](std::size_t i) -> char { return 'A' + i; };


typedef boost::adjacency_list<boost::vecS, // V
                              boost::vecS, // E
                              boost::bidirectionalS,
                              boost::no_property,
                              int // Ignore weights for now
                              > graph;

typedef boost::graph_traits<graph>::edge_iterator edge_iterator;

// Used to end the A*-like search algorithm
struct end_astar { };

// Custom A* visitor
template <class Vertex>
class bestmatch_visitor : public boost::default_dfs_visitor //public boost::default_astar_visitor
{
public:

    // Constructor
    bestmatch_visitor(Vertex goal) : destination_(goal) { };

    // ==============
    // == VERTICES ==
    // ==============

    template<class Graph>
    void initialize_vertex(Vertex u, const Graph &g)
    {
        std::cout << "init " << u << " " << getletter(u) << std::endl;
    }

    // Push a new vertex in the stack
    template<class Graph>
    void discover_vertex(Vertex u, const Graph &g)
    {
        std::cout << "discover " << u << " " << getletter(u) << std::endl;
    }

    // Pop a vertex and examine it
    template <class Graph>
    void examine_vertex(Vertex u, const Graph& g)
    {
        std::cout << ">>>>> examine " << u << " " << getletter(u) << std::endl;

        if (u == destination_) throw end_astar();
    }

    // Vertex examined, moving to the blacklist
    template <class Graph>
    void finish_vertex(Vertex u, const Graph& g)
    {
        std::cout << "vertex examined, closing " << u << " " << getletter(u) << std::endl;
    }

    // ===========
    // == EDGES ==
    // ===========

    // Examine out edges
    template <class Edge, class Graph>
    void examine_edge(Edge e, const Graph& g)
    {
        std::cout << "--> edge examine " << e << std::endl;
    }

    // Relax edge if distance from goal reduces
    template <class Edge, class Graph>
    void edge_relaxed(Edge e, const Graph& g)
    {
        std::cout << "--> edge relax " << e << std::endl;
    }

    // Distance from goal does not decrease: don't relax
    template <class Edge, class Graph>
    void edge_not_relaxed(Edge e, const Graph& g)
    {
        std::cout << "--> edge NOT relaxed " << e << std::endl;
    }

    // Ooops! Already checked this one
    template <class Edge, class Graph>
    void black_target(Edge e, const Graph& g)
    {
        std::cout << "--> BLACKLISTED " << e << std::endl;
    }


private:
    Vertex destination_;
};


int main()
{
    /*
     *    B          H
     *   / \        /
     *  A---D---F---G---I
     *   \ /\
     *    C  E
     *
     *  input:  A Z I M U T
     *  result: A C D F G I
     *
     *  nodes:  ABCDEFGHI
     *  codes:  012345678
     */

    for (int i = 'A'; i <= 'I'; i++) letters[i] = i - 'A';

    graph g;

    boost::add_edge(letters['A'], letters['B'], g);
    boost::add_edge(letters['A'], letters['C'], g);
    boost::add_edge(letters['A'], letters['D'], g);

    boost::add_edge(letters['B'], letters['D'], g);

    boost::add_edge(letters['C'], letters['D'], g);

    boost::add_edge(letters['D'], letters['E'], g);
    boost::add_edge(letters['D'], letters['F'], g);

    boost::add_edge(letters['F'], letters['G'], g);

    boost::add_edge(letters['G'], letters['H'], g);
    boost::add_edge(letters['G'], letters['I'], g);

    edge_iterator ei, ee;

    for (boost::tie(ei, ee) = boost::edges(g); ei != ee; ei++)
    {
        graph::edge_descriptor d = *ei;

        std::cout << getletter(boost::source(*ei, g)) << " -> " <<
        getletter(boost::target(*ei, g)) << "    " << std::endl; //<< g[d] << std::endl;
    }

    // Predecessors
    std::vector<graph::vertex_descriptor> p(boost::num_vertices(g));

    // Distances
    std::vector<graph::vertex_descriptor> d(boost::num_vertices(g));

    // Color: HOW?
    //typename boost::property_map<graph, boost::vertex_color_t>::type c;

    // Start and finish
    int start = letters['A'];
    int goal  = letters['I'];

    bestmatch_visitor<int> v(letters['A']);

    // Useless:
    boost::depth_first_search(g, boost::visitor(v));

    // HOW?
    //boost::depth_first_visit(g, letters['A'], boost::visitor(v), c);

}
+4

All Articles