Search code examples
c++boosta-starboost-graph

Augment custom weights to edge descriptors in boost::grid_graph


I am using BGL for a custom AStar search. Basically, the nodes of the graph correspond to the cells of a map, and each cell has an elevation.

I've created an cell traversal score function stepTime which takes in the elevation of two cells, and outputs a cost function. I wanna add this cost function to the edge weights in my boost graph.

How do I go about this? I've seen functions using

auto weightmap = make_transform_value_property_map

to create a weight map, but how do I update the weights according to the output of:

double stepTime(const vertex_descriptor& source, const vertex_descriptor& target, const std::vector<uint8_t>& elevation)


Solution

  • but how do I update the weights according to the output of:

     double stepTime(const vertex_descriptor& source, const vertex_descriptor& target, const std::vector<uint8_t>& elevation)
    

    I have no clue where you get the elevation vector from, but I guess that's your problem.

    The source and target vertices are easily gotten from the graph itself, so here goes:

    auto custom = boost::make_function_property_map<Graph::edge_descriptor>(
            [&g,&elevation](Graph::edge_descriptor e) {
                return stepTime(boost::source(e, g), boost::target(e, g), elevation);
            });
    

    Demo

    Live On Coliru

    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/astar_search.hpp>
    #include <boost/property_map/function_property_map.hpp>
    #include <iostream>
    
    using Graph = boost::adjacency_list<>;
    
    double stepTime(const Graph::vertex_descriptor& source, const Graph::vertex_descriptor& target, const std::vector<uint8_t>& elevation) {
        std::cout << __FUNCTION__ << "(" << source << ", " << target << ", {" << elevation.size() << " elements})\n";
        return 42;
    }
    
    int main() {
        Graph g(10);
        add_edge(4, 5, g);
        add_edge(2, 8, g);
        add_edge(5, 1, g);
        add_edge(1, 3, g);
    
        std::vector<uint8_t> const elevation { 1,2,3,4,5,6 }; // or whatevs
    
        // custom weight map
        auto custom = boost::make_function_property_map<Graph::edge_descriptor>(
                [&g,&elevation](Graph::edge_descriptor e) {
                    return stepTime(boost::source(e, g), boost::target(e, g), elevation);
                });
    
        // pass it to an algorithm directly, or wrap it in a named-parameter object:
        auto param = boost::weight_map(custom);
        param.weight_map2(custom); // or as the alternative weight map
    }