2010-02-11 10 views
30

Je cherche un moyen d'accéder aux propriétés de vertex en utilisant une clé au lieu de la référence vertex elle-même. Par exemple, si jeTrouver le sommet BGL de Boost par une clé

class Data 
{ 
    public: 
    std::string name; 
    unsigned int value; 
}; 
typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, Data > Graph; 
typedef boost::graph_traits<Graph>::vertex_descriptor Vertex; 

au lieu d'utiliser

Vertex vertex1 = boost::add_vertex(g); 
g[vertex1].name = "Alpha"; 
g[vertex1].value = 10; 

Je voudrais avoir

g["Alpha"].name = "Alpha"; 
g["Alpha"].value = 10; 

Est-ce un mécanisme prêt à l'emploi existe?

Répondre

31

Je pense avoir trouvé un tel mécanisme. Il s'appelle label_graph et fait partie de BGL. Au lieu d'utiliser adjacency_list, on peut utiliser une enveloppe prédéfinie labeled_graph:

typedef boost::labeled_graph< 
    boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, Data >, 
    std::string 
> Graph; 

Après avoir défini un graphique comme celui-ci, il est possible d'accéder à des sommets de la manière suivante:

Graph g; 

boost::add_vertex("Alpha", g); 
g["Alpha"].name = "Alpha"; 
g["Alpha"].value = 10; 

boost::add_vertex("Beta", g); 
g["Beta"].name = "Beta"; 
g["Beta"].value = 20; 

boost::add_edge_by_label("Alpha", "Beta", g); 

L'effet secondaire de ceci est qu'il faut utiliser la fonction membre graph() pour faire fonctionner certains algorithmes:

std::vector<Graph::vertex_descriptor> container; 
boost::topological_sort(g.graph(), std::back_inserter(container)) ; 

Pour une raison quelconque, libellé_graph n'est pas décrit dans la documentation BGL, mais il apparaît dans le dossier d'exemple.

Merci pour la réponse, Serge

+0

En regardant l'histoire de l'adaptateur labeled_graph.hpp, il semble que le fichier est relativement nouveau. (Commencé à apparaître dans la version 1.40 de la bibliothèque Boost). Probablement c'est pourquoi il ne fait pas encore partie de la documentation, –

1

Un mécanisme prêt à l'emploi n'existe pas car le concept adjacency_list ne peut pas connaître que vous souhaitez accéder à votre propriété vertex par un champ dans une structure.

Je préférerais la façon d'avoir une carte supplémentaire qui mappe le nom des données au sommet correspondant. De plus, vous pouvez encapsuler votre algorithme dans une classe ou une fonction, de sorte que lorsque vous ajoutez un nouveau sommet, la carte est automatiquement remplie.