简体   繁体   English

在dijkstra_shortest_paths中使用捆绑属性作为权重映射

[英]Using bundled properties as the weight map in dijkstra_shortest_paths

Perhaps this is a stupid question, but I'm trying to use BGL's dijkstra_shortest_paths , and, in particular, to use a field of my Edge bundled property as the weightmap. 也许这是一个愚蠢的问题,但我正在尝试使用BGL的dijkstra_shortest_paths ,特别是使用我的Edge捆绑属性的字段作为权重图。 My attempts have currently led to tens of pages of compiler errors, so I'm hoping that someone knows how to help me. 我的尝试目前导致了数十页的编译器错误,所以我希望有人知道如何帮助我。 This is essentially what my code looks like: 这基本上就是我的代码:

struct GraphEdge {
    float length;
    // other cruft
};
struct GraphVertex {
    ...
};
typedef boost::adjacency_list
<boost::vecS, boost::vecS, boost::directedS,
 GraphVertex, GraphEdge> GraphType;

I can populate the graph without any problems, however when it comes to calling dijkstra_shortest_paths , I get in trouble. 我可以毫无问题地填充图形,但是当涉及调用dijkstra_shortest_paths ,我遇到了麻烦。 I'd like to use the length field. 我想使用length字段。 Specifically, I'd like to know what's the bit of needed boost voodoo to go fit in a call like this: 具体来说,我想知道在这样的通话中需要什么样的增强伏都教才能适应:

GraphType m_graph;

vector<int> predecessor(num_vertices(m_graph));
vector<float> distances(num_vertices(m_graph), 0.0f);
vector<int> vertex_index_map(num_vertices(m_graph));
for (size_t i=0; i<vertex_index_map.size(); ++i) {
    vertex_index_map[i] = i;
}

dijkstra_shortest_paths(m_graph, vertex_from, predecessor, distances, 
                        weightmap, vertex_index_map, 
                        std::less<float>(), closed_plus<float>(), 
                        (std::numeric_limits<float>::max)(), 0.0f,
                        default_dijkstra_visitor());
// How do I write the right version of weightmap here?

such that weightmap will somehow associate a particular edge of my graph with the corresponding length field in the property. 这样,weightmap会以某种方式将我的图形的特定边缘与属性中的相应length字段相关联。 I'm sure there's an easy way to do this, but the documentation for BGL is incredibly opaque to me. 我确信有一种简单的方法可以做到这一点,但BGL的文档对我来说是非常不透明的。 If you can tell me where in the documentation the example is described, I'd be very happy as well. 如果您可以告诉我描述示例的文档中的哪个位置,我也会非常高兴。

Thank you in advance! 先感谢您!

In case anyone cares about this, using the named parameter version of the call seems to have worked, as follows: 如果有人关心这一点,使用命名参数版本的调用似乎有效,如下所示:

    dijkstra_shortest_paths(m_graph, vertex_from,
                        weight_map(get(&TrafficGraphEdge::length, m_graph))
                        .distance_map(make_iterator_property_map(distances.begin(),
                                                                 get(vertex_index, m_graph))));

This is in the documentation, here . 这是在文档中, 这里 I still don't know how to use the "non-named parameter" version of the call, though. 不过,我仍然不知道如何使用“非命名参数”版本的调用。

Ok, I just wasted too much time on this problem. 好吧,我在这个问题上浪费了太多时间。 Here is the solution for the posterity: 这是后人的解决方案:

/**
 * @brief  Example concerning bundled properties.
 * @author Pierre-Andre Noel
 * @date   September 10 2012
 */

#include <iostream>
#include <boost/graph/adjacency_list.hpp>

/// The type of the field we are interested in.
typedef int interesting_type;

/// The struct whose elements will be bundled in each vertex.
struct bundled_in_vertex_type
{
  /// Something interesting.
  interesting_type something;
};

int main()
{
  typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, bundled_in_vertex_type > graph_type;
  typedef graph_type::vertex_descriptor vertex_descriptor_type;

  /// Create a graph of two vertices.
  graph_type g(2);

  /// Name the two nodes.
  const vertex_descriptor_type v1(*boost::vertices(g).first), v2(*(++boost::vertices(g).first));

  // Store some stuff in the two nodes, the "easy" way.
  g[v1].something = interesting_type(42);
  g[v2].something = interesting_type(999);

  // Now what you came here for.
  /// An handle providing direct access to the field "something".
  boost::property_map< graph_type, interesting_type bundled_in_vertex_type::* >::type handle_to_something( boost::get(&bundled_in_vertex_type::something, g) );
  // You can now use "handle_to_something" for whatever deed you are interested in.

  // Just checking that it works.
  std::cout << "Vertex v1's ""something"" field is: " << handle_to_something[v1] << std::endl;
  std::cout << "Vertex v2's ""something"" field is: " << handle_to_something[v2] << std::endl;

  // Thank you and have a nice day.
  return 0;
}

