Применить алгоритмы, учитывая определенное подмножество кромки
-
01-10-2019 - |
Вопрос
У меня есть огромный график с типированным преимуществом (т.е. край с свойством типа). Сказать
typedef adjacency_list<vecS, vecS, vertex_prop, edge_prop> Graph;
«Тип» края является элементом Edge_Prop и имеет значение в {A, B, C, D},
Я хотел бы запустить широкий алгоритм первого поиска, учитывая только края типа A или B.
Как бы Вы это сделали?
Решение 2
Наконец я думаю, что усиление :: графический способ сделать это - использовать Boost: filtered_graph а также Демо для использования
«Шаблон класса Filtered_Graph - это адаптер, который создает фильтруемый вид графика. Объекты функции предикатов определяют, какие кромки и вершины исходного графа появятся в фильтрованном графике».
Таким образом, вы можете предоставить краевую (или вершину) фильтрующую базу функтора на свойства_map. В моем случае я использую внутренние комплектные свойства. Смотрите свойства карты из Соблюдающие свойства.
Другие советы
Поскольку трудно найти простой пример, смешивающий разные темы BGL, я публикую ниже полный рабочий пример, используя Filtered_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;
}
Я довольно незнакомый с Boost :: График, но я предполагаю Bfsvisitor это то, что вы ищете. Это позволяет вам изменить поведение алгоритма, и ваш конкретный случай будет изменять экзамен исходящих краев после обнаружения вершины и игнорировать те, которые не имеют необходимого «типа» (фактически {A, B, C, D, D } являются ценностями, насколько я понимаю, а не типы в строгом смысле).