2009-02-16 11 views
3

Je travaille sur un graphe orienté (en fait un graphe bidirectionnel) avec Boost.Graph. Je voudrais utiliser les algorithmes de mise en page qui existent (soit Kamada-Kawai ou Fruchterman-Reingold) mais ils n'acceptent que les graphes non orientés comme paramètres.Comment utiliser un graphe orienté BGL comme un graphe non orienté (à utiliser dans un algorithme de mise en page)?

Quelle est la manière la plus simple d'utiliser ces algorithmes de mise en page? Plus généralement, quelle est la bonne façon d'attirer un algorithme en lui faisant croire qu'un graphe orienté est réellement non orienté?

Merci, Benoît

+0

Quel type de représentation utilisez-vous? Matrice d'adjonction, liste d'adjonction ...? –

+0

J'utilise un adjacency_list

Répondre

4

Etes-vous sûr que l'algorithme Fruchterman-Reingold accepte uniquement les graphes non orientés? J'ai essayé d'exécuter le petit exemple à partir du Boost documentation en utilisant un graphique bidirectionnel au lieu d'un graphique non orienté, et il a été compilé et exécuté correctement.


Pour répondre à votre question, je ne suis pas sûr qu'il ya des installations construites dans le BGL pour convertir un graphe orienté vers un un non orienté. La seule solution que je trouve crée un nouveau graphique et l'ajout de tous les bords de l'original:

typedef adjacency_list<vecS, vecS, bidirectionalS> BidirectionalGraph; 
typedef adjacency_list<setS, vecS, bidirectionalS> UndirectedGraph; 
// UndirectedGraph uses a set to avoid parallel edges 

BidirectionalGraph bdg; 
// use bdg 

// create an undirected graph with the edges of the first one 
typedef graph_traits<BidirectionalGraph>::vertex_iterator vi_beg, vi_end; 
tie(vbeg, vend) = vertices(bdg); 

UndirectedGraph ug(std::distance(vbeg, vend)); 

typedef graph_traits<BidirectionalGraph>::edge_iterator ei, ei_end; 

for (tie(ei, ei_end) = edges(bdg) ; ei != ei_end ; ++ei) 
{ 
    add_edge(source(*ei,bdg), target(*ei,bdg), ug); 
} 

Cependant, je pense que cette solution pourrait soulever des problèmes de performance lorsqu'ils traitent avec des graphiques énormes. Il y a peut-être un meilleur moyen d'atteindre ton objectif, mais je ne suis pas un expert en BGL, donc c'est tout ce que je peux te donner :-)!


Comme Benoît a souligné dans un commentaire, la BGL fournir une fonction copy_graph qui copie tous les sommets et arêtes d'un graphe dans l'autre. Par conséquent, le code ci-dessus peut se résumer à ceci:

#include <boost/graph/copy.hpp> 

Bidirectional bdg; 
// use bdg 

// create an undirected graph with the vertices and edges of the first one 
UndirectedGraph g; 
copy_graph(bdg, g); 
+0

La documentation dit qu'il n'est pas conçu pour cela, mais je suppose que j'aurais dû essayer! Je suis toujours intéressé par la réponse, car un tel besoin va probablement revenir –

+0

Merci. C'est tout ce que j'ai trouvé aussi. J'espérais juste qu'il y aurait une sorte d'adaptateur pour ça. En tous cas. Je vais marquer votre réponse comme "acceptée" dès que vous aurez utilisé copy_graph :-) –

+0

Vous avez raison, j'ai totalement raté cette fonction! J'ai édité ma réponse pour inclure cela. –