【问题标题】:Apply algorithms considering a specific edge subset应用考虑特定边缘子集的算法
【发布时间】:2011-02-11 05:03:35
【问题描述】:

我有一个带有类型边缘的巨大图(即带有类型属性的边缘)。说

typedef adjacency_list<vecS, vecS, vertex_prop, edge_prop> Graph;  

边的“类型”是edge_prop的成员,在{A,B,C,D}中有一个值,
我想运行广度优先搜索算法,只考虑 A 或 B 类型的边。
你会怎么做?

【问题讨论】:

  • 您可能想要删除其中一个标签并添加 C++。

标签: c++ algorithm boost boost-graph


【解决方案1】:

因为很难找到混合 BGL 不同主题的简单示例,所以我在下面发布了一个使用 filters_graph 和捆绑属性的完整且有效的示例。:

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

using namespace boost;

enum edge_type_e {
  A, B, C, D
};

class edge_property_c {
public:
  edge_property_c(void) : type_m(A) {}
  edge_property_c(edge_type_e type) : type_m(type) {}
  edge_type_e type_m;
};

typedef adjacency_list<vecS, vecS, undirectedS, no_property, edge_property_c> graph_t;
typedef graph_t::edge_descriptor edge_id_t;

class edge_predicate_c {
public:
  edge_predicate_c() : graph_m(0) {}
  edge_predicate_c(graph_t& graph) : graph_m(&graph) {}
  bool operator()(const edge_id_t& edge_id) const {
    edge_type_e type = (*graph_m)[edge_id].type_m;
    return (type == A || type == B);
  }
private:
  graph_t* graph_m;
};

int main() {
  enum { a, b, c, d, e, n };
  const char* name = "abcde";
  graph_t g(n);
  add_edge(a, b, edge_property_c(A), g);
  add_edge(a, c, edge_property_c(C), g);
  add_edge(c, d, edge_property_c(A), g);
  add_edge(c, e, edge_property_c(B), g);
  add_edge(d, b, edge_property_c(D), g);
  add_edge(e, c, edge_property_c(B), g);

  filtered_graph<graph_t, edge_predicate_c> fg(g, edge_predicate_c(g));

  std::cout << "edge set: ";
  print_edges(g, name);
  std::cout << "filtered edge set: ";
  print_edges(fg, name);

  return 0;
}

【讨论】:

    【解决方案2】:

    最后我认为 boost::graph 方法是使用boost:filtered_graphdemo for usage

    “filtered_graph 类模板是一个适配器,它创建一个图形的过滤视图。谓词函数对象确定原始图形的哪些边和顶点将显示在过滤图形中。”

    因此,您可以提供基于 property_map 的边缘(或顶点)过滤函子。 就我而言,我使用的是内部捆绑属性。查看来自bundled properties 的属性映射。

    【讨论】:

      【解决方案3】:

      我对 boost::graph 不太熟悉,但我认为 BFSVisitor 是您正在寻找的东西。它允许您更改算法的行为,您的具体情况是在顶点发现后更改对传出边的检查并忽略不属于所需“类型”的那些(实际上是 {A,B,C,D } 是我理解的值,而不是严格意义上的类型)。

      【讨论】:

      • 您所指的事件点看起来不错 (vis.examine_edge(e, g)) 但是 1/ 它实际上是在 获得边缘的目标顶点之后出现的。 (for_each edge {Vertex v = target(*ei, g); vis.examine_edge(*ei, g); ... }. 2/ 边是由副本给出的,所以我真的不明白上面的算法如何忽略它。
      猜你喜欢
      • 1970-01-01
      • 2023-03-03
      • 2011-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-27
      相关资源
      最近更新 更多