Seriously, this library is great, but the documentation is definitively lacking. 说真的,这个库很棒,但文档肯定缺乏。 This should be a trivial matter. 这应该是一件小事。


EDIT 编辑

If you are using C++11, then you may prefer the following alternative. 如果您使用的是C ++ 11,那么您可能更喜欢以下替代方案。

    auto handle_to_something( boost::get(&bundled_in_vertex_type::something, g) );

As powerful as the BGL may be, unfortunately, it is not very easy to use in my honest opinion. 不幸的是,就像BGL一样强大,在我的诚实意见中使用起来并不容易。 Getting this to work took some considerable trial and error, but here is a working version compiled with Boost 1.53.0 [we want to use Dijkstra's algorithm on the 'rate' variable in __edge_data]: 实现这一点需要花费大量的试验和错误,但这是一个使用Boost 1.53.0编译的工作版本[我们想在__edge_data中的'rate'变量上使用Dijkstra算法]:

struct __edge_data
{
    double rate;
    double edge_thickness;
    size_t colour;
};

struct __vertex_data
{   
   size_t colour; 
   size_t shape_code;
   string name;
};

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, __vertex_data, __edge_data> DIgraph;
typedef boost::graph_traits<DIgraph>::vertex_descriptor vertexx;
typedef boost::graph_traits<DIgraph>::vertex_iterator   vertexx_iter;
typedef boost::graph_traits<DIgraph>::edge_descriptor   edgee;

// functor
template<typename T>
struct combine_min : public std::binary_function<T, T, T>
{
        T const operator()(const T& a, const T& b) const
        {
            return b < a ? (b) : (a);
        }
};

// functor
template<typename T>
struct compare_less_than : public std::binary_function<T, T, bool>
{
        bool const operator()(const T& a, const T& b) const
        {
            return a < b;
        }
};

void graph_analysis()
{
     ...

      std::vector<vertexx>   parents(num_vertices(G)); 
      std::vector<double>  distances(num_vertices(G)); 

      auto p_map = boost::make_iterator_property_map(&parents[0], boost::get(boost::vertex_index, G));
      auto d_map = boost::make_iterator_property_map(&distances[0], boost::get(boost::vertex_index, G));
      auto w_map = boost::get(&__edge_data::rate_rate, G); // <=== THIS IS THE TRICK!!!
      auto n_map = boost::get(&__vertex_data::name, G);

      boost::dijkstra_shortest_paths(G, start_vertex_vector,
       boost::weight_map(w_map).
              predecessor_map(p_map).
              distance_map(d_map).
              distance_combine(combine_min<double>()).
              distance_compare(compare_less_than<double>()) );

    ...
}

I sincerely hope this helps! 我衷心希望这有帮助! My attempt here was to show how to access all the main 'features' available to the algorithm. 我在这里的尝试是展示如何访问算法可用的所有主要“功能”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 boost的dijkstra_shortest_paths中的负边权重检查 - Negative edge weight check in boost's dijkstra_shortest_paths BGL Dijkstra具有捆绑属性的最短路径 - BGL Dijkstra Shortest Paths with Bundled Properties 使用外部权重调用提升 dijkstra 最短路径算法 map - Call boosts dijkstra shortest paths algorithm using a external weight map dijkstra_shortest_paths Boost Graph Lib 1.57.0失败 - dijkstra_shortest_paths Boost Graph Lib 1.57.0 fails Boost中的自定义图形距离dijkstra_shortest_paths - Custom graph distance in Boost dijkstra_shortest_paths 增强图:dijkstra_shortest_paths:无法形成对“ void”的引用 - Boost graph: dijkstra_shortest_paths: cannot form a reference to 'void' boost :: dijkstra_shortest_paths覆盖内部图形权重? - boost::dijkstra_shortest_paths overwriting internal graph weights? 当特定节点对之间存在多条最短路径时,boost graph dijkstra_shortest_paths 如何选择最短路径? - How does boost graph dijkstra_shortest_paths pick the shortest path when there are multiple shortest paths between a specific pair of nodes? 用boost :: graph包装我的自定义图并计算dijkstra_shortest_paths - Wrap my custom graph with boost::graph and calculate dijkstra_shortest_paths 如何从 GraphML 获取边权重到 boost::dijkstra_shortest_paths? - How do I get edge weights from GraphML into boost::dijkstra_shortest_paths?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM