การใช้คุณสมบัติแบบรวมเป็นแผนที่น้ำหนักใน dijkstra_shortest_paths

บางทีนี่อาจเป็นคำถามโง่ ๆ แต่ฉันกำลังพยายามใช้ dijkstra_shortest_paths ของ BGL และโดยเฉพาะอย่างยิ่งเพื่อใช้ฟิลด์ของคุณสมบัติที่รวม Edge ของฉันเป็นแผนที่น้ำหนัก ความพยายามของฉันทำให้เกิดข้อผิดพลาดของคอมไพเลอร์หลายสิบหน้า ดังนั้นฉันหวังว่าจะมีคนรู้ว่าจะช่วยฉันได้อย่างไร นี่คือลักษณะของรหัสของฉัน:

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

ฉันสามารถเติมกราฟได้โดยไม่มีปัญหาใดๆ แต่เมื่อถึงเวลาโทร dijkstra_shortest_paths ฉันจะประสบปัญหา ฉันต้องการใช้ฟิลด์ length โดยเฉพาะอย่างยิ่ง ฉันต้องการทราบว่าวูดูบูสต์ที่จำเป็นเล็กน้อยคืออะไรเพื่อให้เข้ากับการโทรเช่นนี้:

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?

ดังนั้นแผนที่น้ำหนักจะเชื่อมโยงขอบกราฟของฉันกับฟิลด์ length ที่เกี่ยวข้องในคุณสมบัติ ฉันแน่ใจว่ามีวิธีง่ายๆ ในการทำเช่นนี้ แต่เอกสารสำหรับ BGL นั้นคลุมเครือสำหรับฉันอย่างไม่น่าเชื่อ หากคุณสามารถบอกฉันได้ว่ามีการอธิบายตัวอย่างไว้ที่ใดในเอกสารประกอบ ฉันก็จะมีความสุขมากเช่นกัน

ขอบคุณล่วงหน้า!


person Carlos Scheidegger    schedule 20.08.2010    source แหล่งที่มา


คำตอบ (3)


ในกรณีที่ใครก็ตามสนใจเรื่องนี้ ดูเหมือนว่าการใช้เวอร์ชันพารามิเตอร์ที่มีชื่อของการเรียกจะทำงานได้ดังนี้:

    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))));

ข้อมูลนี้มีอยู่ในเอกสาร ที่นี่ ฉันยังไม่รู้วิธีใช้การโทรเวอร์ชัน "พารามิเตอร์ที่ไม่มีชื่อ"

person Carlos Scheidegger    schedule 20.08.2010

ตกลง ฉันเสียเวลามากเกินไปกับปัญหานี้ นี่คือวิธีแก้ปัญหาสำหรับลูกหลาน:

/**
 * @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;
}

จริงๆ แล้วไลบรารีนี้ดีมาก แต่เอกสารประกอบขาดแน่นอน นี่ควรเป็นเรื่องเล็กน้อย


แก้ไข

หากคุณใช้ C++11 คุณอาจต้องการตัวเลือกอื่นต่อไปนี้

    auto handle_to_something( boost::get(&bundled_in_vertex_type::something, g) );
person user1661473    schedule 11.09.2012

น่าเสียดายที่ BGL อาจทรงพลังพอๆ กับที่น่าเสียดาย มันไม่ง่ายเลยที่จะใช้งานในความคิดเห็นของฉัน การทำให้สิ่งนี้ใช้งานได้ต้องผ่านการลองผิดลองถูกหลายครั้ง แต่นี่คือเวอร์ชันที่ใช้งานได้ซึ่งคอมไพล์ด้วย Boost 1.53.0 [เราต้องการใช้อัลกอริทึมของ Dijkstra กับตัวแปร 'rate' ใน __edge_data]:

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>()) );

    ...
}

ฉันหวังเป็นอย่างยิ่งว่านี่จะช่วยได้! ความพยายามของฉันที่นี่คือการแสดงวิธีเข้าถึง 'คุณสมบัติ' หลักทั้งหมดที่มีในอัลกอริทึม

person user2587407    schedule 16.07.2013