Хорошо, я переведу и адаптирую свой учебник к вашему конкретному вопросу.Документация всегда предполагает тонны «использования пространства имен»;Я не буду использовать, чтобы вы знали, что к чему.Давайте начнем:
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/astar_search.hpp>
Сначала определите вершину и ребро:
struct Vertex{
string name; // or whatever, maybe nothing
};
struct Edge{
// nothing, probably. Or a weight, a distance, a direction, ...
};
Создайте тип или свой график:
typedef boost::adjacency_list< // adjacency_list is a template depending on :
boost::listS, // The container used for egdes : here, std::list.
boost::vecS, // The container used for vertices: here, std::vector.
boost::directedS, // directed or undirected edges ?.
Vertex, // The type that describes a Vertex.
Edge // The type that describes an Edge
> MyGraph;
Теперь вы можетеиспользуйте ярлык для типа идентификаторов ваших вершин и ребер:
typedef MyGraph::vertex_descriptor VertexID;
typedef MyGraph::edge_descriptor EdgeID;
Создание экземпляра вашего графика:
MyGraph graph;
Считывание данных Graphviz и подача графика:
for (each Vertex V){
VertexID vID = boost::add_vertex(graph); // vID is the index of a new Vertex
graph[vID].name = whatever;
}
Обратите внимание, что graph[ a VertexID ]
дает вершину, а graph[ an EdgeID ]
дает преимущество.Вот как добавить один:
EdgeID edge;
bool ok;
boost::tie(edge, ok) = boost::add_edge(u,v, graphe); // boost::add_edge gives a std::pair<EdgeID,bool>. It's complicated to write, so boost::tie does it for us.
if (ok) // make sure there wasn't any error (duplicates, maybe)
graph[edge].member = whatever you know about this edge
Итак, теперь у вас есть график.Вы хотите получить VertexID для Vertex "c".Для простоты давайте воспользуемся линейным поиском:
MyGraph::vertex_iterator vertexIt, vertexEnd;
boost::tie(vertexIt, vertexEnd) = vertices(graph);
for (; vertexIt != vertexEnd; ++vertexIt){
VertexID vertexID = *vertexIt; // dereference vertexIt, get the ID
Vertex & vertex = graph[vertexID];
if (vertex.name == std::string("c")){} // Gotcha
}
И, наконец, чтобы получить соседей вершины:
MyGraph::adjacency_iterator neighbourIt, neighbourEnd;
boost::tie(neighbourIt, neighbourEnd) = adjacent_vertices( vertexIdOfc, graph );
for(){you got it I guess}
Вы также можете получить ребра с помощью
std::pair<out_edge_iterator, out_edge_iterator> out_edges(vertex_descriptor u, const adjacency_list& g)
std::pair<in_edge_iterator, in_edge_iterator> in_edges(vertex_descriptor v, const adjacency_list& g)
// don't forget boost::tie !
Итак, для вашего реального вопроса:
- Найти идентификатор вершины "c"
- Рекурсивно найти in_edges
- Рекурсивно найти out_edges
Пример для in_edges (никогда не компилируется и не пробовал, из головы в голову):
void findParents(VertexID vID){
MyGraph::inv_adjacency_iterator parentIt, ParentEnd;
boost::tie(parentIt, ParentEnd) = inv_adjacent_vertices(vID, graph);
for(;parentIt != parentEnd); ++parentIt){
VertexID parentID = *parentIt;
Vertex & parent = graph[parentID];
add_edge_to_graphviz(vID, parentID); // or whatever
findParents(parentID);
}
}
Для обратного, просто переименуйте Parent в Children и используйте adjacency_iterator /acent_vertices.
Надеюсь, это поможет.