Vous êtes sur la page 1sur 95

Th

eorie des graphes


Principes et programmation
Soluscience
Yann Dantal
Yann.Dantal@soluscience.fr
Christophe Haug
Christophe.Haug@soluscience.fr
Copyright c 2003 Soluscience
Table des mati`eres
I Structures de graphe 9
1 Structure dun graphe simple 11
1.1 Denitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2 Representations classiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.1 Matrice dadjacence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.2.2 Matrices dincidence sommet-arc . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.3 Listes dadjacence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3 Proprietes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3.1 Acyclicite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3.2 Simple connexite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.3.3 Connexite forte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.3.4 Biconnexite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2 Structure dun graphe hierarchique 15
3 Implementation 17
3.1 Les classes de structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.1.1 La classe GraphStruct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.1.2 Les sous-graphes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.1.3 Les graphes hierarchiques . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Les mille et un parcours dun graphe . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.1 Interface de programmation . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.2 Quelques parcours predenis . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.3 Utilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
II Algorithmie 23
4 Denitions et proprietes des graphes 25
4.1 Algorithmes de parcours . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.1.1 Le parcours en largeur (BFS : Breadth First Search) . . . . . . . . . . . . 25
4.1.2 Le parcours en profondeur (DFS : Depth First Search) . . . . . . . . . . . 26
Illustration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2 Les applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
4.2.1 Premier cas dapplication du DFS : le tri topologique . . . . . . . . . . . 28
4.2.2 Le deuxi`eme cas dapplication du DFS : la biconnexite . . . . . . . . . . . 30
4.2.3 Le troisi`eme cas dapplication du DFS : les composantes connexes . . . . 32
III Geometrie 3D des structures relationnelles 33
5 Attributs dun graphe 3D 35
5.1 Les mod`eles nodaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.2 Les mod`eles composites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.3 Attributs auxiliaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
6 Resolution geometrique de graphes 3D 37
6.1 Mode operatoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.2 Formulation directe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.3 Formulation optimale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.3.1 Calcul des orientations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
6.3.2 Calcul des translations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
7 Implementation et utilisation 41
7.1 Cas simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
7.2 Cas hierarchique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
IV Interfaces utilisateur 43
8 Presentation de lediteur de graphe 45
8.1 Interfaces graphiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
8.2 Interface de donnees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
8.3 Donnees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
8.4 Exemple dutilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
8.4.1 Localisation de lexemple . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
8.4.2 Code dutilisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
8.5 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
9 Interface de donnees 49
9.1 Classe de declaration :VManagerGraph . . . . . . . . . . . . . . . . . . . . . . . . 50
9.1.1 Methodes virtuelles de declaration . . . . . . . . . . . . . . . . . . . . . . 50
9.1.2 Declaration dune modication . . . . . . . . . . . . . . . . . . . . . . . . 50
9.1.3 Stockage des modications . . . . . . . . . . . . . . . . . . . . . . . . . . 52
9.2 Classe dimplementation :VManagerGraphTest . . . . . . . . . . . . . . . . . . . . 52
9.2.1 Separation donnees de graphe/autres donnees . . . . . . . . . . . . . . . . 52
9.2.2 Separation recuperation/modication dinformations . . . . . . . . . . . . 53
9.2.3 Gestion du graphe hierarchique. . . . . . . . . . . . . . . . . . . . . . . . 53
9.2.4 Code exemple de creation dun gestionnaire . . . . . . . . . . . . . . . . . 53
10 Interface graphique du graphe 55
10.1 wxGraph . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
10.1.1 Comportement abstrait wxAbstractComportGraph . . . . . . . . . . . . . 56
10.1.2 Comportement souris wxMouseComportGraph . . . . . . . . . . . . . . . . 58
10.1.3 Comportement clavier wxComportGraph . . . . . . . . . . . . . . . . . . . 58
10.1.4 Style graphique wxStyleGraph . . . . . . . . . . . . . . . . . . . . . . . . 58
10.1.5 Interface scrollable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
10.1.6 Informations internes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
10.1.7 Donnee de calque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
10.2 wxGraphScroll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
10.3 wxGraphEditor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
11 Gestionnaire de calques 65
V Tutorial 67
12 Tutorial 69
12.1 Graphe et parcours de graphe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
13 Tutorial 77
13.1 Creation dun graphe hierarchique . . . . . . . . . . . . . . . . . . . . . . . . . . 77
13.2 Creation dun graphe hierarchique recurif . . . . . . . . . . . . . . . . . . . . . . 82
13.3 Utilisation de sous mod`eles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
VI Pour nir. . . 89
A Le reste du monde 93
A.1 Theorie de graphes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
A.2 Programmation de graphes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
A.3 Visualisation de graphes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
A.4 Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Copyright c 2003 Soluscience 5
6 Copyright c 2003 Soluscience
Introduction
En 50 ans, la theorie des graphes a produit une quantite incroyable dalgorithmes permettant
de les transformer en un outil de modelisation tr`es puissant.
La validite de ces algorithmes nest plus `a prouver. Neanmoins, pour pouvoir en proter, il
est necessaire de disposer dune base algorithmique permettant de les implementer.
Nous proposons ici une biblioth`eque permettant la manipulation de ces graphes. Nous fournis-
sons une structure de donnees tr`es performante permettant lapplication aisee de ces algorithmes.
La documentation presentee ici est encore dans une phase de tests. Elle ne sera (et ne
pourra) etre compl`ete quapr`es lutilisation de la biblioth`eque par les utilisateurs. La validation
de la biblioth`eque et de sa documentation se feront par le biais des retours derreurs.
Dans la premi`ere partie de ce document nous presenterons quelques bases theoriques necessaires
`a la comprehension et `a la manipulation du concept de graphes. Nous introduirons egalement
une notion moins connue, celle de graphe hierarchique. Nous montrerons egalement les structures
de bases de la biblioth`eque permettant la manipulation de ces graphes.
La deuxi`eme partie sinteressera `a lalgorithmie de graphe, et nous presenterons les quelques
algorithmes de base implementes dans la biblioth`eque.
La troisi`eme partie penchera sur les geometrie 3D des structures relationnelles, et donc de
la representation de graphes tridimensionnels.
La quatri`eme partie presentera les mecanismes de linterface utilisateur. Elle introduit les
fonctionnalites essentielles de linterface de programmation.
Nous concluerons ce document par un tutorial, et par un recensement des travaux eectues
dans le monde sur ce sujet.
Copyright c 2003 Soluscience 7
Premi`ere partie
Structures de graphe
Copyright c 2003 Soluscience 9
Chapitre 1
Structure dun graphe simple
b
a
s
e
/
s
t
r
u
c
t
1.1 Denitions
On appelle graphe G le couple (S, A) constitue dun ensemble S de sommets et dun
ensemble A darcs. Chaque arc de A relie deux sommets de S.
Un graphe peut etre oriente ou non selon le sens que lon donne aux arcs, les deux sommets
quils relient pouvant etre consideres comme ordonne ou non.
Nous ajouterons une notion, qui nest pas essentielle `a la theorie des graphes, mais qui est
extremement importante, dans son applicabilite et sa generalisation. Il sagit de la notion de
port. Il correspond `a la localisation de laccroche, realisee ou non, dun arc sur un sommet.
Il permet notamment de montrer un graphe en cours de construction, les ports dun sommet
pouvant etre imposes par des r`egles externes `a la theorie des graphes.
On appelle sous-graphe de G, un graphe G

= (S

, A

) tel que S

et A

soient des sous-


ensembles respectifs de S et A.
On appelle sous-graphe de G induit par S

, le sous-graphe G

= (S

, A

) de G tels que A

soit lensemble des arcs de A reliant des sommets de S

.
b
a
s
e
/
s
t
r
u
c
t
1.2 Representations classiques
Nous allons presenter dierentes methodes de representation formelle des graphes.
1.2.1 Matrice dadjacence
Cest une matrice A(n, n) telle que a
i,j
= 1 pour tout arc (i, j) appartenant au graphe, tous
les autres elements etant nuls.
Illustration Voici une matrice dadjacence :
a b c d
a 0 1 1 1
b 0 0 0 0
c 0 0 0 0
d 0 1 0 0
Voici son expression :
Copyright c 2003 Soluscience 11
CHAPITRE 1. STRUCTURE DUN GRAPHE SIMPLE
a
b
d
c
Fig. 1.1 Expression de la matrice dadjacence precedente
1.2.2 Matrices dincidence sommet-arc
Cest une matrice A, de taille n m. On associe les sommets aux lignes, et les arcs aux
colonnes. Lecriture de cette matrice necessite la numerotation des arcs ; le choix est laisse `a
lutilisateur. On denira donc la matrice de A de la sorte :
a
ij
=
_

_
1 si le sommet i est le sommet origine de larc k
1 si le sommet i est le sommet destination de larc k
0 sinon
On obtient une matrice tr`es creuse. Cette methode est donc peu performante. On la presente
`a des ns theoriques plus qualgorithmique tant son utilisation se rev`ele co uteuse et complexe.
Illustration Voici une matrice dincidence :
1 2 3 4 5
a 1 1 1 0 0
b -1 0 0 -1 1
c 0 0 -1 0 -1
d 0 -1 0 1 0
Voici son expression :
b
c
5
a
1
3
d
2
4
Fig. 1.2 Expression de la matrice dincidence precedente
1.2.3 Listes dadjacence
La structure de liste dadjacence est souvent utilisee car elle permet de representer un graphe
peu dense sans utiliser beaucoup de ressources.
12 Copyright c 2003 Soluscience
Cette liste dadjacence dun graphe G = (S, A) consiste en un tableau Adj de |S| listes, une
pour chaque sommet de S. Pour tout u S la liste dadjacence Adj[u] est une liste chanee des
sommets v, pour (u, v) A. Donc Adj[u] est constituee de tous les sommets adjacents `a u dans
G.
Illustration Voici une representation par liste dadjacence :
a c b d
b e
c
d b
e a
Voici son expression :
a
b
d
c
e
Fig. 1.3 Expression des listes dadjacence precedentes
b
a
s
e
/
s
t
r
u
c
t
1.3 Proprietes
1.3.1 Acyclicite
On appelle cycle dun graphe (S, A), un sous-ensemble ordonne darcs, tel que tout couple
darcs consecutifs puisse secrire ((u, v), (v, w)) et que le premier arc et le dernier arc secrivent
(a, b) et (c, a). Cette notion sapplique aussi bien dans un graphe oriente que non-oriente.
Un graphe est dit acyclique lorsquil ne poss`ede aucun cycle. Attention, un graphe non-
oriente peut contenir des cycles alors que lorsquil est considere comme oriente, il soit acyclique.
On attribue souvent un ordre topologique `a un graphe acyclique oriente. Cet ordre est
dailleurs la preuve lorsquil peut etre applique, que le graphe est acyclique. On represente
souvent cet ordre par une valeur unique attribuee `a chaque sommet. Cette valeur OT : S R
verie alors pour tout arc (u, v) reliant deux sommets u et v, on a legalite OT(u) > OT(v).
1.3.2 Simple connexite
On appelle chemin simple de u `a v, ...
Un graphe (S, A) est dit simplement connexe si pour tous sommets u et v de S, u ; v
implique quil existe au plus un chemin simple de u `a v.
Copyright c 2003 Soluscience 13
CHAPITRE 1. STRUCTURE DUN GRAPHE SIMPLE
1.3.3 Connexite forte
On appelle composante fortement connexe dun graphe oriente (S, A), le sous-graphe
(S

, A

) induit par S

qui soit maximal quant `a la relation dinclusion sur les sommets et tel que
tout couple de sommets soient mutuellement accessibles ((u, v) A

u ; v et v ; u).
1.3.4 Biconnexite
On appelle composante biconnexe dun graphe G un ensemble maximal daretes tel que
deux aretes quelconques de lensemble se trouvent dans le meme cycle elementaire
1
. On appelera
point (resp. arete) darticulation dun graphe connexe tout nud (resp. arete) dont la
suppression rend le graphe non connexe.
1
Un cycle est dit elementaire si tous les sommets sont distincts
14 Copyright c 2003 Soluscience
Chapitre 2
Structure dun graphe hierarchique
La structure de graphe hierarchique G
0
repose sur un ensemble, M= {M}, de mod`eles
de graphes et la donnee, M
0
, dun de ces mod`eles. On dit que G
0
est une instantiation de
M
0
sur M.
Nous distinguerons deux types de mod`ele de graphe. Le premier, dit composite, est constitue
de plusieurs elements :
une liste dinstantiations g
0
(i) de M
m(i)
sur M{M
0
},
une liste de ports externes, P
0
(p),
une liste de connections dinstantiation `a instantiation, S
0
() = (P
i
1
()
(p
1
()), P
i
2
()
(p
2
())),
une liste de connections dinstantiation `a port externe, S
0
() = (P
i()
(p()), P
0
(p
2
())),
Le deuxi`eme type de mod`ele, dit elementaire ou nodal, est simplement constitue dune liste
de ports externes.
Exemples :
Copyright c 2003 Soluscience 15
CHAPITRE 2. STRUCTURE DUN GRAPHE HI

ERARCHIQUE
16 Copyright c 2003 Soluscience
Chapitre 3
Implementation
Lexpression dun graphe dans des codes de programmation est tr`es dierente de celle dun
vecteur, dune liste ou meme dun dictionnaire. Souvent dans ces derni`eres notions la structure
meme des donnees est assez evidente (sequentielle) pour netre abordee que par hasard. Dans
un graphe, la structure prend au contraire une place preponderante voire cruciale.
Il etait donc necessaire de pouvoir manipuler cette structure independamment des donnees
qui pouvaient y etre attachees.
`
A linverse de la STL, nous avons donc fait le choix de mettre
cette structure en avant et de deleguer la gestion en tant que conteneur au programmeur (cela
nest nalement pas si dicile).
Ce travail repose donc essentiellement sur la possibilite de creer des entites telles que Nud,
Lien, Port ou Mod`ele de graphe, en leur attribuant un identiant unique, qui peut servir de cle
dans des conteneurs externes.
Aujourdhui, lidentiant est donne par ladresse memoire de lentite. Ce choix est critiquable
dans certains cadres bien precis. Il est cependant parfaitement encapsule et transparent vis-`a-vis
de son utilisation.
b
a
s
e
/
i
m
p
l
3.1 Les classes de structures
3.1.1 La classe GraphStruct
Cette classe g`ere la notion centrale de graphe elementaire. Elle permet la creation/suppression
des trois entites Nud, Lien et Port.
Linterface de programmation pour la creation et la manipulation est evidente :
NodeId GraphStruct::CreateNode();
NodeId GraphStruct::AddNode(NodeId);
PortId GraphStruct::CreatePort(NodeId = 0);
LinkId GraphStruct::CreateLink(PortId, PortId, bool removeOldLinks = true);
LinkId GraphStruct::CreateLink(NodeId, NodeId);
void GraphStruct::RemoveNode(NodeId, bool withOtherPorts = false);
void GraphStruct::RemovePort(PortId, bool withOtherPort = false);
void GraphStruct::RemoveLink(LinkId, bool withPorts = false);
Signalons que la methode AddNode prend exclusivement un NodeId fraichement cree.
Copyright c 2003 Soluscience 17
CHAPITRE 3. IMPL

EMENTATION
Les booleens removeOldLinks et with... permettent de controler la suppression des entites
attenantes. Par exemple, la suppression dun port peut etre accompagnee ou non de celle du lien
et du port eventuellement adjacents.
Quelques methodes supplementaires permettent de controler la qualite dorientation du
graphe. Cette derni`ere sera interpretee par dautres classes comme les parcours de graphes.
void GraphStruct::SetDirected(bool d =true);
bool GraphStruct:: IsDirected(void) const;
Un certains nombres diterateurs standards ont ete mis en place, nous nindiquons ici que la
methode ...begin. Les autres sont peuvent etre deduites.
GraphStruct:: node_iterator GraphStruct::nodes_begin(void);
GraphStruct::const_node_iterator GraphStruct::nodes_begin(void) const;
GraphStruct:: port_iterator GraphStruct::ports_begin(void);
GraphStruct::const_port_iterator GraphStruct::ports_begin(void) const;
GraphStruct:: link_iterator GraphStruct::links_begin(void);
GraphStruct::const_link_iterator GraphStruct::links_begin(void) const;
Enn, nous trouvons quelques methodes dacc`es `a dierentes proprietes du graphe :
int GraphStruct::nodes_number(void ) const;
int GraphStruct::ports_number(void ) const;
int GraphStruct::ports_number(NodeId n) const;
int GraphStruct::links_number(void ) const;
En tant que pointeur les dierents identiants dentites permettent dacceder `a ces entites.
Linterface de programmation evoluera probablement leg`erement si le choix des pointeurs est
remis en question :
NodeId Node::opposite(const LinkId) const;
NodeId Port::node;
LinkId Port::link;
PortId Link::first;
PortId Link::second;
NodeId Link::source(void) const;
NodeId Link::target(void) const;
3.1.2 Les sous-graphes
Nous avons deni une class abstraite au sens de Barton et Nackman permettant de manipuler
la notion de sous-graphe. Labstraction est poss`ede la meme interface que GraphStruct et sera
comprise par les classes de parcours qui seront denies plus loin.
Le sous-graphe se denit comme un sous-ensemble de nuds et/ou de liens et ou de ports
dun graphe complet. Les classes concr`etes apportent une methode attestant de lappartenance
de ces entites au sous-graphes :
18 Copyright c 2003 Soluscience
bool SubG::ValidNode(NodeId n) const;
bool SubG::ValidPort(PortId n) const;
bool SubG::ValidLink(LinkId n) const;
Nous fournissons dej`a deux classes de sous-graphes, le sous-graphe complet, FullSubGraphStruct,
o` u les validateurs renvoient toujours true, et un sous-graphe qui sappuie sur les map de la STL,
MapSubGraphStruct :
GraphStruct graph;
NodeId n1 = graph.CreateNode();
NodeId n2 = graph.CreateNode();
LinkId l = graph.CreateLink(n1,n2);
...
MapSubGraphStruct subGraph(graph);
subGraph.include_Node[n1] = true;
subGraph.include_Node[n2] = false;
...
Si une entite nest pas incluse dans les include ..., le sous-graphe suppose par defaut quelle
ne lui appartient pas.
3.1.3 Les graphes hierarchiques
Un graphe hierarchique est beaucoup plus complexe `a mettre en place. La diculte essentielle
vient du fait que ce nest pas `a proprement parler un graphe, mais une collection de mod`eles
de graphe. Rigoureusement un graphe hierarchique est la donnee de cette collection et dun des
mod`eles devant etre instantie.
Nous avons donc deux classes dierentes, HierarchicalGraphStruct et GraphModel. La
premi`ere g`ere la liste de mod`eles que constituent les objets de la classe suivante.
Linterface de programmation de la premi`ere est simple :
ModelId HierarchicalGraphStruct:: CreateModel();
ModelId HierarchicalGraphStruct:: AddModel(ModelId);
ModelId HierarchicalGraphStruct::CreateSubModel(ModelId p, const set<NodeId>& s);
void HierarchicalGraphStruct:: RemoveModel(ModelId);
La methode CreateSubModel permet de creer un nouveau mod`ele (celui retourne), `a partir
duquel on instantiera un nud qui remplacera un ensemble de nuds s du mod`ele parent p.
On y a ajoute les methodes traditionnelles :
int HierarchicalGraphStruct::models_number(void);
model_iterator HierarchicalGraphStruct::models_begin(void);
const_model_iterator HierarchicalGraphStruct::models_begin(void) const;
...
La seconde est plus etoee, puisquun mod`ele de graphe est un graphe dont les nuds peuvent
faire reference `a un autre mod`ele.
Copyright c 2003 Soluscience 19
CHAPITRE 3. IMPL

EMENTATION
class GraphModel : public GraphStruct {
NodeId CreateNode();
NodeId CreateNode(ModelId);
PortId CreatePort(NodeId =0, bool pseudo =false);
LinkId CreateLink(PortId, PortId);
ModelId GetModel(NodeId);
void SetModel(NodeId, ModelId);
void SetModel(NodeId, ModelId, const PortTranslator&);
void SetModel(NodeId, ModelId, set<PortId>&, bool withOtherPort = false);
void SetModel(NodeId, ModelId, const PortTranslator&,
set<PortId>&, bool withOtherPort = false);
NodeId SetAsSubModel(ModelId parent, const set<NodeId>&);
PortId GetFreePort(PortId localId);
PortId GetLocalFreePort(NodeId localId, PortId internalId);
};
Les deux premi`eres methodes permettent la creation de nuds simple ou selon un mod`ele.
Les dierentes methodes SetModel permettent de changer ou denlever le mod`ele dun nud.
La diculte de cette operation vient du traitement de la liasion entre les ports locaux et les ports
internes dun nud instantie selon un mod`ele.
`
A Completer...
La methode SetAsSubModel est appelee par HierarchicalGraphStruct::CreateSubModel.
Son interface publique pourra etre remise en cause.
Dans le cas dun nud instantie selon un mod`ele, ses ports seront en relation directe avec les
ports libres (ie sans nud) du mod`ele en question. Un mod`ele pouvant etre instantie plusieurs
fois, on comprend alors que le nom du port libre dans le mod`ele instantie ne peut etre le meme que
celui des ports correspondants dans le mod`ele instantiant. Les derni`eres methodes permettent
de passer dun syst`eme de nommage `a un autre.
La declaration exacte des classes HierarchicalGraphStruct et GraphModel est en fait beau-
coup plus compliquee. Elles ne seront jamais utilisees directement, mais au travers de classes
derivees. Un premier couple de classes, qui ne fait rien de plus, que ce qui a ete dej`a decrit,
a ete renomme DefaultHierarchicalGraph et DefaultGraphModel. Un deuxi`eme permet la
gestion des dependances quil peut y avoir entre les dierents mod`eles, HierarchicalGraphLib
et GraphModelOfLib. Sans rien imposer sur ces contraintes, le HierarchicalGraphLib enre-
gistre au fur et `a mesure le fait quun mod`ele en utilise un autre et lui est donc necessaire
pour etre instantie. En fait, HierarchicalGraphLib est un GraphStruct, dont les nuds sont
les GraphModelOfLib et les liens ces relations de dependances. Un simple tri topologique de ce
graphe permet alors de savoir si lon peut ou non (( mettre `a plat )) tous les mod`eles du graphe
hierarchique.
Linterface de programmation est encore susceptible de bouger, mais devrait ressembler `a
ceci :
20 Copyright c 2003 Soluscience
1 ...
2 lib.UpdateOrder();
3 if (lib.topologicalOrder.is_acyclic()) {
4 ...
5 TopSort::const_iterator mi = lib.topologicalOrder.begin();
6 while ( mi != lib.topologicalOrder.end()) {
7 ... // (*mi) is a model
8 ++mi;
9 }
10 }
b
a
s
e
/
i
m
p
l
3.2 Les mille et un parcours dun graphe
Contrairement `a une structure sequentielle, le graphe ne poss`ede pas de notion de parcours
qui soit evidente. Sans meme se creuser les meninges, on trouve facilement dix facons tout aussi
naturelles les unes que les autres de le parcourir :
la liste de ses nuds
la liste de ses liens
la liste de ses ports
la liste des liens attaches (directement ou non) `a un nud
la liste des nuds adjacents `a un autre
la liste des nuds simplement connexes `a un autre.
. . .
3.2.1 Interface de programmation
Il etait donc necessaire de positionner correctement linterface de programmation dans ce
cadre. La principale contrainte etant de laisser susamment de place `a la creation des mille et
une autres facons de le parcourir que nous navons pas imaginees encore.
Dans la STL, la notion de parcours passe par celle diterateurs, qui sont des indicateurs de
position dans un parcours.

Etant etroitement lies, le conteneur et son parcours sont alors tr`es
souvent confondus. Les methodes begin() et end() sont par exemple les deux methodes essen-
tielles dun parcours ni. La presence de deux parcours distincts dans un conteneur bidirectionnel
comme un vecteur se traduit par la duplication de ces methodes (rbegin() et rend()).
Il nest evidemment pas question dans le cas des graphes, de proceder entre autre `a cette
multiplication des methodes de delimitation, `a chaque nouveau parcours imagine. Nous avons
donc proposer des classes supplementaires, chacune exprimant une facon de parcourir un graphe.
La creation de nouveaux parcours est extremement simple et les appels aux methodes begin()
et end() sont parfaitement lisibles.
`
A premi`ere vue, la syntaxe parait un peu plus lourde que celle de la STL, elle correspond
aussi `a une necessite dexpression beaucoup plus riche.
1 ...
2 AllNodesPath<GraphStruct> allnodes(graph);
3 AllNodesPath<GraphStruct>::const_iterator ni = allnodes.begin();
4 for (; ni!=allnodes.end(); ++ni)
5 NodeId n = *ni;
Nous ferons une petite remarque, `a loccasion, sur la ligne 5 et loperateur dincrementation
de ni. On a lhabitude decrire par defaut une simple incrementation en utilisant loperateur
Copyright c 2003 Soluscience 21
postxe. Cest probablement par conformisme avec lappellation meme du C++. Il sagit bien l`a
dune mauvaise habitude, comme souvent peut letre le conformisme. En eet loperateur prexe
et postxe ne sont pas du tout equivalents.
Le premier incremente une valeur et renvoie une reference sur cette valeur. Le deuxi`eme
cree une copie de la valeur quil renverra plus tard et incremente la valeur. On limplemente
traditionnellement comme ci-dessous :
1 T& T::operator++() {
2 ...
3 return *this;
4 }
5 // operateur postfixe : attention `a la syntaxe
6 T T::operator++(int) {
7 T tmp = *this;
8 operator++();
9 return tmp;
10 }
On voit que loperateur postxe nest pas du tout aussi anodin que son cousin prexe.
3.2.2 Quelques parcours predenis
AllNodesPath<GraphStruct> nodes(graph);
AllPortsPath<GraphStruct> ports(graph);
AllLinksPath<GraphStruct> links(graph);
ExternalPortsPath<GraphStruct> freeports(graph);
CompletedLinksPath<GraphStruct> fulllinks(graph);
PortsOfNodePath<GraphStruct> nports(graph,node);
LinksOfNodePath<GraphStruct> adjacent_links(graph,node);
DirectLinksOfNodePath<GraphStruct> from_links(graph,node);
IndirectLinksOfNodePath<GraphStruct> to_links(graph,node);
NodesOfNodePath<GraphStruct> adjacent_nodes(graph,node);
DirectNodesOfNodePath<GraphStruct> next_nodes(graph,node);
IndirectNodesOfNodePath<GraphStruct> precious_nodes(graph,node);
b
a
s
e
/
i
m
p
l
3.3 Utilisation
Deuxi`eme partie
Algorithmie
Copyright c 2003 Soluscience 23
Chapitre 4
Denitions et proprietes des graphes
a
l
g
o
/
i
n
t
r
o
4.1 Algorithmes de parcours
Parcourir un graphe consiste `a choisir un sommet et `a enumerer `a partir de celui-ci ses somets
en suivant arcs ses autant que possible. Le choix de larc et du nud `a visiter en priorite est
deni au prealable par le type de parcours (profondeur, largeur, etc.)
4.1.1 Le parcours en largeur (BFS : Breadth First Search)
a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre
Fig. 4.1 Graphe `a parcourir
Le parcours en largeur consiste `a parcourir les noeuds du graphe en commencant toujours
par les plus proches du point de depart.
Pour cela, on utilise un le, dans laquelle on met des aretes `a visiter. Ces aretes sont des
couples de noeuds, (d, a) tels que d et a soient voisins, d a dej`a ete enti`erement traite et pas
a. Au depart, cette le ne contient que le noeud de depart (d, d). Lalgorithme est alors le
suivant : on enl`eve la premi`ere arete (d, a) de la le. Si a est le point darrivee, on a ni.
Sinon, on ajoute en queue de le toutes les aretes (a, b) telles que b soit un voisin de a non
visite et on note que tous les b seront visites.
Cliquez ici pour une animation de ce parcours.
Copyright c 2003 Soluscience 25
CHAPITRE 4. D

EFINITIONS ET PROPRI

ET

ES DES GRAPHES
a
b
c
d
e
a1
b1
c1
d1
e1
a2
b2
c2
d2
e2 a3
b3 c3
d3 e3
centre a
b
c
d
e
a1
b1
c1
d1
e1
a2
b2
c2
d2
e2 a3
b3 c3
d3 e3
centre
Fig. 4.2 Premi`eres etapes
4.1.2 Le parcours en profondeur (DFS : Depth First Search)
La strategie adoptee par le parcours en profondeur est la suivante :
Pendant le parcours, on enum`ere un sommet u , puis un sommet v adjacent `a u. Le parcours
en profondeur va enumerer les sommets adjacents `a v, avant denumerer les sommets adja-
cents `a u. Comme un sommet peut avoir plusieurs sommets adjacents, il convient de xer
des relations dordre pour denir un ordre de parcours (poids aecte au sommet, etc.) Le
processus complet est acheve lorsque tous les sommets ont ete parcourus.
Passons `a un exemple an de mieux saisir le fonctionnement de cet algorithme.
Illustration
Voici le graphe `a parcourir, que lon appellera G.
On choisit (arbitrairement) de parcourir G `a partir du sommet centre. Pour que lalgorithme
puisse prendre une decision que lon controlera, il faut denir une relation dordre entre les
sommets. On dira donc quil parcoura en priorite les nuds de type a, puis b, ..., d, puis si
cela nest pas susant quil parcoura dabord a, puis a1,...a3. Cela devrait sure pour notre
parcours.
Voici les premi`eres etapes du parcours
Le fonctionnement est tr`es simple, en partant du nud centre lalgorithme parcourt succes-
sivement les sommets a, b, d1, a1, en respectant les relations dordre citees plus haut.
Le parcours se poursuit jusqu`a lexploration du nud a2. On rencontre ici un nouveau type
de probl`eme. Le sommet suivant est, en respectant les r`egles, b2. On se trouve alors bloque, sur
une feuille de larbre de parcours. Le fonctionnement ici consiste `a remonter la pile des nuds
visites, pour trouver des nuds non visites.
Ici, la pile des sommets visites est (en commencant par la tete) b2, a2, c2, b1, etc.. Or, a2
poss`ede des nuds adjacents non visites. Le parcours reprend donc `a partir de a2
On distinguera deux notions :
La decouverte : la decouverte est la date `a laquelle la parcours passe pour la premi`ere fois
par le nud.
26 Copyright c 2003 Soluscience
a
b
c
d
e
a1
b1
c1
d1
e1
a2
b2
c2
d2
e2 a3
b3 c3
d3 e3
centre a
b
c
d
e
a1
b1
c1
d1
e1
a2
b2
c2
d2
e2 a3
b3 c3
d3 e3
centre
a
b
c
d
e
a1
b1
c1
d1
e1
a2
b2
c2
d2
e2 a3
b3 c3
d3 e3
centre
Fig. 4.3 Etapes suivantes
La n de traitement : la n de traitement est la date `a laquelle on observe plus aucun
nud adjacent libre pour un sommet.
Cliquez ici pour une animation de ce parcours.
Copyright c 2003 Soluscience 27
CHAPITRE 4. D

EFINITIONS ET PROPRI

ET

ES DES GRAPHES
a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre
Fig. 4.4: Le graphe que lon va parcourir
a
l
g
o
/
d
f
s
4.2 Les applications
4.2.1 Premier cas dapplication du DFS : le tri topologique
Le tri topologique dun graphe oriente acyclique consiste `a ordonner lineairement tous ses
sommets de sorte que sil contient un arc (u, v), u apparaisse avant v. Si le graphe nest pas
acyclique, aucun ordre lineaire nest possible.
Schematiquement, on pourrait dire que le tri topologique dun graphe est lalignement de ses
sommets, sur un axe horizontal, de mani`ere `a ce que tout ses arcs soient orientes de la droite vers
la gauche. (Ceci nest bien evidemment quune representation schematique et pas une denition
formelle).
Le fonctionnement du tri topologique se base sur le parcours en profondeur. On veut, `a la
n du tri, obtenir une liste chanee L des nuds `a parcourir. On appelle donc le parcours en
profondeur.
A chaque fois que le traitement dun nud sach`eve, on ins`ere ce nud en tete de liste.
Un exemple basique est celui de lordonancement de taches. Considerons lelaboration dune
recette de cuisine, les lasagnes . (La recette est livree telle quelle sans garantie de reussite).
On xera arbitrairement le debut du parcours `a Allumage du four.
28 Copyright c 2003 Soluscience
a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre
a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre
Fig. 4.5: Premi`eres etapes
Carottes
Oignons
Viande
Tomates
Sel et poivre
Beurrer le plat
Beurre
Farine
Lait
Assembler le tout
Allumer le four
Avoir un four chaud
Enfourner
A partir de sommet Allumer le four on arrive nalement sur
Enfourner, qui se retrouve en tete de liste. (pour alleger la notation,
on ne montrera pas les sommets adjacents dans la liste)
L = {Enfourner}
Le parcours se poursuit ainsi jusqu`a letat :
L = {Enfourner, Avoir un four a bonne temperature, Allumer le four}
On poursuit ainsi, tr`es simplement, le parcours en profondeur. Letat
nal de la liste L est represente ci-contre.
Cet exemple a ses limites : sil a le merite dexposer bri`evement le fonc-
tionnement de lalgorithme, ainsi quune application du DFS, il reste
assez naf dans la mesure o` u les relations dordre entre les dierentes
phases sont assez oues.
Copyright c 2003 Soluscience 29
CHAPITRE 4. D

EFINITIONS ET PROPRI

ET

ES DES GRAPHES
a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre
a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre a
b
c
d
e
d1
a1
b1
c1 e1
c2
a2
b2
d2
e2
b3
a3
c3
d3 e3
centre
Fig. 4.6: Premi`eres etapes
4.2.2 Le deuxi`eme cas dapplication du DFS : la biconnexite
Voici le graphe G que lon va
etudier :
F
B
E
C
D
A
G
I
H
Le graphe G
On appelle composante biconnexe dun
graphe G un ensemble maximal daretes tel
que deux aretes quelconques de lensemble se
trouvent dans le meme cycle elementaire
a
. On
appelera point (resp. arete) darticulation
dun graphe connexe tout nud (resp. arete)
dont la suppression rend le graphe non connexe.
a
Un cycle est dit elementaire si tous les sommets sont
distincts
30 Copyright c 2003 Soluscience
Assembler le tout
Enfourner
Beurre
Farine
Lait Beurrer le plat Sel et Poivre
Concentr de tomates
Oignons
Viande
Carottes
Allumer le four
Avoir un four bonne temprature
Fig. 4.7: Le graphe H
E
B
C
A
F
D
H
G
I
Arbre obtenu en appellant le DFS `a
partir du sommet F
Le DFS sur un graphe connexe produit un arbre
dont les arcs appartiennent au graphe. On les
representera en trait plein. Les arcs de G res-
tant seront representes en trait pointille. Les as-
sertions suivantes seront admises, mais elles sont
facilement demontrables.
Si la racine de larbre a plus dun descendant,
alors la racine est un point darticulation.
On appelle donc le DFS `a partir de chaque
nud, et on verie que ce nud a plus dun
descendant. Cest un algorithme tr`es gourmand
en ressources. Neanmoins elle a le merite
dexposer aisement les possibilites oertes par
le DFS
Les composantes biconnexes de G ont ete mises en couleur :
Copyright c 2003 Soluscience 31
F
B
E
C
D
A
G
I
H
Fig. 4.8: Coloration des composantes biconnexes de G
3
4
5
7 9
1
2
6 8
G1 G2 G3
Fig. 4.9: Le graphe G
4.2.3 Le troisi`eme cas dapplication du DFS : les composantes connexes
On appelle composante connexe dun graphe G un sous graphe connexe maximal.
En image, la denition prend tout son sens :
On remarque les trois composantes connexes du graphe G, `a savoir S
G
1 = {1, 2, 3}, S
G
2 =
{4, 5, 6, 7} et S
G
3 = {8, 9}.
Lors de lutilisation de lalgorithme, il faut bien veiller `a parcourir la totalite du graphe,
sous peine de parcourir une seule composante connexe. On appellera le DFS `a partir dun nud
quelconque u de G. Lorsque le traitement du nud u est termine, on peut faire face `a deux
situations :
La liste des nuds de G non visites est vide : le DFS a parcouru tous les nuds. On a
decouvert toutes les composantes connexes.
La liste des nuds de G non visites est non vide : on appelle le DFS `a partir dun nud
v non visite, pour parcourir une nouvelle composante connexe.
Troisi`eme partie
Geometrie 3D des structures
relationnelles
Copyright c 2003 Soluscience 33
Chapitre 5
Attributs dun graphe 3D
Nous allons maintenant denir un graphe 3D, en decorant les dierents elements denissant
un graphe hierarchique, avec un certain nombre dattributs geometriques.
g
e
o
m
e
t
r
y
/
a
t
t
r
i
b
u
t
5.1 Les mod`eles nodaux
Ils sont supposes ponctuels. On najoutera donc simplement lorientation geometrique Q(p)
de chaque port externe. Celle-ci peut etre denie par un deplacement euclidien de lespace,
cest-`a-dire par une rotation.
La direction de la future liaison est donnee par limage de Oz par cette rotation. Limage
de Ox par la rotation est donnee comme reference pour evaluer langle de torsion autour de la
futur liaison.
Remarque : on utilisera souvent les quaternions pour representer numeriquement une ro-
tation.
g
e
o
m
e
t
r
y
/
a
t
t
r
i
b
u
t
5.2 Les mod`eles composites
Seules les liaisons de type instantiation instantiation poss`ederont une information geometrique
initiale.
Une liaison est denie par la donnee de sa longueur () et dun angle de torsion ()
autour de cette derni`ere. On calcule ainsi le deplacement oriente du port origine vers le port
extremite :
D
0
() = T(Oz, ()).R(Ox, ).R(Oz, ())
Toutes les autres donnees seront supposees calculees et/ou evaluables sur la donnee de la
position et de lorientation de lune des instantiation. Lorientation et la position dun port
externe sont, par exemple, les memes que celles du port issu de linstantiation auquel le port
externe se rattache.
g
e
o
m
e
t
r
y
/
a
t
t
r
i
b
u
t
5.3 Attributs auxiliaires
On note D
/i
(p), le deplacement ane tel que limage du point nul represente la position dans
le mod`ele M
m(i)
du port externe p. La partie vectorielle identiant son orientation.
On note D(i), le deplacement ane identiant la position et lorientation de g
0
(i) dans le
mod`ele M
0
.
Copyright c 2003 Soluscience 35
CHAPITRE 5. ATTRIBUTS DUN GRAPHE 3D
On note enn D(), le deplacement eectif entre les deux extremites p
1
de g
0
(i
1
) et p
2
de
g
0
(i
2
). On a la relation evidente :
D() = (D(i
1
).D
/i
1
(p
1
))
1
.D(i
2
).D
/i
2
(p
2
)
36 Copyright c 2003 Soluscience
Chapitre 6
Resolution geometrique de graphes
3D
g
e
o
m
e
t
r
y
/
o
p
t
i
m
a
l
6.1 Mode operatoire
Il sagit devaluer les attributs geometriques auxiliaires dun graphe hierarchique. Connaissant
par denition tous les attributs des mod`eles elementaires, nous pouvons denir une procedure
de calcul des attributs dun mod`ele composite M
0
, `a partir des attributs des mod`eles dont il
depend.
Sont donc consideres comme donnes, tous les deplacements D
/i
(p) des ports, dits internes,
et les deplacements voulus D
0
().
Les variables sont les deplacements D(i) de chaque instantiation.
Remarques :
Les D(i) sont denis `a un deplacement global pr`es.
Il existe une methode de calcul direct et exacte des D(i) dans le cas dun graphe connexe
sans cycle.
Les deplacements D
0
() ne permettent pas de determiner compl`etement ou de facon ro-
buste tous les D(i), en presence de cycles ou de composantes connexes multiples.
g
e
o
m
e
t
r
y
/
o
p
t
i
m
a
l
6.2 Formulation directe
g
e
o
m
e
t
r
y
/
o
p
t
i
m
a
l
6.3 Formulation optimale
Notons D une distance denie sur lespace des deplacements anes. Nous pouvons donc
poser le probl`eme optimal sur les variables D(i) :
_
min
/D(i)

D
_
D
0
(), D()
_
D(i = 0) = Id
(6.1)
Nous denissons un deplacement D comme un couple (Q, T) dune rotation et dune trans-
lation telles que D = Q.T. IL sagit pour les trois termes, dapplications anes de lespace. On
note q et t le quaternion et le vecteur translation associes. On note aussi [q] et [t] les operateurs
matriciels anes. On prendra garde aux multiples produits en presence, notamment le produit
non commutatif deni sur le corps des quaternions.
On denit les normes et Q =

et T =

, par :
Q

(D
0
(), D()) = 1
_

_
q.q
0
__
2
Copyright c 2003 Soluscience 37
CHAPITRE 6. R

ESOLUTION G

EOM

ETRIQUE DE GRAPHES 3D
T

(D
0
(), D()) =
_
_
_t t
0
_
_
_
2
La forme particuli`ere de Q

vient du calcul de la somme sur les vecteurs de base e


i
:
Q

=

e
i
_
_
_
_
q.q
0
_
.e
i
e
i
_
_
_
2
Comme attendu, cette distance ne distingue pas q et q qui identie la meme rotation.
Nous ne resoudrons pas exactement le probl`eme 6.1, mais un probl`eme approche, o` u lon cal-
cule dabord les orientations minimisant Q, puis les translations (qui dependent de la premi`ere
etape) minimisant T . Dans la mesure, o` u lon met en place ce procede uniquement dans un cadre
destine `a corriger des imprecisions sur les donnees de depart, cette approche est largement satis-
faisante. Dautant que la mise en place dune distance globale D induit de nombreux probl`emes
techniques de normalisation des dierents termes (optimisation multi-crit`eres).
Reste `a etablir les expressions de q() et de t() en fonction de q(i), t(i), q
/i
(p) et t
/i
(p). On
notera que [q]
1
= [q], que [t]
1
= [t] et donc que (q, t)
1
= (q, [q] .t).
q() = q
/i
1
.q(i
1
).q(i
2
).q
/i
2
(6.2)
t() =
_
q
/i
1
_
.
_
t
/i
1
+ [q(i
1
)] .
_
t(i
1
) +t(i
2
) + [q(i
2
)] .t
/i
2
__
(6.3)
6.3.1 Calcul des orientations
La premi`ere etape de la resolution est en fait un probl`eme doptimisation sous contraintes.
En eet, on doit avoir `a lesprit que les quaternions doivent rester normalises (qq = 1). On
introduit donc les coecients de Lagrange n(i) et on denit la nouvelle fonctionnelle :

q
(q(i), n(i)) =

+

i
n(i). (q(i).q(i) 1)
La condition de stationnarite de
q
en n(i) equivaut au respect de la normalisation de q(i). Il
ne reste qu`a evaluer les derivees de
q
par rapport `a q(i). Nous ferons pour cela une hypoth`ese
importante `a retenir par la suite :
Hypoth`ese : Quel que soit , i
1
() et i
2
() sont dierents. Cest `a dire que lon ne peut
relier deux ports dune meme instantiation.
On notera I
q
le tenseur dordre 2 issu de la derivation
q(i)
q(i)
.

q(i
1
)
q() = q
/i
2
.q(i
2
). I
q
.q
/i
1

q(i
2
)
q() = q
/i
2
. I
q
.q(i
1
).q
/i
1
1
2

q(i
1
)
Q

=
_
q
/i
1
. I
q
.q(i
2
).q
/i
2
.q
0
_
(6.4)
1
2

q(i
2
)
Q

=
_
q
0
.q
/i
2
. I
q
.q(i
1
).q
/i
1
_
(6.5)
1
2

q(i)

n(i

).
_
q(i

).q(i

) 1
_
= n(i).q(i) (6.6)
38 Copyright c 2003 Soluscience
6.3.2 Calcul des translations
La seconde etape est beaucoup plus classique. On notera I
t
le tenseur dordre 2 issu de la
derivation
t(i)
t(i)
.

t(i
1
)
t() =
_
q
/i
1
.q(i
1
)
_
I
t

t(i
2
)
t() =

t(i
1
)
t()
1
2

t(i
1
)
T

=
_
q(i
1
).q
/i
1
_ _
t() t
0
()
_
= [q(i
1
)] .t
/i
1
+t(i
1
) t(i
2
) [q(i
2
)] .t
/i
2
+
_
q(i
1
).q
/i
1
_
t
0
() (6.7)
1
2

t(i
2
)
T

=
1
2

t(i
1
)
T

(6.8)
Copyright c 2003 Soluscience 39
CHAPITRE 6. R

ESOLUTION G

EOM

ETRIQUE DE GRAPHES 3D
40 Copyright c 2003 Soluscience
Chapitre 7
Implementation et utilisation
g
e
o
m
e
t
r
y
/
i
m
p
l
7.1 Cas simple
g
e
o
m
e
t
r
y
/
i
m
p
l
7.2 Cas hierarchique
Copyright c 2003 Soluscience 41
Quatri`eme partie
Interfaces utilisateur
Copyright c 2003 Soluscience 43
Chapitre 8
Presentation de lediteur de graphe
Plusieurs widgets ont ete construits pour permettre la representation de syst`emes de graphes.
Il sagit en fait de presenter une librairie souple qui permette `a tous types dutilisateurs de se
servir dun outil de representation de graphes adapte `a ses propres besoins.
Ces interfaces graphiques fonctionnent avec la librairie de graphes fournie dans lensemble
SoluTK2 mais elle est independante dans le sens o` u une autre librairie de graphes peut etre
representee.
Plusieurs groupes de composants interviennent dans cette librairie :
Les interfaces graphiques de representations.
Les interfaces de donnees.
Les donnees.
Cette decomposition est calquee sur le mod`ele de la librairie Phenix qui a inspire ce travail.
g
u
i
/
e
d
i
t
o
r
2
d
8.1 Interfaces graphiques
Quatre widgets composent cette librairie :
Graph est lediteur de graphe proprement dit. Il permet de creer une fenetre seule o` u les dierents
composants du graphe (noeuds, ports, liens) peuvent etre implementes dans un espace de
travail qui nest quune partie de la zone dimplementation du graphe.
GraphScroll est compose de lediteur precedent, dascenseurs pour faire deler la zone de travail
et dune roulette pour manipuler le zoom de lediteur.
LayerManager est un outil qui permet de manipuler un syst`eme de calques. Le calque est une
profondeur de representation de dierents composants. On peut modier la profondeur des
calques et leur visibilite. Les dierents composants du graphe se trouvent sur des calques.
GraphEditor est un ensemble complexe permettant de visionner plusieurs parties du graphe
simultanement. Il permet en fait de representer des widgets de type GraphScroll (10 au
maximum) en decoupant une fenetre de travail soit horizontalement soit verticalement.
Ce widget poss`ede egalement un gestionnaire de calques et une barre de titre qui permet
la navigation dans un graphe hierarchique. Cette barre donne acc`es `a des sous menus qui
orent des fonctionnalites de representation.
g
u
i
/
e
d
i
t
o
r
2
d
8.2 Interface de donnees
Une interface de donnees permet `a linterface graphique de communiquer avec une donnee
de graphe et une donnee associee de positionnement des dierents composants (rectangle pour
Copyright c 2003 Soluscience 45
CHAPITRE 8. PR

ESENTATION DE L

EDITEUR DE GRAPHE
les noeuds et les ports, vecteur de points pour les liens). Le concept de base est dacceder et de
modier les donnees via des cles qui sont du type void* qui identie les noeuds, les ports et les
liens et les donnees associees.
Elle est composee dune classe, VManagerGraph possedant un grand nombre de methodes.
On en distingue trois types :
Les methodes virtuelles dobtention dinformations soit de graphe, soit de positionnement.
Les methodes normales de modication dinformations. Ce sont celles quil faut appeler si
lon veut manipuler la donnee sans linterface. Elle g`ere lappel `a des fonctions de modi-
cations mais aussi des methodes denrobage dune modication :
le stockage de la modication dans une structure adaptee
stockage temporaire dune modication et compilation de modication dans une liste de
modications dej`a realisee.
Les methodes virtuelles de modications dinformations. Ce sont celles qui sont appelees
par les methodes prececentes. Elles portent le meme nom, sauf que chaque nom commence
par un V comme Virtual. Ces methodes doivent etre redenies dans les classes derivees
mais elles ne sont pas appelees directement.
Lorsque la donnee est modiee, un compte rendu de modication doit etre rempli. Ce
compte rendu doit reeter exactement ce que le programmeur a fait sur la donnee lors
dune modication.
Ce compte rendu est stocke dans une classe VMModif qui ore tous les champs necessaires
pour en rendre compte. Cette technique ore une liberte totale aux utilisateurs pour faire
ce quils desirent lors dune modication de donnees.
Par dessus la librairie de graphe exposee precedemment, une interface derivee, VManagerGraphTest,
a ete developpee. On introduit `a ce niveau, un objet particulier, le manipulateur de donnees qui
est utilise pour les methodes qui permettent une modication de donnees. Cette astuce permet
dimplementer rapidement des comportements dierents lors de la modication de la donnee.
De plus, cela isole les methodes de modications, des methodes dobtention de linformation.
Une classe de base est fournie, DGManip et une classe derivee utilisant la structure de graphe
exposee precedemment a ete implementee du nom de DGManipTest. Cette derni`ere classe ore
un comportement trivial de base qui peut etre reutilise pour des manipulations un peu plus
complexe.
g
u
i
/
e
d
i
t
o
r
2
d
8.3 Donnees
Deux types de donnees sont geres par linterface precedente :
Les donnees de graphes. Elles doivent se caracteriser par la fourniture de cles qui sont des
identiants uniques des noeuds, des ports, des liens et des mod`eles de graphes pour les
graphes hierarchiques.
On implemente la classe GraphModelV qui se comporte comme la classe GraphModel*.
Les donnees de positionnement qui fournissent les rectangles pour les noeuds et les ports,
les vecteurs de points pour les liens. Pour chacun des composants, on peut recuperer une
chane de caract`eres.
Pour les noeuds, on peut fournir une sc`ene vectorielle qui permet de dessiner le noeud dun
mani`ere particuli`ere, un objet de la classe Scene2D. Une transformation geometrique peut
egalement etre associee. Cela permet dacher des noeuds du meme type dun mani`ere
dierente. Si ces objets nexistent pas, les noeuds seront dessines sous la forme dun carre
jaune.
Pour les ports, il est possible de fournir une direction de sortie privilegiee. Cette direction
46 Copyright c 2003 Soluscience
peut etre utilisee pour forcer un lien `a sortir suivant une direction precise lors de la creation
dun lien.
Une classe particuli`ere, DataLayout a ete implementee. Il sagit grosso modo dune map
entre les cles et les donnees de positionnement.
Aux cles de noeuds, de ports et de liens on peut associer autant de types de donnees que
lutilisateur le souhaite. Linterface ne les utilisera `a priori pas, mais il est toutefois possible
dinteragir avec elles grace aux manipulateurs de donnees derivees qui peuvent tenir compte de
ces donnees annexes lors de la manipulation de donnees.
La gure 8.1 presente cette organisation generale.
GUI
Structure de Graphe
VManagerGraphTest
VManagerGraph
DGManip
DGManipTest Autre Manipulateur
Lien
Port
Noeud
Infos
Geometriques
Modele
Autres Infos
Autre Manager
Fig. 8.1: Organisation de linterface de donnee et des donnees
g
u
i
/
e
d
i
t
o
r
2
d
8.4 Exemple dutilisation
La creation de graphe est realisable de la mani`ere suivante :
Pour ajouter un noeud, il sut de cliquer avec le bouton gauche sur lespace de travail.
Pour ajouter un port rattacher `a un noeud, cliquer avec le bouton droit sur le-dit noeud.
Pour ajouter un port libre, cliquer avec le bouton droit sur lespace de travail.
Pour ajouter un lien, cliquer avec le bouton gauche sur un port (libre ou non) qui sera
donc le port de debut du lien, puis sur un second port (libre ou non) qui sera donc le port
de n du lien.
Il est possible de modier manuellement lagencement et lapparence dun graphe.
Pour deplacer un noeud ou un port (libre ou non), si cela est autorise, cliquer en son sein
et eectuer un dragging vers lemplacement desire.
Pour retailler un noeud ou un port (libre ou non), si cela est autorise, cliquer pr`es du bord
ou du coin `a retailler et eectuer un dragging jusqu`a obtenir la taille desiree. Il est `a noter
que ces objets ont une taille minimale.
Pour ajouter un point de controle `a un lien, si cela est autorise, cliquer sur le segment
voulu et eectuer un dragging jusqu`a lobtention du point desire.
Pour deplacer un point de controle dun lien, si cela est autorise, cliquer sur ce point et
eectuer un dragging jusqu`a lobtention du deplacement du point desire. Il est `a noter
quun point de controle situe proche du segment forme par ses points de controle precedent
et suivant sera supprime.
On peut aussi deplacer un segment entier dun lien, si cela est autorise, selon les directions
des segments precedent et suivant. Pour se faire, appuyer sur la touche Shift et eectuer
Copyright c 2003 Soluscience 47
CHAPITRE 8. PR

ESENTATION DE L

EDITEUR DE GRAPHE
un dragging du segment `a deplacer.
Pour deplacer un segment de lien sans suivre les directions des segments precedent et
suivant mais en gardant la meme taille et direction du lien, si cela est autorise, appuyer
sur la touche Ctrl et eectuer un dragging du segment.
8.4.1 Localisation de lexemple
Localisation Visual C++ : Gosb/workspace/demos/Appli.dsp
Localisation Metrowerks CodeWarrior : Gosb/project/CW xml/AppliGraph.mcp.xml
Localisation gcc : Gosb/workspace/demos/Makele
8.4.2 Code dutilisation
Ce code nest pas present tel quel dans lexemple, mais il est presente simplie pour permettre
une comprehension meilleure :
1 int w=500,h=500;
2 VManagerGraphTest* datai=new VManagerGraphTest;
3 DataLayout* datal=new DataLayout;
4 DGManipTest* manip=new DGManipTest;
5 DataStructGraph* datag=new DataStructGraph;
6
7 datai->SetData(datag,datal);
8 manip->SetLayout(datal);
9 manip->SetGraph(datag);
10 datai->SetManipulator(manip);
11 wxFrame *frame = new wxFrame(0,0,"Minimal wxWindows App",
12 wxPoint(0, 30), wxSize(w, h));
13 frame->GetClientSize(\&w,\&h);
14 frame->Show(true);
15 wxGraphEditor*view=new wxGraphEditor(frame,-1,wxPoint(0,0),wxSize(w/3,h/4));
16 view->SetData(datai);
Ligne 2 on cree une donnee dinterface de type VManagerGraphTest.
Ligne 3 on cree une donnee dachage de type DataLayout.
Ligne 4 on cree un manipulateur de graphe de type DGManipTest.
Ligne 5 on cree une donnee de structure de graphe de type DataStructGraph.
Ligne 7 `a 10 on recup`ere les dierentes donnees necessaires.
Ligne 11 et 12 on cree une fenetre pour lediteur de graphe.
Ligne 13 et 14 on xe les param`etres de la fenetre.
Ligne 15 on cree une fenetre pour lediteur de graphe.
Ligne 16 on xe la donnee `a visualiser `a linterface VManagerGraphTest.
g
u
i
/
e
d
i
t
o
r
2
d
8.5 Conclusion
Cette presentation ore un rapide tour dhorizon de cette librairie dinterface graphique.
Les chapitres qui suivent, entrent plus en details avec les dierents composants introduits, en
commencant par linterface de donnee.
48 Copyright c 2003 Soluscience
Chapitre 9
Interface de donnees
Linterface de donnees est un protocole de communication entre une interface graphique (ou
autre chose) et une donnee reelle. Il sagit le plus souvent dun cadre stricte de methodes :
informations auxquelles linterface peut acceder.
formes sous lesquelles elle va les recevoir
mani`ere de modier une information avec un format donne.
Lobjectif est de permettre `a une interface graphique de sabstraire dune donnee particuli`ere
et en fait de pouvoir representer non pas une donnee mais des donnees ayant des caracteristiques
communes avec le minimum deorts de programmation.
Ce chapitre presente linterface de donnees qui permet la communication entre lediteur de
graphes et les donnees de graphes ayant les caracteristiques suivantes :
Le graphe est constitue de noeuds, de ports et de liens que lon rep`ere via des cles (iden-
tiant unique) de type void*.
Un port peut appartenir `a un noeud ou etre libre. On peut donc obtenir le noeud dun
port (egal au pointeur 0 si le port na pas de noeud) et obtenir tous les ports dun noeud.
Un lien relie deux ports. On peut donc obtenir `a partir dune cle de lien, deux ports, le
premier etant le port de depart, le second le port darrivee. On peut egalement obtenir le
lien dun port sil existe.
Les noeuds et les ports sont reperes geographiquement par des rectangles. On peut donc
obtenir `a partir de la cle dun noeud ou dun port son rectangle respectif.
Les liens sont reperes geographiquement par des vecteurs de points qui denissent des
lignes brisees entre le debut et la n dun noeud.
Les noeuds, les ports et les liens appartiennent `a un calque qui est repere par un numero
strictement positif. Les calques permettent de denir des profondeurs de representations
et des visibilites pour un ensemble de composants.
Les noeuds, les ports et les liens poss`edent une chane de caract`eres associee.
Les noeuds poss`edent une sc`ene vectorielle associee qui est utilisee pour leur achage. Si
elle est non denie, le noeud sera represente par un carre jaune. Ce type dinformation est
rendu via la classe Scene2D de la librairie Phenix.
Les noeuds poss`edent un vecteur de deplacements qui peuvent etre appliques aux sc`enes
qui les representent.
Les ports poss`edent un point qui indique un vecteur de direction privilegiee de sortie pour
un lien en sortant.
A partir de ces caracteristiques, une classe de declaration,VManagerGraph a ete construite.
Une classe dimplementation, VManagerGraphTest basee sur la librairie de graphe introduit
Copyright c 2003 Soluscience 49
CHAPITRE 9. INTERFACE DE DONN

EES
auparavant et sur une architecture particuli`ere que lon conseille, a ete realisee orant une
veritable plateforme de developpement avec de nombreuses fonctionnalites dej`a en place tout en
laissant de larges opportunites de developpements.
g
u
i
/
i
n
t
e
r
f
a
c
e
d
o
n
n
e
e
.
t
e
x
9.1 Classe de declaration :VManagerGraph
Cette classe poss`edent deux attributions :
1. Declarer les methodes virtuelles qui seront redenies dans les classes derivees comme
VManagerGraphTest.
2. Gerer le stockage des modications et la derni`ere modication en cours dite modication
courante.
9.1.1 Methodes virtuelles de declaration
Ces methodes sont reparties en deux groupes distincts :
1. Les methodes qui permettent de recuperer de linformation. Leurs noms commencent tou-
jours par Get suivi dun nom generalement expressif. Les methodes qui permettent de
recuperer de linformation de graphe ne sont pas dissociees des methodes qui permettent
de recuperer des informations geometriques.
2. Les methodes qui permettent de modier de linformation dans les donnees. Toutes ces
methodes commencent leurs noms par VSet, V comme Virtual. L`a encore, les methodes
qui permettent de modier de linformation de graphe ne sont pas dissociees de celles qui
permettent de modier des informations geometriques.
Ces methodes doivent etre redenies dans les classes derivees dans leur totalite.
La plupart du temps, on recup`ere ou modie une information sur un composant repere par
une cle du type void*. Toutes ces methodes renvoient un argument booleen qui indique si laction
demandee a pu etre realisee. Pour linstant, aucun message derreur nest prevu pour informer
lutilisateur dun probl`eme eventuel.
9.1.2 Declaration dune modication
Lorsquune modication est realisee sur une donnee, un formulaire de modications doit etre
rempli. Cette obligation a pour interet de permettre `a nimporte quel programmeur de realiser
ce quil desire via les methodes de modications et ceci de mani`ere bien dierente des methodes
dites triviales.
Ce formulaire prend la forme dune classe du nom de VMModif qui poss`ede un grand nombre
dattributs publics qui vont par groupe :
NodesAdd, NodesAddInfo de type vector<void*>, vector<aPointer<NodeAddInfo> >representent
les cles de noeuds ajoutes et les informations geometrique et de graphe creees pour sto-
cker la modication. La classe NodeAddInfo peut etre derivee `a volonte pour stocker des
informations speciques `a chaque probl`eme rencontre.
NodesRemove NodesRemoveInfo de type vector<void*>, vector<aPointer<NodeRemoveInfo>
> representent les cles de noeuds supprimes et les informations geometrique et de graphe
creees pour stocker la modication. La classe NodeRemoveInfo peut etre derivee `a volonte
pour stocker des informations speciques `a chaque probl`eme rencontre.
50 Copyright c 2003 Soluscience
NodesModif, NodesModifInfo de type vector<void*>, vector<aPointer<NodeModifInfo>
> representent les informations de cles de ports supprimes et les informations geometrique
et de graphe creees pour stocker la modication. La classe NodeModifInfo peut etre derivee
`a volonte pour stocker des informations speciques `a chaque probl`eme rencontre.
PortsAdd, PortsAddInfo de type vector<VPortModif>, vector<aPointer<PortAddInfo>
> representent les informations de cles de ports ajoutes et les informations geometrique et
de graphe creees pour stocker la modication. La classe PortAddInfo peut etre derivee `a
volonte pour stocker des informations speciques `a chaque probl`eme rencontre.
PortsRemove, PortsRemoveInfo de type vector<VPortModif>, vector<aPointer<PortRemoveInfo>
> representent les informations de cles de ports supprimes et les informations geometrique
et de graphe creees pour stocker la modication. La classe PortRemoveInfo peut etre
derivee `a volonte pour stocker des informations speciques `a chaque probl`eme rencontre.
PortsModif, PortsModifInfo de type vector<VPortModif>, vector<aPointer<PortRemoveInfo>
> representent les informations de cles de ports modies et les informations geometrique et
de graphe creees pour stocker la modication. La classe PortModifInfo peut etre derivee
`a volonte pour stocker des informations speciques `a chaque probl`eme rencontre.
LinksAdd, LinksAddInfo de type vector<VLinkModif>, vector<aPointer<LinkAddInfo>
> representent les informations de cles de liens ajoutes et les informations geometrique et
de graphe creees pour stocker la modication. La classe LinkAddInfo peut etre derivee `a
volonte pour stocker des informations speciques `a chaque probl`eme rencontre.
LinksRemove, LinksRemoveInfo de type vector<VLinkModif>, vector<aPointer<LinkRemoveInfo>
> representent les informations de cles de liens supprimes et les informations geometrique
et de graphe creees pour stocker la modication. La classe LinkRemoveInfo peut etre
derivee `a volonte pour stocker des informations speciques `a chaque probl`eme rencontre.
LinksModif, LinksModifInfo de type vector<VLinkModif>, vector<aPointer<LinkRemoveInfo>
> representent les informations de cles de liens modies et les informations geometrique et
de graphe creees pour stocker la modication. La classe LinkModifInfo peut etre derivee
`a volonte pour stocker des informations speciques `a chaque probl`eme rencontre.
LayersAdd, LayersAddInfo de type vector<unsigned int >, vector<aPointer<LayersAdd>
> representent les informations de cles de liens ajoutes et les informations geometrique et
de graphe creees pour stocker la modication.
LayersRemove, LayersRemoveInfo de type vector<unsigned int>, vector<aPointer<LayerRemoveInfo>
> representent les informations de cles de liens supprimes et les informations geometrique
et de graphe creees pour stocker la modication.
LayersModif, LayersModifInfo de type vector<unsigned int>, vector<aPointer<LayerModifInfo>
> representent les informations de cles de liens modies et les informations geometrique
et de graphe creees pour stocker la modication.
Il faut toutefois prevenir le programmeur que des modications successives ne peuvent etre
retenues dans un seul formulaire sans generer des incoherences. Il convient donc de remplir ce
formulaire en faisant attention `a la coherence des modications.
Un formulaire est present dans chaque objet de la classe VManagerGraph que lon peut obtenir
via la methode GetModif qui le renvoie.
Copyright c 2003 Soluscience 51
CHAPITRE 9. INTERFACE DE DONN

EES
9.1.3 Stockage des modications
Les modications realisees sur la donnee sont stockees automatiquement dans une structure
de donnees adpatee `a cet eet du nom de MemoryModifGraph qui contient en fait des listes de mo-
dications primaires stockees dans une classe du nom de ModifGraph. Dans le gestionnaire, cette
operation seectue via des methodes de modications non virtuelles au nom quasi identiques
aux methodes virtuelles de modications (sans le V du debut de chaque nom de methode).
Ces modications peuvent etre recuperees via les methodes Undo et Redo de la classe MemoryModifGraph
qui renvoie les modications `a faire pour revenir sur ou refaire une operation. Il sagit dune
operation dicile mais elle a ete implementee une fois dans une classe de manipulation de la
donnee de mani`ere que lon peut qualier de denitive.
Il est possible de debrayer ce stockage automatique, via les methodes SetSilentModif et
de recuperer lexistence de ce comportement via la methode IsSilentModif. Cette action va
arreter le stockage et vider la memoire des derni`eres modications.
Il est egalement possible de debrayer temporairement ce stockage dinformations via la
methode SetTemporarySilentModif et de recuperer lexistence de ce comportement via la
methode IsTemporarySilentModif. Cette action va mettre le gestionnaire de donnees dans
le mode silencieux pour enregistrer les modications, comme dans le paragraphe precedent, `a la
dierence pr`es que le stockage des derni`eres modications nest pas eace. Cette methode est
utile pour eectuer des modications successives et de stocker la modication nale quapr`es la
serie.
Pour ce dernier type doperations, la classe VMModif est equipee pour compiler une serie de
modications en une seule via trois methodes du nom de Compile.
1. Une compile un vecteur de modications dans la classe qui appelle.
2. Une compile une liste de modications dans la classe qui appelle.
3. Une compile une modication dans la classe qui appelle.
On peut alors soumettre cette modication au gestionnaire VManagerGraph via la methode
SetModif.
On peut remettre `a zero le formulaire de modications du gestionnaire via la methode
InitModif.
g
u
i
/
i
n
t
e
r
f
a
c
e
d
o
n
n
e
e
.
t
e
x
9.2 Classe dimplementation :VManagerGraphTest
Plus quune implementation de la classe precedente, une organisation de linterface de donnees
a ete proposee. Cela se base tout dabord sur une decomposition franche entre plusieurs compo-
sants.
9.2.1 Separation donnees de graphe/autres donnees
Tout dabord, les informations de graphes dun cote et les informations geometriques ou tout
autre dun autre cote sont completement separees. Le principe est que les cles fournies par la
librairie de graphe servent `a acc`eder `a toutes les donnees que lon desire utiliser. On trouve donc
plusieurs donnees :
La donnee de graphe prend la forme dune classe du type GraphModelV. Il sagit dune
classe qui se comporte comme un pointeur sur une classe du type GraphModel*. Elle est
securisee par le fait que le pointeur quelle contient est intialisee `a 0 dans son constructeur
et que lon ne peut pas detruire par son biais le pointeur quelle contient. Le pointeur de ce
52 Copyright c 2003 Soluscience
type de classe ne doit jamais etre detruit directement, uniquement par le biais dune classe
qui porte le nom de ProjetGraph. En eet, on introduit `a ce niveau le concept de graphe
hierarchique et de mod`ele de graphe. Un mod`ele de graphe est un graphe qui peut avoir
comme representation un noeud dans un autre graphe. Le syst`eme dinterdependance qui
se cree alors ne permet pas de pouvoir detruire un mod`ele de graphe simplement.
Les donnees geometriques ne se distinguent des donnees autres que les donnees de graphes.
On acc`ede aux informations geometriques des composants via les cles de type void* qui
les identient de mani`ere unique. Il sagit en fait dune map entre les cles et des donnees
geometriques que lon a dej`a decrites. Elles sont indispensables pour lachage de lediteur
de graphes et doivent repondre aux contraintes du gestionnaire de calques. Plusieurs classes
ont ete construites `a cet eet dont la principale qui fournit tous les acc`es necessaires portent
le nom de DataLayout.
On peut introduire autant de donnees que lon souhaite sous le mod`ele de DataLayout
pour associer des donnees aux composants du graphe.
9.2.2 Separation recuperation/modication dinformations
Deuxi`emement, on a dissocie laction dobtenir une information de laction de modier une
information. Lobjectif est de permettre avec un minimum deort aux programmeurs de pouvoir
creer des comportements de graphes tr`es particuliers et dierents des cas triviaux.
Le premier pas etait la creation dun formulaire de remplissage de modications.
Le second pas est la creation dune classe de manipulation des donnees de graphes, de
geometrie et dautres donnees si on le souhaite. La classe de declaration porte le nom de
DGManip et une implementation des cas triviaux de manipulation a ete realisee au sein de
la classe DGManipTest. On y declare un ensemble de methodes virtuelles de modications
qui commencent souvent par Set et qui prennent souvent pour argument la cle du com-
posant que lon desire modier et toujours un formulaire de remplissage de modications.
DGManipTest ore un ensemble de fonctionnalites basiques qui peuvent etre utilisees par
des manipulateurs plus complexes.
La gure 9.1 resume cette organisation un peu particuli`ere.
9.2.3 Gestion du graphe hierarchique.
Un graphe hierarchique est un ensemble de graphes. Chacun peut avoir deux representations :
Deplie o` u lon peut voir lensemble de ses composants. Une donnee geometrique est alors
associee `a une donnee de graphe.
Sous la forme dun noeud dans un autre graphe. Dans ce cas, il est necessaire de posseder
une sc`ene vectorielle qui le represente dans un rectangle. Un identiant sous la forme dune
chane de caract`eres serait le bienvenu. Pour linstant, on se borne `a lui donner un nom
sous la forme dune chane de caract`eres.
9.2.4 Code exemple de creation dun gestionnaire
On fournit un bout de code pour montrer comment une donnee de graphe est construite :
1 VManagerGraphTest* datai=new VManagerGraphTest;
2 DataLayout* datal=new DataLayout;
3 DGManipTest* manip=new DGManipTest;
4 aPointer<ProjetGraph> projet=new ProjetGraph;
5 HierarchicalGraph *hg=new HierarchicalGraph;
Copyright c 2003 Soluscience 53
CHAPITRE 9. INTERFACE DE DONN

EES
GUI
Structure de Graphe
VManagerGraph
DGManip
DGManipTest
Lien
Port
Noeud
Infos
Geometriques
Modele
Autres Infos
Autre Manager
VManagerGraphTest
Metaprogrammation
Systeme entree/sortie
Manipulateur abstrait
Orthogonal, Moleculaire, etc.
Fig. 9.1: Organisation des donnees et de linterface de donnees
6 BibElementPtr element;
7
8 projet->SetHierarchicalGraph(hg);
9 projet->CreateModel(element);
10 datai->SetData(element);
11 datai->SetProjetGraph(projet);
12 datai->SetManipulator(manip);
Ligne 1 on cree une donnee dinterface de type VManagerGraphTest.
Ligne 2 on cree une donnee dachage de type DataLayout.
Ligne 3 on cree un manipulateur de graphes de type DGManipTest.
Ligne 4 on cree un projet capable de creer des graphes hierarchiques et de les detruire du type
ProjetGraph. Cette structure peut dailleurs stocker des biblioth`eques de graphes.
Ligne 5 on cree une structure du type HierarchicalGraph issue de la librairie mathematique
de graphe.
Ligne 6 on declare un el`ement du type BibElementPtr qui est un pointeur sur une classe qui
peut contenir :
Un mod`ele de graphe du type GraphModelV
Une donnee geometrique du type DataLayout
Une sc`ene vectorielle qui permet de denir le dessin du graphe quand il est represente
sous forme de noeuds dans un autre graphe.
Un nom sous la forme dune chane de caract`eres.
Ligne 8 on xe un outil de creation de graphes hierarchiques au projet de graphe projet.
Ligne 9 on demande la creation dun nouveau mod`ele de graphe au projet.
Ligne 10 on xe ce mod`ele de graphe au gestionnaire de graphes.
Ligne 11 on xe le projet au gestionnaire de graphes. Celui-ci en aura besoin, lors de la montee
et de la descente dans des graphes hierarchiques.
Ligne 12 on xe le manipulateur de donnees que lon desire utiliser avec ce gestionnaire de
graphes.
54 Copyright c 2003 Soluscience
Chapitre 10
Interface graphique du graphe
Lediteur de graphes existe sous trois formes :
wxGraph est lediteur simple. Cest le noyau de tous les autres objets. Il poss`ede donc la plus
grande complexite.
wxGraphScroll est compose avec un editeur simple, de deux ascenseurs (un vertical et un
horizontal) et une roulette pour gerer le zoom.
wxGraphEditor est un editeur splittable compose dau plus 10 objets de type wxGraphScroll,
dune barre de titre pouvant gerer des petits menus contextuels et dun gestionnaire de
calques qui est detaille dans un autre chapitre.
Ce chapitre decrit le fonctionnement de ces trois classes.
g
u
i
/
i
n
t
e
r
f
a
c
e
g
r
a
p
h
.
t
e
x
10.1 wxGraph
Cette classe est la classe de base de linterface qui permet dinterpreter une structure de
graphes simple composee :
De nud qui est une structure qui peut contenir des ports. Linterface de donnees peut
fournir une sc`ene vectorielle de type Scene2D de representation qui est alors utilise pour le
dessiner. Cette sc`ene peut subir une transformation geometrique qui est egalement fournie
par linterface de donnees. Si aucune sc`ene nexiste pour la representation du nud celui-ci
est represente par un carre jaune.
Linterface de donnees informe si un noeud peut etre agrandi et de quelle mani`ere il peut
letre parmi 8 possibilites, les 8 angles cardinaux principaux. Linterface informe egalement
si un nud peut etre deplace ou pas.
De ports qui sont les zones dattaches des liens. Les ports peuvent etre libres ou bien
appartenir `a un noeud. Dans ce cas, si le nud poss`ede une sc`ene vectorielle, ils ne sont
pas dessines, la sc`ene vectorielle en etant responsable. Les sc`enes vectorielles poss`edent la
particularite de pouvoir posseder des zones. Ces zones peuvent etre utiliser pour reperer
les ports.
De la meme mani`ere que pour les noeuds, linterface de donnees informe si on peut agrandir
ou deplacer les ports.
Les liens qui permettent de relier deux ports. Les liens sont un ensemble de points qui
partent du milieu dun port pour aller ves le milieu dun autre port. Contrairement aux
nuds et aux ports, le comportement de deplacement des liens est regi par les comporte-
ments souris et clavier de lediteur.
Copyright c 2003 Soluscience 55
CHAPITRE 10. INTERFACE GRAPHIQUE DU GRAPHE
Par defaut, il est posible de creer un lien, dajouter des points de controle, de deplacer
des points de controle ou de deplacer des segments entier de liaison soit librement soit
parall`element `a la position initiale.
Plusieurs objets particulier peuvent apparatre pour aider lutilisateur dans sa demarche de
creation dun graphe.
Une palette apparat lorsque le curseur reste trop longtemp inactif. Il permet alors de choisir
dans une palette un autre type de nuds que lon souhaite ajouter. Il sut alors de cliquer
sur le nud dans la palette ou appuyer sur la touche retour. A partir de l`a, tous les
ajouts de nuds seront du type choisi. Cette palette est transparente et permet de voir
exactement laction que lon va faire.
Les eches permettent de faire deler la palette pour choisir un el`ement particulier.
Un menu contextuel sache lorsque plusieurs ports se trouvent les uns au dessus des autres
de telle mani`ere `a ce quon puisse pas les selectionner directement pour creer une liaison.
Ce menu va alors acher des chanes de caract`eres associees aux ports concernes fournis
par linterface de donnees. La selection des items permet de voir quelles sont les liaisons
concernees par un port.
Un menu circulaire apparait lorsque lon laisse appuyer le bouton droit ou que lon eectue
un drag droit trop important. Il permet dacceder `a des param`etres de lediteur pour
scroller horizontalement ou verticalement, pour zoomer, pour selectionner des param`etres
dachage. En particulier, on peut choisir si on souhaite acher une grille et les nombres
sur la grille pour se reperer.
Il est possible de rendre inoperationnel ces interacteurs particuliers.
Cet objet poss`ede des comportements complexes qui sont decrits dans des styles de compor-
tement clavier et souris.
10.1.1 Comportement abstrait wxAbstractComportGraph
Lediteur de graphe simple est dote dun comportement clavier particuli`erement complet et
complexe. Il a ete decide de la batir comme un kit que lon peut reorganiser pour interpreter
plus ou moins dieremment les actions sur le clavier.
De plus, il est dote dun comportement de souris virtuelle capable de mimer toutes les actions
de la souris avec les quatres eches et les touches Alt, Shift et Ctrl.
Pour eviter de repliquer un grand nombre de methodes, les comportement souris et clavier ont
ete implementes de mani`ere originale. Ils derivent tous deux de la meme classe wxAbstractComportGraph
qui ore un panel de methodes qui representent un ensemble dactions que lon peut realiser sur
lediteur de graphe. Pour les citer :
Ajouter un point de controle `a un lien.
Reactualiser la position du curseur.
Reactualiser la position du curseur pendant une phase de dragging.
Reactualiser la position du curseur pendant une phase de dragging avec le bouton droit.
Reactualiser lachage du menu contextuel de choix des ports en cas de besoin.
Reactualiser lachage de la palette.
Eectuer une action de dragging. Cette methode reoriente vers dautres methodes ba-
siques en fonction du contexte, dierents modes de liaison, mode de selection, mode de
deplacement, mode de selection de taille de ports ou de nuds etc. . .
Gerer un deplacement de la souris simple soit en mode normal soit en mode de liaison.
56 Copyright c 2003 Soluscience
Gestion dun relache de bouton gauche.
Gestion dun enfoncenement de bouton droit.
Gestion dun relache de bouton gauche.
Reactualisation de la taille dun port par un procede de dragging. Il faut noter que cette
fonction comme beaucoup dautres possede un fonctionnement particulier. Il faut en eet
dissocier un click bref pour ajouter un nud ou un port dun deplace qui lui seectue
sur des distances courtes. Dans une phase de dragging, tant que le deplacement nest
pas susant on neectue aucune operatoin de selection, de deplacement de nuds, ports
ou liens. Si le relache intervient avant un deplacement assez long, on consid`ere que lon
eectue uen action de click bref qui peut saccompagner de lajout dun port ou dun nud
par exemple. Par contre, si le deplacement sav`ere susament long pendant une action de
dragging on entre alors dans un mode dierent qui va permettre dagrandir ou de deplacer
des objets et on nen ressortira que lors du relache de la souris.
Il faut egalement noter que toutes les actions de deplacer, agrandir peuvent seectuer soit
en mode direct, on voit alors la modication en temps reel, soit en mode indirect ou un
grise apparat pour avoir une idee de ce qui va se passer lorsque lon relachera la souris.
Ajout dun point dans un segment et gestion de son deplacement.
Gestion du deplacement dun nud lors dun dragging.
Gestion du deplacement dun port lors dun dragging.
Gestion de lagrandissement dun nud.
Gestion de selection de composant lors dun dragging.
Gestion du deplacement dun segment, celui-ci restant toujours parall`ele `a sa position ini-
tiale, les deux points du segment se deplacant en consequence, les deux points les encadrant
restant xes.
Gestion du deplacement dun segment librement, celui restant toujours de la meme taille,
parral`ele `a lorigine, les deux point encadrant restant xes.
Gestion de deplacement dun point de controle.
Gestion de la creation dun lien.
Gestion dun dragging droit. Si le depalcement est faible et court avant le relache, il y aura
rajout de port, sinon ce sera lapparation dun menu circulaire appele egalement Marking
Menu pour gerer des param`etres de lediteur.
Fin de deplacement dun nud pour gerer le mode indirect.
Fin dajout dun point de controle dun lien pour gerer le mode indirect.
Fin de dagrandissement dun port pour gerer le mode indirect.
Fin de deplacement dun port pour gerer le mode indirect.
Fin dagrandissement dun nud pour gerer le mode indirect.
Fin dune liaison lors dun relache. Si la position de la souris est dans un port autre que
celui du port dorigine, il y aura tentative de creation dun lien.
Fin de deplacement dun point de controle dun lien pour gerer le mode indirect.
Fin de deplacement dun segment celui-ci restant parral`ele `a sa position dorigine ainsi que
les deux segments lencadrant pour gerer le mode indirect.
Fin de deplacement dun segment, celui-ci restant parall`ele `a sa position dorigine, les
segments lencadrant se deplacant librement pour gerer le mode indirect.
Fin dune selection. Si le deplacement maximal realise est trop court, un nud est rajoute,
sinon on arrete simplement la selection.
Fin dune selection. Idem `a la precedente sauf que lorsquun nud est cree le premier port
libre fait demarrer un nouveau lien tant et si bien que lon cree des liens sans arr`et jusqu`a
Copyright c 2003 Soluscience 57
CHAPITRE 10. INTERFACE GRAPHIQUE DU GRAPHE
click droit.
Fin dun dragging droit. Si le deplacement `a ete court lors du dragging, il y a creation
dun port sinon rien.
Fin dun liaison qui cree un nud daccroche sur le nouveau nud cree.
Ces methodes sont independantes de laction reelle de lutilisateur. Le programmeur est libre
de les enchaner comme il le souhaite lors de la venue dev`enement reels. Cela ore une grande
souplesse pour programmer de nouveaux comportements, les fonctions de bases existant dej`a.
En particulier, on utilise cette methode pour mimer un comportement souris avec les eches.
10.1.2 Comportement souris wxMouseComportGraph
Avec la methode decrite precedemment, le comportement souris de base implemente dans
cette classe devient triviale.
10.1.3 Comportement clavier wxComportGraph
Le comportement clavier est un peu plus complexe car il g`ere des actions speciques :
le copier-coller. Le copier coller est une action tr`es proche de la sauvegarde de chiers dans
le cas des graphes et il reste `a limplementer.
Les actions Undo/Redo sont implementees et sont enti`erement gerees par linterface de
donnees.
Les touches PageUp/PageDown permettent de faire deler les pages de lediteur.
La touche F2, ou lassociation Ctrl + permettent daugmenter le zoom.
La touche F1, ou lassociation Ctrl - permettent de diminuer le zoom.
Lassocitation Ctrl+P permet lachage de la palette. Celle-ci peut sacher suivant plu-
sieurs modes, soit lorsque la souris reste inactive trop longtemp ou par cette association,
soit uniquement par cette association.
Neanmoins, autour des actions sur les eches un comportement permettant dobtenir toutes
les actions de la souris a ete implemente :
Lappui sur les eches induit des comportements de type moving, deplacement libre de la
souris. La meme chose avec la touche Shift enfoncee accel`ere ce mouvement. On peut de
cette mani`ere obtenir un placement tr`es precis du curseur.
Lappui sur la touche Alt equivaut au bouton gauche de la souris enfoncee lors de deplacement
avec les touches eches. Des quun deplacement seectue alors avec la touche Alt relevee,
cela equivaut `a un relache de bouton gauche de la souris.
Le meme fonctionnement est utilise avec la touche controle pour mimer laction sur le
bouton droit.
Toutefois lorsque la palette est visible, les eches sont utilisees pour faire deler la palette.
Il est prevu de complexier le comportement clavier, pour par exemple appeler une librairie
ou un module en tapant son nom et pour bien dautres operations.
10.1.4 Style graphique wxStyleGraph
Le style graphique est assez universel, il y a donc peut de chances que dautres styles soient
crees. Il g`ere plusieurs achages :
Lachage de la grille en premier avant tout le monde.
Lachage de nuds. Ils sont aches juste apr`es la premi`ere instance dachage des liens.
Lachage des ports, apr`es celui des neuds.
58 Copyright c 2003 Soluscience
Lachage des liens se fait en deux fois pour gerer la complexite dachage de ceux-ci. Les
liens qui traversent un nud auquel ils ne sont pas lies sont aches en dessous de ceux-ci
tandis quun lien est au dessus dun nud auquel il est attache. Idem pour les ports.
Trace la selection des nuds, ports et liens.
Trace les modication de liens, de taille ou de place dun nud ou dun port etc. . .en mode
indirect.
Le curseur est invisible, le style graphique se charge de le redessiner. En eet pour le
comportement abstrait de souris lie au clavier, le curseur ne correspond plus `a la souris
reelle. Il existe sur certaines plateformes la possibilite de commander le placement de la
souris via la methode wx, WarpPointer de la classe wxWindow, mais ce nest pas le cas
partout (Mac OS 9 en particulier). En contrepartie, on utilise cette astuce pour linstant.
Trace la palette de choix del`ements dune librairie.
10.1.5 Interface scrollable
Lediteur de graphes ne represente quune petite partie dun espace de travail vaste. On a
dailleurs denit une taille arbitraire de celui-ci `a 10 000 points dans linterface de donnees mais
rien nempecherai de travailler sur des espaces beaucoup plus grands.
Pour programmer ce type dobjet, on utilise un concept qui est celui du cache. On consid`ere
que lon represente un rectangle de lespace de travail. Celui-ci se comporte comme si sur une
carte, on avait place une grande feuille blanche dans laquelle on aurait decoupe un rectangle.
On peut alors faire glisser cette feuille blanche et ne visualiser quune partie de la carte. Avec
linformatique, on peut se permettre des choses plus complexes comme dagrandir le rectangle
de la feuille blanche ou changer son echelle de representation.
De cette idee, pour tout type dinterface de ce type on denit trois rectangles particuliers :
Un premier rectangle abstrait qui est celui de lespace de travail. Il est generalement tr`es
grand. La taille de lespace de travail est une information de linterface de donnees. Cest la
donnee qui la denit, ou encore cest le meme rectangle pour toutes les interfaces graphiques
qui vont chercher `a interpreter la donnee.
Un second rectangle abstrait, lie au premier, represente la zone que lon visualise dans le
premier rectangle. Bien quabstrait, cest une information de linterface graphique, chaque
interface possedant un rectangle propre, celui quelle represente. On le qualie de rectangle
de representation.
Le rectangle reel de visualisation `a lecran. Cest ce que lutilisateur voie. En son interieur,
on represente tous les composants qui existent dans le rectangle de representation. Il existe
donc des fonctions de correspondance entre les points de lespace de representation et celui
de lespace de visualisation. Generalement, on construit quatre fonctions :
1. Changement de rep`ere dun point de lespace de representation vers lespace de vi-
sualisation.
2. Linverse.
3. Changement de rep`ere dun rectangle de lespace de representation vers lespace de
visualisation.
4. Linverse.
Ces fonctions doivent etre construites au tout debut de limplementation dune de ces
classes. Il ne faut jamais essayer de les reimplementer ailleurs dans une fonction specique.
Copyright c 2003 Soluscience 59
CHAPITRE 10. INTERFACE GRAPHIQUE DU GRAPHE
En eet tout changement dans ces fonctions va se repercuter completement sur toute lin-
terface. Elle joue le role de carrefour central de calculs dinformations. Linterface graphique
est donc tr`es sensible `a toute modication de leur implementation. Cest un avantage de
centraliser ce type de fonctions.
Une fois ces fonctions construites, il faut reperer les composants que lon visualise, cest-`a-
dire ceux dont la geometrie poss`ede une intersection avec le rectangle de reperesentation. Ce
calcul va seectuer `a chaque fois que lon va changer le rectangle de representation soit par un
deplacement soit par un zoom. Ce calcul a un co ut car il faut acceder `a linformation geometrique
des composants et verier si il y a une intersection.
Si on poss`ede n composants, lacc`es aux informations dun composant poss`ede un cout de
ln(n) pour acceder dans la map dinformations `a partir de la cle dun composant. Le co ut total
`a chaque modication du rectangle de representation est donc de nln(n). Actuellement cest le
cas, mais il y a moyen daccelerer la manuvre. En eet, on doit scruter tous les composants. Il
nest donc pas utile de rechercher les composants avec leur cle. Il sut de parcourir toute la map
dinformations avec un iterateur adequat. On acc`ede alors `a chaque composant avec un cout de
lordre dune operation et le co ut total est alors de lordre de n. Linterface de donnees est en
cours de modication pour fournir une methode de parcours rapide de tous les composants.
Ces informations sont stockees dans la classe grGraph au sein de donnees protegees :
nodevis est le vecteur de tous les nuds visibles.
linkvis est le vecteur de tous les liens visibles.
portvis est le vecteur de tous les ports libres visibles.
portnodevis est le vecteur de tous les ports visibles des nuds visibles.
et ces informations sont calculees aux seins de methodes particuli`eres privees
recomputefreeport recalcule lensemble des ports libres visibles.
recomputelink recalcule lensemble des liens visibles.
recomputenode recalcule lensemble des nuds visibles et des ports visibles des nuds
visibles.
Ces methodes sont toujours appelees ensemble au sein de la methode publique Recompute.
Cette derni`ere est toujours appelee d`es que le rectangle de representation est modie ou d`es que
lon modie la donnee. Ce sont des methodes centrales. On a fait le choix de faire des calculs de
blocs `a chaque modication. Il est probablement possible de travailler plus nement dans certains
cas mais il est dicile de faire autrement lors de la modication du rectangle de representation
en particulier lors des periodes de scroll ou de zoom.
Lalgorithmie interne de ces methodes est triviale. Il existe probablement des methodes pour
accelerer le calcul des composants visibles. Si tel est le cas, il sura de les implementer dans ces
methodes pour obtenir lamelioration voulue.
10.1.6 Informations internes
Linterface graphique conservent des informations speciques `a elle sur tous les composants
dans des vecteurs de plusieurs classes qui actuellement font la meme chose :
InternalGraphNodeInfo poss`ede des informations sur les nuds speciques `a linterface
graphique. Ces informations sont de deux types mais concernent la selection des objets.
On peut savoir si un nud est selectionne ou pas pour le dessiner. On peut savoir si il
fait partie des dej`a selectionne. Cela sert `a un certain mode de selection o` u lon etend la
selection. Ceux qui etait selectionne avant lextension reste toujours selectionne quoiquil
arrive dans ce mode. Par contre en fonction de la zone de selection les autres composants
60 Copyright c 2003 Soluscience
vont se trouver nouvellement selectionnes ou deselectionnes.
InternalGraphPortInfo idem avec les ports.
InternalGraphLinkInfo idem avec les liens.
Ces trois classes sont identiques. On peut se poser la question de linteret den avoir cree trois.
On sest tout simplement dit que de nouvelles informations speciques `a linterface pouvaient
survenir dans le futur et que cette fois ci, il pourrait tr`es bien y avoir une distinction entre les
types de composants.
Ces vecteurs dinformations complementaires sont des donnees protegees de la classe grGraph :
nodesinfo pour les nuds.
portsinfo pour les ports.
linksinfo pour les liens.
Les valeurs de ces champs sont gerees par la methode ReactualiseSelect qui prend comme
argument un point, celui de la position de la souris lors dune selection. Cette methode ne fait
pas grand chose et va en fait en appeler trois autres dordre prive :
reactualiseselectnode g`ere la reactualisation de la selection des nuds.
reactualiseselectport g`ere la reactualisation de la selection des ports.
reactualiseselectlink g`ere la reactualisation de la selection des liens.
Ces methodes ont un fonctionnement particulier car on a souhaite que toutes les interfaces
soient au courant quune modication de selection sest produite dans lune dentre elle. Pour
cela, il fallait passer par le point commun de toutes les interfaces representant la meme donnee,
la donnee elle meme. Cette derni`ere poss`ede le formulaire de derni`ere modication. Les methodes
mentionnees plus haut remplissent donc ce formulaire lors dune selection dans un champ ap-
proprie.
Cest une methode originale car une modication de selection nest pas une modication de la
donnee elle-meme. On se sert ici du support fournit par linterface de donnees pour communiquer
entre les interfaces graphiques.
Il est egalement possible de commander la selection dun nud, dun port ou dun lien via
trois methodes publiques :
ReactualiseSelectNode. Cette methode comme les suivantes prend en argument la cle
du nud que lon souhaite selectionner. Cette methode fonctionne sur les deux modes, soit
la selection ecrase lancienne et lobjet est obligatoirement le seul selectionne, soit il y a
inversion de selection de lobjet sans que le reste de la selection ne soit atteint.
Le premier mode se xe et se recupere via les methode Set/IsSecondFunction. Ce mode
est xe lorsque la touche Shift est enfoncee et annuler lorsquelle ne lest pas. Neanmoins
cette methodologie permet de xer ce mode comme on le souhaite dans les comportements
clavier et souris.
ReactualiseSelectPort
ReactualiseSelectLink
Des methodes privees permettent de selectionner ou deselectionner completement des com-
posants :
un/selectallport deselectionne ou selectionne tous les ports. La commande se fait via
la methode Un/SelectAllPort.
un/selectalllink deselectionne ou selectionne tous les liens. La commande se fait via
la methode Un/SelectAllLink.
un/selectallnode deselectionne ou selectionne tous les nuds. La commande se fait via
la methode Un/SelectAllNode.
On peut tout deselectionner via la methode UnSelectAllLink.
Copyright c 2003 Soluscience 61
CHAPITRE 10. INTERFACE GRAPHIQUE DU GRAPHE
On peut obtenir letat de selection des nuds, des ports de nuds, des ports libres, et des
liens via les methodes du type GetSelectNodeVis.
Il reste `a noter quil existe des couleurs qui sont atrribuees `a la selection qui sobtiennent via
les methodes, Get/SetColorNodeSelect, Get/SetColorPortSelect, Get/SetColorLinkSelect.
Le style graphique reste libre dutiliser cette infomation pour lachage particulier de la selection.
10.1.7 Donnee de calque
Les calques sont dautres informations que lon stocke au sein de linterface graphique. Cette
donnee est tr`es particuli`ere car elle est duale. Elle existe `a la fois au sein de la donnee, il faut
bien lors de louverture dun chier par exemple, mais d`es que lon splitte la fenetre en plusieurs
editeurs, on peut denir les param`etres de calques dieremment en fonction de chaque sous
fenetre. Cela signie donc bien que la donnee de calque est en partie `a linterface graphique,
(son etat) et en partie `a la donnee, (le nombre de calques par exemple). Au sein de linterface
graphique, il sagit dune donnee protegee du nom de layer qui est un vecteur de calques
de type grLayer. Un calque poss`ede des proprietes. Ici, ils peuvent etre visibles, invisibles ou
verrouilles, libres. En fait la propriete sapplique aux composants qui appartiennent au calque.
Il sera possible par la suite de fournir dautres proprietes aux calques en les rajoutant dans la
classe grLayer.
Une seconde information concerne le calque courant de linterface. Il sagit du calque dans
lequel vont etre ajoutes les composants. Cette donnee est un indice qui indique le calque dans
le vecteur layer. Cette variable est nommee curlayer.
Il est possible de changer lordre de visibilite des calques. Celui-ci concerne lordre dachage
des composants ou plutot qui est devant qui. Les composants, liens, nuds, ports poss`edent
dans la donnee lindexe du calque sur lequel il se trouve. Il nest donc pas question de manipuler
directement lordre du vecteur layer. Pour cela, on utilise une classe particuli`ere qui reindexe
un vecteur du nom de Indexer de la librairie phenix. La variable qui porte cet indexeur est
protegee et porte le nom de indexlayer.
g
u
i
/
i
n
t
e
r
f
a
c
e
g
r
a
p
h
.
t
e
x
10.2 wxGraphScroll
Comparee `a la classe precedente, il sagit dune classe particuli`erement simple. Il sagit en
fait dune classe composee :
Un editeur de graphe simple wxGraph
Deux ascenseurs pour les deplacements verticaux et horizontaux.
Une roulette pour gerer le zoom.
Des petits widgets qui sont sans utilite si le widget est utilise seul. Il sagit de separateur,
de boutons de deplacements et de cles qui servent `a lediteur de graphes wxGraphEditor
pour splitter et deplacer des parties de lediteur et faire apparatre et disparatre la barre
de titre de lediteur.
A priori cet objet nest pas sense evoluer enormememt `a part les methodes simples de re-
transciption dordre vers lediteur de graphe simple quil contient.
g
u
i
/
i
n
t
e
r
f
a
c
e
g
r
a
p
h
.
t
e
x
10.3 wxGraphEditor
Cet objet est un peu plus complexe que le precedent. Il peut gerer jusqu`a dix editeurs de
type wxGraphScroll qui representent la meme donnee dans une fenetre unique. Ce type dobjet
62 Copyright c 2003 Soluscience
est tr`es commun d`es que lon souhaite utiliser un editeur dans la librairie phenix. Il reste
neanmoins necessaire de bien penser les questions de generalite, cest-`a-dire si un param`etre doit
etre applique `a lensemble des editeurs quil poss`ede ou bien est libre pour chacun des editeurs
representes. Dans le cas present certains param`etres sont libres :
Zone de lespace de travail visualisee.
Visibilite des calques.
Choix du zoom.
Choix des param`etres de visibilite (grille, nombre, palette)
Par contre dautres param`etres sont geres de mani`ere commune :
Selection des objets.
En plus des dix editeurs visualisables, trois autres objets sont presents.
Une barre de titre qui represente le chemin hierarchique de lobjet represente. La representation
permettant de visualiser un graphe hierarchique, double cliquer sur un nud hierarchique
induit une descente dans la stucture de graphe. Un chemin sache alors dans la barre
de titre pour indiquer la zone o` u lon se trouve. Ce chemin est constitue des noms de
chaque nud visite hierarchiquement (Nom du p`ere+.+Nom du nud) separe par des /.
En double cliquant sur le nom dun nud on peut remonter dans sa visite.
La barre de titre poss`edent egalement des boutons `a icone qui permettent dacceder `a des
menus contextuels pour faire des choix de param`etres. Pour linstant, ils sont sous utilises
mais on reechit `a parametrer le fonctionnement de cet outil pour les particulariser en
fonction de lutilisation de lediteur.
A droite, de la barre de titre, un losange est dessine. Quand le graphe est sauvegarde en
memoire, ce losange apparat seul et quand il ne lest pas, `a la suite dune modication, il
est barre en rouge.
Un gestionnaire de calque est present pour gerer lordre dachage des calques et leur
visibilite. On ne decrit pas ici precisement le fonctionnement de cet objet qui est explicite
plus en detail dans le chapitre suivant.
Neanmoins, un calque peut se trouver dans trois etats, non selectionne, selectionne, ou
possedant le focus. Un seul calque peut posseder le focus. Lors de lajour dun nud, dun
port ou dun lien, cest dans ce calque que le composant est ajoute.
Une barre dinformation basique au dessus des editeurs les plus hauts. Il ne sagit pas dun
widget car cest la classe wxGraphEditor qui g`ere son achage. Il est possible de faire a-
cher plusieurs types de messages dans cette barre, la position `a droite et un message parti-
culier `a gauche dans une zone assez large. Lediteur se charge par la reception dev`enements
particuliers dacher des informations basiques pour indiquer les consequences des actions
quil va realiser en fonction du contexte. Cette barre pourra etre utiliser dans le futur pour
acher dautres types de messages.
Ces trois objets sont retractables. Le gestionnaire de calques et la barre de titre peut etre
retirer ou racher par des actions sur des petits widgets que lon nomme des cles. Ceux-ci ont
la forme dun petit carre blanc lorsque la cle est ouverte et dun carre blanc coupe par du gris
quand elle est fermee. Ces cles sont situees en haut de lediteur le plus en haut `a droite et `a
droite de la barre de titre.
Pour linstant la barre dinformation nest pas retirable via linterface mais peut letre en
programmation.
Copyright c 2003 Soluscience 63
CHAPITRE 10. INTERFACE GRAPHIQUE DU GRAPHE
64 Copyright c 2003 Soluscience
Chapitre 11
Gestionnaire de calques
Copyright c 2003 Soluscience 65
Cinqui`eme partie
Tutorial
Copyright c 2003 Soluscience 67
Chapitre 12
Tutorial
Les sections qui suivent presentent dierents exemples dutilisation de la librairie de graphe.
Tous les codes se trouvent dans le repertoire :
Pole/demos/graph
Des projets visual C++, gcc et CodeWarrior sont disponibles :
Visual C++ : SimpleG.dsp et HierarG.dsp dans le repertoire des chiers.
gcc : Pas encore disponible.
CodeWarrior : Importer GraphTest.mcp.xml dans le repertoire Pole/CW xml/projects/demo/
t
u
t
o
r
i
a
l
/
s
i
m
p
l
e
.
t
e
x
12.1 Graphe et parcours de graphe
Pole/demos/graph/SimpleG.cpp
Un graphe doit pouvoir etre cree par lajour de nuds, de ports et de liens. Une fois cela
fait, il faut pouvoir parcourir ces structures de multiples mani`eres. Cette exemple presente la
creation dun graphe et lensemble des methodes de parcours de constituants du graphe.
1 void test_basics(void)
2 {
3 MyGraph graph;
4
5
6 MyGraph::InternalNodeId n1;
7 MyGraph::InternalNodeId n2;
8
9
10 MyGraph::InternalPortId p01;
11 MyGraph::InternalPortId p11;
12 MyGraph::InternalPortId p12;
13 MyGraph::InternalPortId p21;
14
15
16 MyGraph::InternalLinkId l0111;
17 MyGraph::InternalLinkId l1221;
18
19
20 allValues[n1 = graph.CreateNode()] = 1.0;
21 allValues[n2 = graph.CreateNode()] = 2.0;
22
23 allValues[p01 = graph.CreatePort()] = 0.1;
24 allValues[p11 = graph.CreatePort(n1)] = 1.1;
25 allValues[p12 = graph.CreatePort(n1)] = 1.2;
Copyright c 2003 Soluscience 69
CHAPITRE 12. TUTORIAL
26 allValues[p21 = graph.CreatePort(n2)] = 2.1;
27
28
29 graph.CreatePort();
30
31
32 allValues[l0111 = graph.CreateLink(p01,p11)] = 1.11;
33 allValues[l1221 = graph.CreateLink(p12,p21)] = 12.21;
34
35
36
37 DISPLAY_EXPR(n1->opposite(l0111));
38 DISPLAY_EXPR(n2->opposite(l1221));
39
40
41 DISPLAY_EXPR(n1);
42 DISPLAY_EXPR(p11);
43 DISPLAY_EXPR(l1221);
44
45
46 DISPLAY_EXPR(p12->node);
47 DISPLAY_EXPR(p12->link);
48 DISPLAY_EXPR(l1221->second);
49
50
51 PAUSE("All nodes");
52 AllNodesPath<MyGraph> allNodes(graph);
53 DISPLAY_EXPR(*ni);
54 }}
55 PAUSE("All ports");
56 AllPortsPath<MyGraph> allPorts(graph);
57 {for (AllPortsPath<MyGraph>::const_iterator pi = allPorts.begin(); pi != allPorts.end(); pi++) {
58 DISPLAY_EXPR(*pi);
59 }}
60 PAUSE("All free ports");
61 ExternalPortsPath<MyGraph> freePorts(graph);
62 {for (ExternalPortsPath<MyGraph>::const_iterator fpi = freePorts.begin(); fpi != freePorts.end(); fp
63 i++) {
64 DISPLAY_EXPR(*fpi);
65 }}
66 PAUSE("All links");
67 AllLinksPath<MyGraph> allLinks(graph);
68 {for (AllLinksPath<MyGraph>::const_iterator li = allLinks.begin(); li != allLinks.end(); li++) {
69 DISPLAY_EXPR(*li);
70 }}
71 PAUSE("All ports of n1");
72 PortsOfNodePath<MyGraph> portsOfNode1(graph,n1);
73 {for (PortsOfNodePath<MyGraph>::const_iterator pn1i = portsOfNode1.begin(); pn1i != portsOfNode1.end
74 (); pn1i++) {
75 }}
76 PAUSE("All ports of n2");
77 PortsOfNodePath<MyGraph> portsOfNode2(graph,n2);
78 {for (PortsOfNodePath<MyGraph>::const_iterator pn2i = portsOfNode2.begin(); pn2i != portsOfNode2.end
79 (); pn2i++) {
80 }}
81 PAUSE("All links of n1");
82 LinksOfNodePath<MyGraph> linksOfNode(graph,n1);
83 {for (LinksOfNodePath<MyGraph>::const_iterator ln1i = linksOfNode.begin(); ln1i != linksOfNode.end()
84 ; ln1i++) {
85 }}
70 Copyright c 2003 Soluscience
86 PAUSE("Links from n1");
87 DirectLinksOfNodePath<MyGraph> linksFromNode(graph,n1);
88 {for (DirectLinksOfNodePath<MyGraph>::const_iterator lfn1i = linksFromNode.begin(); lfn1i != linksFr
89 omNode.end(); lfn1i++) {
90 DISPLAY_EXPR(*lfn1i);
91 }}
92 PAUSE("Links to n1");
93 IndirectLinksOfNodePath<MyGraph> linksToNode(graph,n1);
94 {for (IndirectLinksOfNodePath<MyGraph>::const_iterator ltn1i = linksToNode.begin(); ltn1i != linksTo
95 Node.end(); ltn1i++) {
96 DISPLAY_EXPR(*ltn1i);
97 }}
98 PAUSE("All neighbours of n1");
99 NodesOfNodePath<MyGraph> neighboursOfN1(graph,n1);
100 {for (NodesOfNodePath<MyGraph>::const_iterator nn1i = neighboursOfN1.begin(); nn1i != neighboursOfN1
101 .end(); nn1i++) {
102 }}
103 PAUSE("Direct neighbours of n1");
104 DirectNodesOfNodePath<MyGraph> dNeighboursOfN1(graph,n1);
105 {for (DirectNodesOfNodePath<MyGraph>::const_iterator dnn1i = dNeighboursOfN1.begin(); dnn1i != dNeig
106 hboursOfN1.end(); dnn1i++) {
107 DISPLAY_EXPR(*dnn1i);
108 }}
109 PAUSE("Indirect neighbours of n1");
110 IndirectNodesOfNodePath<MyGraph> iNeighboursOfN1(graph,n1);
111 {for (IndirectNodesOfNodePath<MyGraph>::const_iterator inn1i = iNeighboursOfN1.begin(); inn1i != iNe
112 ighboursOfN1.end(); inn1i++) {
113 DISPLAY_EXPR(*inn1i);
114 }}
115 PAUSE("All neighbours of n2");
116 NodesOfNodePath<MyGraph> neighboursOfN2(graph,n2);
117 {for (NodesOfNodePath<MyGraph>::const_iterator nn2i = neighboursOfN2.begin(); nn2i != neighboursOfN2
118 .end(); nn2i++) {
119 }}
120 PAUSE("Direct neighbours of n2");
121 DirectNodesOfNodePath<MyGraph> dNeighboursOfN2(graph,n2);
122 {for (DirectNodesOfNodePath<MyGraph>::const_iterator dnn2i = dNeighboursOfN2.begin(); dnn2i != dNeig
123 hboursOfN2.end(); dnn2i++) {
124 DISPLAY_EXPR(*dnn2i);
125 }}
126 PAUSE("Indirect neighbours of n2");
127 IndirectNodesOfNodePath<MyGraph> iNeighboursOfN2(graph,n2);
128 {for (IndirectNodesOfNodePath<MyGraph>::const_iterator inn2i = iNeighboursOfN2.begin(); inn2i != iNe
129 ighboursOfN2.end(); inn2i++) {
130 DISPLAY_EXPR(*inn2i);
131 }}
132
133 MapSubGraphStruct fsgs(graph);
134 fsgs.include_Node[n1] = true;
135 fsgs.include_Node[n2] = true;
136 fsgs.include_Port[p12] = true;
137 fsgs.include_Port[p21] = true;
138 fsgs.include_Link[l1221] = true;
139 PAUSE("All sub nodes");
140 AllNodesPath<MapSubGraphStruct > allSubNodes(fsgs);
141 {for (AllNodesPath<MapSubGraphStruct>::const_iterator ni = allSubNodes.begin(); ni != allSubNodes.en
142 d(); ni++) {
143 }}
144 PAUSE("All sub links of n1");
145 LinksOfNodePath<MapSubGraphStruct> subLinksOfNode(fsgs,n1);
Copyright c 2003 Soluscience 71
CHAPITRE 12. TUTORIAL
146 {for (LinksOfNodePath<MapSubGraphStruct>::const_iterator ln1i = subLinksOfNode.begin(); ln1i != subL
147 inksOfNode.end(); ln1i++) {
148 DISPLAY_EXPR(*ln1i);
149 }}
150 PAUSE("All adjacent nodes of n1");
151 NodesOfNodePath<MapSubGraphStruct> subNodesOfNode(fsgs,n1);
152 {for (NodesOfNodePath<MapSubGraphStruct>::const_iterator nn1i = subNodesOfNode.begin(); nn1i != subN
153 odesOfNode.end(); nn1i++) {
154 DISPLAY_EXPR(*nn1i);
155 }}
156
157 PAUSE("End of basics");
158
Ligne 3 On declare un graphe simple.
Ligne 6 On declare une cle de nud n
1
. Cest en fait un pointeur dun type particulier. Ce
pointeur une fois allouee contiendra des informations propres au nud. On sert de ladresse
de ce pointeur comme une cle unique une fois quil aura ete cree via loperateur new.
Ligne 7 On declare une seconde cle de nud n
2
.
Ligne 10 On declare la cle de port p
01
. Comme les cles de nuds, les cles de port contiennent
des informations comme le nud dappartenance. On se sert de ladresse du pointeur
comme dune cle unique.
Ligne 11 On declare la cle de port p
11
.
Ligne 12 On declare la cle de port p
12
.
Ligne 13 On declare la cle de port p
21
.
Ligne 16 On declare la cle de lien l
0111
. Comme les cles de nuds et de ports, les cles de liens
sont des pointeurs qui contiennent des informations comme le debut et la n du lien sous
la forme de cle de port. Ladresse du lien sert de cle unique.
Ligne 17 On declare la cle de lien l
1221
Ligne 20 On cree tout dabord le nud n
1
. La methode de graphe CreateNode fait appel `a
loperateur new qui cree ladresse unique de n
1
dont on se sert comme cle. Cette cle sert
`a atteindre une donnee de type reelle sous la forme dune map entre ladresse de n
1
et la
valeur reelle 1.0.
Ligne 21 On cree la cle de nud n
2
et on associe `a cette cle la valeur 2.0.
Ligne 23 On cree le port libre p
01
. Le port est dit libre car il nappartient `a aucun nud. A
ladresse de ce port on associe la valeur 0.1.
Ligne 24 On cree le port p
11
qui appartient au nud n
1
. On lui associe la valeur 1.1.
Ligne 25 On cree le port p
12
qui appartient au nud n
1
. On lui associe la valeur 1.2.
Ligne 26 On cree le port p
21
qui appartient au nud n
2
. On lui associe la valeur 2.1.
Ligne 29 On cree un port libre sans retenir la cle de port qui a ete cree.
Ligne 32 On cree le lien l
1011
. Un lien est deni entre deux ports, ici p
01
et p
11
. On associe `a
ladresse (la cle) de ce lien la valeur 1.11.
Ligne 33 On cree le lien l
1221
entre les ports p
12
et p
21
et on lui associe la valeur 12.21.
Ligne 37 On utilise la methode de nud opposite qui prend comme argument un lien. On
obtient le nud oppose au lien de ce nud. (Ce peut etre lui meme). On ache la valeur
du nud.
72 Copyright c 2003 Soluscience
Ligne 38 On recupere le nud oppose au lien l
1221
par rapport au nud n
2
. On ache la valeur
du nud.
Ligne 41 On ache la valeur du nud n
1
.
Ligne 42 On ache la valeur du port p
11
Ligne 43 On ache la valeur du lien l
1221
Ligne 46 On recupere le nud qui poss`ede le port p
12
et on lache la valeur reelle associee.
Ligne 47 On recupere le lien qui relie le port p
12
`a un autre port et on lache la valeur reelle
associee.
Ligne 48 on ache le la valeur associee au lien l
1221
.
Ligne 52 On cree un containeur diterateur de nud allNodes par rapport au graphe graph. Ce
containeur va permettre de construire literateur permettant de parcourir tous les nuds
de graph. On declare literateur de nud de graph, n
i
. On va faire parcourir `a cet iterateur
lensemble des nuds jusqu`a atteindre literateur allNodes.end().
Ligne 53 On ache la valeur associee au nud n
i
.
Ligne 56 On cree un containeur diterateur de port allPorts par rapport au graphe graph. Ce
containeur va permettre de construire literateur permettant de parcourir tous les ports de
graph.
Ligne 57 On declare literateur de port de graph, p
i
. On va faire parcourir `a cet iterateur
lensemble des ports jusqu`a atteindre literateur allPorts.end().
Ligne 58 On ache la valeur associee au port p
i
.
Ligne 61 On cree un containeur diterateur de port libre (nappartenant pas `a un nud)
freePorts par rapport au graphe graph. Ce containeur va permettre de construire literateur
permettant de parcourir tous les ports libres de graph.
Lignes 62,63 On declare literateur de port libre de graph, fp
i
. On va faire parcourir `a cet
iterateur lensemble des ports libres jusqu`a atteindre literateur freePorts.end().
Ligne 64 On ache la valeur associee au lien fp
i
.
Ligne 67 On cree un containeur diterateur de liens allLinks par rapport au graphe graph.
Ce containeur va permettre de construire literateur permettant de parcourir tous les liens
de graph.
Ligne 68 On declare literateur de port libre de graph, l
i
. On va faire parcourir `a cet iterateur
lensemble des liens jusqu`a atteindre literateur allLinks.end().
Ligne 69 On ache la valeur associee au lien l
i
.
Ligne 72 On cree un containeur diterateur de ports du nud n
1
portsofNode1 par rapport au
graphe graph. Ce containeur va permettre de construire literateur permettant de parcourir
tous les ports du nud n
1
de graph.
Lignes 73,74 On declare literateur de port du nud n
1
de graph, p
n1i
. On va faire parcourir `a
cet iterateur lensemble des ports du nud n
1
jusqu`a atteindre literateur portsOfNode1.end().
DISPLAY EXPR(*pn1i) ; // On ache la valeur associee au port p
n1i
.
Ligne 77 On cree un containeur diterateur de ports du nud n
2
portsofNode2 par rapport au
graphe graph. Ce containeur va permettre de construire literateur permettant de parcourir
tous les ports du nud n
2
de graph.
Copyright c 2003 Soluscience 73
CHAPITRE 12. TUTORIAL
Lignes 78,79 On declare literateur de port du nud n
2
de graph, p
n2i
. On va faire parcourir `a
cet iterateur lensemble des ports du nud n
2
jusqu`a atteindre literateur portsOfNode2.end().
DISPLAY EXPR(*pn2i) ; // On ache la valeur associee au port p
n2i
.
Ligne 82 On cree un containeur diterateur de liens du nud n
1
linksOfNode par rapport au
graphe graph. Ce containeur va permettre de construire literateur permettant de parcourir
tous les liens du nud n
1
de graph.
Lignes 83,84 On declare literateur de port du nud n
1
de graph, l
n1i
. On va faire parcourir `a
cet iterateur lensemble des ports du nud n
1
jusqu`a atteindre literateur linksOfNode1.end().
DISPLAY EXPR(*ln1i) ; // On ache la valeur associee au lien l
n1i
.
Ligne 87 On cree un containeur diterateur de liens qui partent du nud n
1
linksFromNode par
rapport au graphe graph. Ce containeur va permettre de construire literateur permettant
de parcourir tous les liens qui partent du nud n
1
de graph.
Lignes 88,89 On declare literateur de liens qui partent du nud n
1
de graph, l
fn1i
. On va
faire parcourir `a cet iterateur lensemble des liens qui partent du nud n
1
jusqu`a atteindre
literateur linksFromNode.end().
Ligne 90 On ache la valeur associee au lien l
fn1i
.
Ligne 93 On cree un containeur diterateur de liens qui arrivent au nud n
1
linksToNode par
rapport au graphe graph. Ce containeur va permettre de construire literateur permettant
de parcourir tous les liens qui arrivent au nud n
1
de graph.
Lignes 94,95 On declare literateur de liens qui arrivent au nud n
1
de graph, l
tn1i
. On va faire
parcourir `a cet iterateur lensemble des liens qui arrivent au nud n
1
jusqu`a atteindre
literateur linksToNode.end().
Ligne 96 On ache la valeur associee au lien l
tn1i
.
Ligne 99 On cree un containeur diterateur de nuds qui sont les voisins du nud n
1
neighboursOfN1
par rapport au graphe graph. Ce containeur va permettre de construire literateur permet-
tant de parcourir tous les voisins du nud n
1
de graph.
Lignes 100,101 On declare literateur de nuds voisins de n
1
de graph, n
n1i
. On va faire
parcourir `a cet iterateur lensemble des voisins du nud n
1
jusqu`a atteindre literateur
neighboursOfN1.end(). DISPLAY EXPR(*nn1i) ; // On ache la valeur associee au
nud n
n1i
.
Ligne 104 On cree un containeur diterateur de nuds qui sont les voisins du nud n
1
dNeighboursOfN1
dont les liens partent de n
1
par rapport au graphe graph. Ce containeur va permettre de
construire literateur permettant de parcourir tous les voisins du nud n
1
dont le lien parte
de n
1
de graph.
Lignes 105,106 On declare literateur de voisins du nud n
1
qui partent de n
1
de graph, d
nn1i
.
On va faire parcourir `a cet iterateur lensemble des voisins du nud n
1
qui partent de n
1
jusqu`a atteindre literateur dNeighboursOfN1.end()
Ligne 107 On ache la valeur associee au nud d
nn1i
.
Ligne 110 On cree un containeur diterateur de nuds qui sont les voisins du nud n
1
iNeighboursOfN1
dont les liens arrivent `a n
1
par rapport au graphe graph. Ce containeur va permettre de
construire literateur permettant de parcourir tous les voisins du nud n
1
dont le lien
arrive `a n
1
de graph.
Lignes 111,112 On declare literateur de voisins du nud n
1
qui arrivent `a n
1
de graph, i
nn1i
.
On va faire parcourir `a cet iterateur lensemble des voisins du nud n
1
qui arrivent `a n
1
jusqu`a atteindre literateur iNeighboursOfN1.end()
74 Copyright c 2003 Soluscience
Ligne 113 On ache la valeur associee au nud i
nn1i
.
Ligne 116 On cree un containeur diterateur de nuds qui sont les voisins du nud n
2
neighboursOfN2
par rapport au graphe graph. Ce containeur va permettre de construire literateur permet-
tant de parcourir tous les voisins du nud n
2
de graph.
Lignes 117,118 On declare literateur de nuds voisins de n
2
de graph, n
n2i
. On va faire
parcourir `a cet iterateur lensemble des voisins du nud n
2
jusqu`a atteindre literateur
neighboursOfN2.end(). DISPLAY EXPR(*nn2i) ; // On ache la valeur associee au
nud n
n2i
.
Ligne 121 On cree un containeur diterateur de nuds qui sont les voisins du nud n
2
dNeighboursOfN2
dont les liens partent de n
2
par rapport au graphe graph. Ce containeur va permettre de
construire literateur permettant de parcourir tous les voisins du nud n
2
dont le lien parte
de n
2
de graph.
Lignes 122,123 On declare literateur de voisins du nud n
2
qui partent de n
2
de graph, d
nn2i
.
On va faire parcourir `a cet iterateur lensemble des voisins du nud n
2
qui partent de n
2
jusqu`a atteindre literateur dNeighboursOfN2.end()
Ligne 124 On ache la valeur associee au nud d
nn2i
.
Ligne 127 On cree un containeur diterateur de nuds qui sont les voisins du nud n
2
iNeighboursOfN2
dont les liens arrivent `a n
2
par rapport au graphe graph. Ce containeur va permettre de
construire literateur permettant de parcourir tous les voisins du nud n
2
dont le lien
arrive `a n
2
de graph.
Lignes 128,129 On declare literateur de voisins du nud n
2
qui arrivent `a n
2
de graph, i
nn2i
.
On va faire parcourir `a cet iterateur lensemble des voisins du nud n
2
qui arrivent `a n
2
jusqu`a atteindre literateur iNeighboursOfN2.end()
Ligne 130 On ache la valeur associee au nud i
nn2i
.
Ligne 133 On declare une structure qui va permettre de selectionner uniquement certains com-
posants du graphe graph. Tout se comportera alors comme si les autres composants nexis-
taient pas.
Ligne 134 On ajoute le nud n
1
.
Ligne 135 On ajoute le nud n
2
.
Ligne 136 On ajoute le port p
12
.
Ligne 137 On ajoute le port p
21
.
Ligne 138 On ajoute le lien pl
1221
.
Ligne 140 On cree un containeur diterateur de nuds qui appartiennent au sous graphe fsgs
allSubNodes. Ce containeur va permettre de construire literateur permettant de parcourir
tous les nuds du sous graphe fsgs.
Lignes 141,142 On declare literateur de nuds n
i
du sous graphe fsgs. On va faire parcourir
`a cet iterateur lensemble des nuds du sous graphe fsgs jusqu`a atteindre literateur
allSubNodes.end() DISPLAY EXPR(*ni) ; // On ache la valeur associee au nud
n
i
.
Ligne 145 On cree un containeur diterateur de liens de n
1
qui appartiennent au sous graphe
fsgs subLinksOfNode. Ce containeur va permettre de construire literateur permettant de
parcourir tous les liens du nud n
1
du sous graphe fsgs.
Copyright c 2003 Soluscience 75
CHAPITRE 12. TUTORIAL
Lignes 146,147 On declare literateur de liens du nud n
1
, l
n1i
du sous graphe fsgs. On va
faire parcourir `a cet iterateur lensemble des liens du nud n
1
du sous graphe fsgs jusqu`a
atteindre literateur subLinksOfNode.end()
Ligne 148 On ache la valeur associee au nud l
n1i
.
Ligne 151 On cree un containeur diterateur de nuds voisins de n
1
qui appartiennent au
sous graphe fsgs subNodesOfNode. Ce containeur va permettre de construire literateur
permettant de parcourir tous les voisins du nud n
1
du sous graphe fsgs.
Lignes 152,153 On declare literateur de voisins du nud n
1
, n
n1i
du sous graphe fsgs. On
va faire parcourir `a cet iterateur lensemble des voisins du nud n
1
du sous graphe fsgs
jusqu`a atteindre literateur subNodesOfNode.end()
Ligne 154 On ache la valeur associee au nud n
n1i
.
76 Copyright c 2003 Soluscience
Chapitre 13
Tutorial
Les sections qui suivent presentent dierents exemples dutilisation de la librairie de graphe.
Tous les codes se trouvent dans le repertoire :
Pole/demos/graph
Des projets visual C++, gcc et CodeWarrior sont disponibles :
Visual C++ : SimpleG.dsp et HierarG.dsp dans le repertoire des chiers.
gcc : Pas encore disponible.
CodeWarrior : Importer GraphTest.mcp.xml dans le repertoire Pole/CW xml/projects/demo/
t
u
t
o
r
i
a
l
/
h
i
e
r
a
r
c
h
i
q
u
e
.
t
e
x
13.1 Creation dun graphe hierarchique
Pole/demos/graph/hctors.cpp
Le code presente permet de realiser un graphe hierarchique et de tester dierentes fonction-
nalites existentes sur ce type de structures.
1 /*
2 Cette methode decrit la creation dun mod`ele `a partir dun graphe hierarchique.
3 */
4 void ctor_graph1(HierarchicalGraphLib& graph)
5 {
6
7
8
9
10 HierarchicalGraphLib::InternalModelId m1 = graph.CreateModel();
11 names[m1] = "m1";
12
13
14 GraphModelOfLib::InternalNodeId N1 = m1->CreateNode();
15 GraphModelOfLib::InternalPortId p11 = m1->CreatePort(N1);
16 GraphModelOfLib::InternalPortId p10 = m1->CreatePort();
17 GraphModelOfLib::InternalPortId p20 = m1->CreatePort();
18 GraphModelOfLib::InternalLinkId L = m1->CreateLink(p11,p10);
19 names[N1] = "N1";
20 names[p11] = "p11";
21 names[p10] = "p10";
22 names[p20] = "p20";
23 names[L] = "L";
24
25
26
Copyright c 2003 Soluscience 77
CHAPITRE 13. TUTORIAL
27
28
29
30
31
32 HierarchicalGraphLib::InternalModelId m2 = graph.CreateModel();
33 names[m2] = "m2";
34
35
36 GraphModelOfLib::InternalNodeId Nm1 = m2->CreateNode(m1);
37 GraphModelOfLib::InternalPortId p21 = m2->GetLocalFreePort(Nm1,p10);
38 GraphModelOfLib::InternalNodeId Nm2 = m2->CreateNode(m1);
39 GraphModelOfLib::InternalPortId p22 = m2->GetLocalFreePort(Nm2,p10);
40 GraphModelOfLib::InternalPortId p220= m2->GetLocalFreePort(Nm2,p20);
41 GraphModelOfLib::InternalPortId p01 = m2->CreatePort();
42 GraphModelOfLib::InternalPortId p02 = m2->CreatePort();
43 GraphModelOfLib::InternalLinkId L12 = m2->CreateLink(p21,p22);
44 GraphModelOfLib::InternalLinkId L1 = m2->CreateLink(p210,p02);
45 GraphModelOfLib::InternalLinkId L2 = m2->CreateLink(p01,p220);
46 names[Nm1] = "Nm1";
47 names[p21] = "p21";
48 names[p210]= "p210";
49 names[Nm2] = "Nm2";
50 names[p22] = "p22";
51 names[p220]= "p220";
52 names[L12] = "L12";
53 names[p01] = "p01";
54 names[p02] = "p02";
55 names[L1] = "L1";
56 names[L2] = "L2";
57
58
59
60 HierarchicalGraphLib::InternalModelId m3 = graph.CreateModel();
61 names[m3] = "m3";
62
63
64 GraphModelOfLib::InternalNodeId Nm21 = m3->CreateNode(m2);
65 GraphModelOfLib::InternalPortId p311 = m3->GetLocalFreePort(Nm21,p01);
66 GraphModelOfLib::InternalPortId p321 = m3->GetLocalFreePort(Nm21,p02);
67
68
69 #define POST_MODEL 0
70 #if POST_MODEL
71 GraphModelOfLib::InternalNodeId Nm22 = m3->CreateNode();
72 GraphModelOfLib::InternalPortId p312 = m3->CreatePort(Nm22);
73 GraphModelOfLib::InternalPortId p322 = m3->CreatePort(Nm22);
74 GraphModelOfLib::InternalPortId p332 = m3->CreatePort(Nm22);
75 #else
76 GraphModelOfLib::InternalNodeId Nm22 = m3->CreateNode(m2);
77 GraphModelOfLib::InternalPortId p312 = m3->GetLocalFreePort(Nm22,p01);
78 GraphModelOfLib::InternalPortId p322 = m3->GetLocalFreePort(Nm22,p02);
79 #endif
80
81 GraphModelOfLib::InternalLinkId LL1 = m3->CreateLink(p311,p312);
82
83
84 names[Nm22] = "Nm22";
85 names[p311] = "p311";
86 names[p312] = "p312";
78 Copyright c 2003 Soluscience
87 names[p321] = "p321";
88 names[p322] = "p322";
89 names[LL1] = "LL1";
90
91
92
93 DISPLAY_MODEL(m1,GraphModelOfLib,HierarchicalGraphLib);
94 DISPLAY_MODEL(m2,GraphModelOfLib,HierarchicalGraphLib);
95
96
97 DISPLAY_MODEL(m3,GraphModelOfLib,HierarchicalGraphLib);
98 cout<<"Premier appel m3"<<endl;
99 display_dependencies(graph);
100
101
102 GraphModelOfLib::PortTranslator t;
103 #if POST_MODEL
104 t[p312] = p01;
105 m3->SetModel(Nm22,m2,t);
106 #endif
107
108 cout<<"Deux appel m3"<<endl;
109 DISPLAY_MODEL(m3,GraphModelOfLib,HierarchicalGraphLib);
110 display_dependencies(graph);
111
112
113 m3->SetModel(Nm22,0);
114 cout<<"Trois appel m3"<<endl;
115 DISPLAY_MODEL(m3,GraphModelOfLib,HierarchicalGraphLib);
116 display_dependencies(graph);
117
118
119 t[p312] = p02;
120 set<GraphModelOfLib::InternalPortId> deletedP;
121 m3->SetModel(Nm22,m2,t,deletedP,true);
122 cout<<"Effacement"<<endl;
123 for (set<GraphModelOfLib::InternalPortId>::const_iterator pi = deletedP.begin(); pi != deletedP.end(
124 ); ++pi)
125 {
126 cout<<names[*pi]<<endl;
127 names.erase(*pi);
128 }
129 cout<<"---------------------"<<endl;
130 cout<<"Quatre appel m3"<<endl;
131 DISPLAY_MODEL(m3,GraphModelOfLib,HierarchicalGraphLib);
132 display_dependencies(graph);
133 }
Ligne 10 On cree un mod`ele m
1
`a partir du graph. m
1
est un pointeur qui sert de cle pour
atteindre des informations de ce mod`ele.
Ligne 11 On associe `a la cle m
1
, la chane de caract`ere m1. names est une map entre void*
et string. Il faut noter quavec ce type de map, on peut associer nimporte quel type de
donnees aux cles des composants des graphes.
Ligne 14 Dans le mod`ele m
1
, on cree un nud avec la cle N
1
.
Ligne 15 Dans le mod`ele m
1
, on cree un port avec la cle p
11
dans le nud de cle N
1
.
Ligne 16 Dans m
1
, on cree un port libre p
10
. Les ports libres sont des points dacc`es vers le
mod`ele m
1
.
Copyright c 2003 Soluscience 79
CHAPITRE 13. TUTORIAL
Ligne 17 Dans m
1
, on cree un port libre p
20
.
Ligne 18 dans m
1
, on cree la liaison L entre les ports p
11
et le port p
10
.
Ligne 19 On associe au nud N
1
la chane de caract`ere N1
Ligne 20 On associe au nud p
11
la chane de caract`ere p11
Ligne 21 On associe au nud p
10
la chane de caract`ere p10
Ligne 22 On associe au nud p
20
la chane de caract`ere p20
Ligne 23 On associe au nud L la chane de caract`ere L
Ligne 32 On cree un nouveau mod`ele avec la cle m
2
.
Ligne 33 On associe `a ce nouveau mod`ele m
2
, la chane de caract`ere m2.
Ligne 36 Dans m
2
, on cree un nud N
m1
de mod`ele m
1
. Ce nud permet dacceder aux
informations de graphe de mod`ele m
1
.
Ligne 37 Dans m
2
, on cree un port exterieur p
21
sur le nud n
m1
qui correspond au port p
10
dans le mod`ele m
1
. On ne peut faire ce type doperation que sur des ports libres du mod`ele
en question. GraphModelOfLib : :InternalPortId p210= m2-GetLocalFreePort(Nm1,p20) ;//Dans
m
2
, on cree un port exterieur p
210
sur le nud n
m1
qui correspond au port p
20
dans le
mod`ele m
1
.
Ligne 38 Dans m
2
, on cree un nouveau nud N
m2
de mod`ele m
1
.
Ligne 39 Dans m
2
, on cree un port exterieur p
22
sur le nud n
m2
qui correspond au port p
10
dans le mod`ele m
1
.
Ligne 40 Dans m
2
, on cree un port exterieur p
220
sur le nud n
m2
qui correspond au port p
20
dans le mod`ele m
1
.
Ligne 41 Dans m
2
, on cree un port libre p
01
.
Ligne 42 Dans m
2
, on cree un second port libre p
02
.
Ligne 43 On cree une liaison entre les ports p
21
et p
22
avec la cle L
12
. Notez que lon peut creer
des liens sur nimporte quel type de ports (libre, de nud, exterieur)
Ligne 44 On cree une liaison entre les ports p
210
et p
02
avec la cle L
1
.
Ligne 45 On cree une liaison entre les ports p
01
et p
220
avec la cle L
2
.
Ligne 46 On associe au nud N
m1
, la chane de caract`ere Nm1.
Ligne 47 On associe au port p
21
, la chane de caract`ere p21.
Ligne 48 On associe au port p
210
, la chane de caract`ere p21.
Ligne 49 On associe au nud N
m2
, la chane de caract`ere Nm2.
Ligne 50 On associe au port p
22
, la chane de caract`ere p22.
Ligne 51 On associe au port p
220
, la chane de caract`ere p220.
Ligne 52 On associe au lien L
12
, la chane de caract`ere L12.
Ligne 53 On associe au port p
01
, la chane de caract`ere p01.
Ligne 54 On associe au port p
02
, la chane de caract`ere p02.
Ligne 55 On associe au lien L
1
, la chane de caract`ere L1.
Ligne 56 On associe au lien L
2
, la chane de caract`ere L2.
Ligne 59 Construct m3 : Nm21()-LL-()Nm22
80 Copyright c 2003 Soluscience
Ligne 60 On cree un nouveau mod`ele m
3
avec la cle m3.
Ligne 61 On associe `a ce nouveau mod`ele m
3
, la chane de caract`ere m3.
Ligne 64 Dans m
3
, on cree le nud N
m21
de mod`ele m
2
.
Ligne 65 Dans m
3
, on associe un port exterieur p
311
du nud N
m21
au port libre p
01
du mod`ele
m
2
.
Ligne 66 Dans m
3
, on associe un port exterieur p
321
du nud N
m21
au port libre p
02
du mod`ele
m
2
.
Ligne 69 On denit deux cas possible de creation de port exterieur associe aux ports libres de
mod`ele m
2
represente par un nouveau nud N
m22
.
Ligne 70 Le cas de denition de ces nuds apr`es coup. On denit dabord un nud sans
mod`eles avec des ports associes `a ce nud.
Ligne 71 Dans m
3
, on cree un nud sans mod`ele N
m22
.
Ligne 72 Dans m
3
, on cree le port p
312
dans le nud N
m22
.
Ligne 73 Dans m
3
, on cree le port p
322
dans le nud N
m22
.
Ligne 74 Dans m
3
, on cree le port p
332
dans le nud N
m22
.
Ligne 75 Le cas identique aux precedents nuds de mod`eles.
Ligne 76 Dans m
3
, on cree le nud N
m22
de mod`ele m
2
.
Ligne 77 Dans m
3
, on cree un port exterieur p
312
dans le nud N
m22
associe au port libre p
01
du mod`ele m
2
.
Ligne 78 Dans m
3
, on cree un port exterieur p
322
dans le nud N
m22
associe au port libre p
02
du mod`ele m
2
.
Ligne 81 On cree la liaison L
L1
entre les ports p
311
et p
312
.
Ligne 84 On associe au nud N
m22
la chane de caract`ere Nm22.
Ligne 85 On associe au port p
311
la chane de caract`ere p311.
Ligne 86 On associe au port p
312
la chane de caract`ere p312.
Ligne 87 On associe au port p
321
la chane de caract`ere p321.
Ligne 88 On associe au port p
322
la chane de caract`ere p322.
Ligne 89 On associe au port L
L1
la chane de caract`ere LL1.
Ligne 93 On ache en format texte le mod`ele m
1
.
Ligne 94 On ache en format texte le mod`ele m
2
.
Ligne 97 On ache en format texte le mod`ele m
3
.
Ligne 99 On ache les dependances m
3
.
Ligne 102 Dans le cas o` u lon na pas encore accroche les ports p
312
et p
322
aux ports libres
p
01
et p
02
du mod`ele m
2
, on va creer une structure appelee translateur pour transformer
les ports non associes en port associe.
Ligne 104 On indique que lon va translater le port p
312
pour lassocier au port libre p
01
du
mod`ele m
2
.
Ligne 105 On realise cette translation, en indiquant que lon souhaite que le nud N
m22
doit maintenant representer le mod`ele m
2
avec linformation de translation de la ligne
precedente. Sans autre argument, les ports non reaectes sont conserves.
Copyright c 2003 Soluscience 81
CHAPITRE 13. TUTORIAL
Ligne 109 On ache le mod`ele m
3
.
Ligne 110 On ache les dependances.
Ligne 113 On desaecte le nud N
m22
du mod`ele m
2
.
Ligne 115 On reache le mod`ele m
3
Ligne 116 on ache les dependances du graphe hierarchique.
Ligne 119 On modie le translateur pour reaecter de nouveau le nud N
m22
au mod`ele m
2
.
Cela va causer la destruction de certains ports que lon va recuperer pour mettre `a jour
les informations associes aux dierentes cles de composants.
Ligne 120 Structure de stockage des ports qui vont etre detruits.
Ligne 121 On eectue la modication. Le dernier param`etre booleen indique que lon va
detruire les ports sans aectation.
Lignes 123,124 On eace les donnees associes aux ports detruits.
Ligne 126 On indique le nom de la chane de caract`ere que lon va detruire.
Ligne 127 On detruit cette information.
Ligne 131 on ache le mod`ele m
3
.
Ligne 132 on reache les dependances.
t
u
t
o
r
i
a
l
/
h
i
e
r
a
r
c
h
i
q
u
e
.
t
e
x
13.2 Creation dun graphe hierarchique recurif
On realise un graphe hierachique recursif, cest `a dire quun des noeuds dun mod`ele est le
mod`ele lui meme.
1 void ctor_graph3(HierarchicalGraphLib& graph)
2 {
3 /* Construct m1 : <N2/m1>(p10:po)-L2-(p12)N1(p11)-L1-(p10)*/
4 HierarchicalGraphLib::InternalModelId m1 = graph.CreateModel();
5 names[m1] = "m1";
6
7
8 GraphModelOfLib::InternalNodeId N1 = m1->CreateNode();
9 GraphModelOfLib::InternalPortId p11 = m1->CreatePort(N1);
10 GraphModelOfLib::InternalPortId p12 = m1->CreatePort(N1);
11 GraphModelOfLib::InternalPortId p10 = m1->CreatePort();
12 GraphModelOfLib::InternalLinkId L1 = m1->CreateLink(p11,p10);
13 names[N1] = "N1";
14 names[p11] = "p11";
15 names[p12] = "p12";
16 names[p10] = "p10";
17 names[L1] = "L1";
18
19
20 GraphModelOfLib::InternalNodeId N2 = m1->CreateNode(m1);
21 GraphModelOfLib::InternalPortId po = m1->GetLocalFreePort(N2,p10);
22 names[N2] = "N2";
23 names[po] = "po";
24 names[L2] = "L2";
25 DISPLAY_MODEL(m1,GraphModelOfLib,HierarchicalGraphLib);
26 }
Ligne 4 Avec le graphe hierarchique, on cree le mod`ele m
1
.
82 Copyright c 2003 Soluscience
Ligne 5 On associe `a ce mod`ele une information sous la forme dune chane de caract`ere de
valeur m1. names est une map entre des cles sous la forme de pointeur et des chanes de
caract`eres. On peut ainsi associer nimporte quelle information aux composants de graphes
crees.
Ligne 8 Dans m
1
, on cree le nud N
1
.
Ligne 9 Dans m
1
, on cree le port p
11
dans le nud N
1
.
Ligne 10 Dans m
1
, on cree le port p
12
dans le nud N
1
.
Ligne 11 On cree un port libre p
10
dans m
1
. Seuls les ports libres sont accessibles dans les
nuds qui representeront le mod`ele m
1
.
Ligne 12 On cree la liaison L
1
entre les ports p
11
et p
10
.
Ligne 13 On associe au nud N
1
la chane de caract`ere N1.
Ligne 14 On associe au port p
11
la chane de caract`ere p11.
Ligne 15 On associe au port p
12
la chane de caract`ere p12.
Ligne 16 On associe au port p
10
la chane de caract`ere p10.
Ligne 17 on associe au lien L
1
la chane de caract`ere L1
Ligne 20 Dans m
1
, on cree le nud N
2
qui represente m
1
lui meme. Il sagit dun graphe
hierachique recursif.
Ligne 21 On cree sur le nud N
2
un port exterieur p
0
qui est associe au port libre p
1
0 du
mod`ele m
1
. GraphModelOfLib : :InternalLinkId L2 = m1-CreateLink(po,p12) ;//On cree
la liaison l
2
entre les ports p
0
et p
12
.
Ligne 22 On associe au nud N
2
, la chane de caract`ere N2.
Ligne 23 On associe au port p
0
, la chane de caract`ere p0.
Ligne 24 On associe au lien L
2
, la chane de caract`ere L2.
Ligne 25 On ache sous format texte le mod`ele m
1
t
u
t
o
r
i
a
l
/
s
u
b
m
o
d
e
l
.
t
e
x
13.3 Utilisation de sous mod`eles
Pole/demos/graph/hctors2.cpp
Il peut etre interessant de transformer un ensemble de nuds en mod`ele pour faciliter
lecriture de graphes hierarchique. Lexemple suivant presente comment realiser cette operation.
1 void ctor_graph2(HierarchicalGraphLib& graph)
2 {
3
4 HierarchicalGraphLib::InternalModelId m1 = graph.CreateModel();
5 names[m1] = "m1";
6
7
8 GraphModelOfLib::InternalNodeId N1 = m1->CreateNode();
9 GraphModelOfLib::InternalPortId p11 = m1->CreatePort(N1);
10 GraphModelOfLib::InternalPortId p12 = m1->CreatePort(N1);
11 GraphModelOfLib::InternalNodeId N2 = m1->CreateNode();
12 GraphModelOfLib::InternalPortId p21 = m1->CreatePort(N2);
13 GraphModelOfLib::InternalPortId p22 = m1->CreatePort(N2);
14 GraphModelOfLib::InternalLinkId L1 = m1->CreateLink(p11,p21);
15 GraphModelOfLib::InternalNodeId N3 = m1->CreateNode();
16 GraphModelOfLib::InternalPortId p31 = m1->CreatePort(N3);
Copyright c 2003 Soluscience 83
CHAPITRE 13. TUTORIAL
17 GraphModelOfLib::InternalLinkId L2 = m1->CreateLink(p31,p22);
18
19
20 names[N1] = "N1";
21 names[p11] = "p11";
22 names[p12] = "p12";
23 names[N2] = "N2";
24 names[p21] = "p21";
25 names[p22] = "p22";
26 names[N3] = "N3";
27 names[p31] = "p31";
28 names[L1] = "L1";
29 names[L2] = "L2";
30
31
32 DISPLAY_MODEL(m1,GraphModelOfLib,HierarchicalGraphLib);
33
34
35
36 set<GraphModelOfLib::InternalNodeId> nodes;
37 GraphModelOfLib::InternalPortId po21 = L1->second;
38 GraphModelOfLib::InternalNodeId N2child = po21->node;
39 GraphModelOfLib::InternalPortId pi21 = m1->GetFreePort(po21);
40 GraphModelOfLib::InternalLinkId ls1 = pi21->link;
41 GraphModelOfLib::InternalPortId po22 = L2->second;
42 GraphModelOfLib::InternalPortId pi22 = m1->GetFreePort(po22);
43 GraphModelOfLib::InternalLinkId ls2 = pi22->link;
44 names[m2] = "m2";
45 names[pi21] = "pi21";
46 names[po21] = "po21";
47 names[ls1] = "ls1";
48 names[pi22] = "pi22";
49 names[po22] = "po22";
50 names[ls2] = "ls2";
51 names[N2child] = "N2child";
52
53
54 DISPLAY_MODEL(m1,GraphModelOfLib,HierarchicalGraphLib);
55 DISPLAY_MODEL(m2,GraphModelOfLib,HierarchicalGraphLib);
56
57
58
59 nodes.clear();
60 nodes.insert(N2child);
61 nodes.insert(N3);
62 HierarchicalGraphLib::InternalModelId m3 = graph.CreateSubModel(m1,nodes);
63 GraphModelOfLib::InternalPortId po3 = L1->second;
64 GraphModelOfLib::InternalNodeId N3child = po3->node;
65 GraphModelOfLib::InternalLinkId ls3 = pi3->link;
66 names[m3] = "m3";
67 names[pi3] = "pi3";
68 names[po3] = "po3";
69 names[ls3] = "ls3";
70 names[N3child] = "N3child";
71
72
73 DISPLAY_MODEL(m1,GraphModelOfLib,HierarchicalGraphLib);
74 DISPLAY_MODEL(m2,GraphModelOfLib,HierarchicalGraphLib);
75 DISPLAY_MODEL(m3,GraphModelOfLib,HierarchicalGraphLib);
76
84 Copyright c 2003 Soluscience
77
78 GraphModelOfLib::InternalNodeId N4 = m1->CreateNode(m3);
79 GraphModelOfLib::InternalPortId p41 = m1->GetLocalFreePort(N4,pi3);
80 GraphModelOfLib::InternalLinkId L3 = m1->CreateLink(p12,p41);
81 names[N4] = "N4";
82 names[p41] = "p41";
83 names[L3] = "L3";
84
85
86 DISPLAY_MODEL(m1,GraphModelOfLib,HierarchicalGraphLib);
87 }
Ligne 3 Construct m1 : (p12)N1(p11)-L1-(p21)N2(p22)-L2-(p31)N3
Ligne 4 A partir du graphe hierarchique graph, on cree un nouveau mod`ele m
1
.
Ligne 5 On associe `a la cle du mod`ele m
1
(son adresse), une information sous la forme dune
chane de caract`ere de valeur m1. names est une map entre des cles sous la forme de pointeur
et des chanes de caract`eres.
Ligne 8 Dans m
1
, on cree un nud N
1
.
Ligne 9 Dans m
1
, on cree un port p
11
dans le nud N
1
.
Ligne 10 Dans m
1
, on cree un port p
12
dans le nud N
1
.
Ligne 11 Dans m
1
, on cree un nud N
2
.
Ligne 12 Dans m
1
, on cree un port p
21
dans le nud N
2
.
Ligne 13 Dans m
1
, on cree un port p
22
dans le nud N
2
.
Ligne 14 Dans m
1
, on cree la liaison L
1
entre les ports p
11
et p
21
.
Ligne 15 Dans m
1
, on cree un nud N
3
.
Ligne 16 Dans m
1
, on cree un port p
31
dans le nud N
3
.
Ligne 17 Dans m
1
, on cree la liaison L
2
entre les ports p
31
et p
22
.
Ligne 20 On associe au nud N
1
, la chane de caract`ere N1.
Ligne 21 On associe au port p
11
, la chane de caract`ere p11.
Ligne 22 On associe au port p
12
, la chane de caract`ere p12.
Ligne 23 On associe au nud N
2
, la chane de caract`ere N2.
Ligne 24 On associe au port p
21
, la chane de caract`ere p21.
Ligne 25 On associe au port p
22
, la chane de caract`ere p22.
Ligne 26 On associe au nud N
3
, la chane de caract`ere N3.
Ligne 27 On associe au port p
31
, la chane de caract`ere p31.
Ligne 28 On associe au lien L
1
, la chane de caract`ere L1.
Ligne 29 On associe au lien L
2
, la chane de caract`ere L2.
Ligne 32 On ache le mod`ele m
1
.
Ligne 35 Construct m2 as submodel of N2 in m1
Ligne 36 On declare un ensemble de nud dans lequel on va declarer le sous mod`ele sur lequel
on va travailler. nodes.insert(N2) ;//On declare lensemble de nud du sous mod`ele comme
etant egal au nud N
2
. HierarchicalGraphLib : :InternalModelId m2 = graph.CreateSubModel(m1,nodes) ;//On
cree le sous mod`ele m
2
`a partir de lensemble de nud nodes de m
1
.
Copyright c 2003 Soluscience 85
CHAPITRE 13. TUTORIAL
Ligne 37 Pour retrouver le port exterieur p
021
dans m
1
qui correspondait au port p
21
ancien-
nement dans m
1
, on regarde le bout de la liaison L
1
.
Ligne 38 Le nouveau nud N
2child
de mod`ele m
2
cree dans m
1
est recupere comme etant le
nud du port p
021
Ligne 39 Dans m
2
, on trouve le port le port libre p
i21
associe au port p
021
.
Ligne 40 On trouve le lien l
s1
qui relie le port p
i21
au port p
21
dans m
2
.
Ligne 41 Dans m
1
, on retrouve le port exterieur qui correspondait initialement au port p
22
dans m
1
.
Ligne 42 Dans m
2
, on trouve le port le port libre p
i22
associe au port p
022
.
Ligne 43 On trouve le lien l
s2
qui relie le port p
i22
au port p
22
dans m
2
.
Ligne 44 On associe `a la cle (le pointeur) du mod`ele m
2
`a la chane de caract`ere m2.
Ligne 45 On associe `a la cle (le pointeur) du port p
i21
`a la chane de caract`ere pi21.
Ligne 46 On associe `a la cle (le pointeur) du port p
021
`a la chane de caract`ere p021.
Ligne 47 On associe `a la cle (le pointeur) du lien l
s1
`a la chane de caract`ere ls1.
Ligne 48 On associe `a la cle (le pointeur) du port p
i22
`a la chane de caract`ere pi22.
Ligne 49 On associe `a la cle (le pointeur) du port p
022
`a la chane de caract`ere p022.
Ligne 50 On associe `a la cle (le pointeur) du lien l
s2
`a la chane de caract`ere ls2.
Ligne 51 On associe `a la cle (le pointeur) du nud N
2child
`a la chane de caract`ere N2child.
Ligne 54 On ache le mod`ele m
1
.
Ligne 55 On ache le mod`ele m
2
.
Ligne 58 Construct m3 as submodel of N2child,N3 in m1
Ligne 59 On eace lancien ensemble de nud. On va creer un sous mod`ele `a partir des nud
N
2child
nouvellement cree et du nud N
3
.
Ligne 60 On ajoute `a lensemble de nud, le nud N
2child
.
Ligne 61 On ajoute `a lensemble de nud, le nud N
3
.
Ligne 62 On cree le sous mod`ele m
3
dans m
1
`a partir de lensemble de nuds nodes.
Ligne 63 On recup`ere le port exterieur p
03
qui correspondait au port p
021
de lancien nud
N
2child
comme extremite nale du lien L
1
.
Ligne 64 On recup`ere le nouveau nud N
3child
de mod`ele m
3
qui a ete cree comme nud du
port p
03
. Dans m
3
, on recup`ere le port libre p
i3
qui correspond au port p
03
dans m
1
.
Ligne 65 Dans m
3
, on recup`ere le lien qui reunit le port libre p
i3
au port p
021
de N
2child
.
Ligne 66 On associe `a la cle (le pointeur) du mod`ele m
3
`a la chane de caract`ere m3.
Ligne 67 On associe `a la cle (le pointeur) du port p
i3
`a la chane de caract`ere pi3.
Ligne 68 On associe `a la cle (le pointeur) du port p
O3
`a la chane de caract`ere p03.
Ligne 69 On associe `a la cle (le pointeur) du lien l
s3
`a la chane de caract`ere ls3.
Ligne 70 On associe `a la cle (le pointeur) du nud N
3child
`a la chane de caract`ere N3child.
Ligne 73 On ache le mod`ele m
1
.
Ligne 74 On ache le mod`ele m
2
.
Ligne 75 On ache le mod`ele m
3
.
86 Copyright c 2003 Soluscience
Ligne 78 Dans m
1
, on cree un nud N
4
de mod`ele m
3
.
Ligne 79 Dans m
1
, on cree un port exterieur p
41
du nud N
4
de mod`ele m
3
correspondant au
port p
i3
du mod`ele m
3
.
Ligne 80 On cree le lien L
3
entre les ports p
12
et p
41
.
Ligne 81 On associe `a la cle (le pointeur) du nud N
4
`a la chane de caract`ere N4.
Ligne 82 On associe `a la cle (le pointeur) du port p
41
`a la chane de caract`ere p41.
Ligne 83 On associe `a la cle (le pointeur) du lien L
3
`a la chane de caract`ere L3.
Ligne 86 On ache le mod`ele m
1
.
Sixi`eme partie
Pour nir. . .
Copyright c 2003 Soluscience 89
Conclusion
Copyright c 2003 Soluscience 91
92 Copyright c 2003 Soluscience
Annexe A
Le reste du monde
a
n
n
e
x
e
s
/
r
d
m
A.1 Theorie de graphes
www.utm.edu/cgi-bin/caldwell/tutor/departments/math/graph/index.html
www.utc.edu/ cpmawata/petersen
a
n
n
e
x
e
s
/
r
d
m
A.2 Programmation de graphes
www.infosun.fmi.uni-passau.de/GTL
www.jgraph.com
a
n
n
e
x
e
s
/
r
d
m
A.3 Visualisation de graphes
www.absint.com
www.cs.brown.edu/people/rt/gd.html
dept-info.labri.u-bordeaux.fr/ auber/projects/tulip
graphdrawing.org
www.graphviz.org
www.ics.uci.edu/ eppstein/gina/gdraw.html
www.informatik.uni-bremen.de/daVinci
www.mpi-sb.mpg.de/AGD/index.html
rw4.cs.uni-sb.de/ sander/html/gsvcg1.html
www.cs.utk.edu/ plank/plank/jgraph/jgraph.html
hans.breuer.org/dia
a
n
n
e
x
e
s
/
r
d
m
A.4 Applications
www.prism.gatech.edu/ gte067k/xdrawchem
www.uku./ thassine/ghemical
Copyright c 2003 Soluscience 93
ANNEXE A. LE RESTE DU MONDE
94 Copyright c 2003 Soluscience
BIBLIOGRAPHIE
Bibliographie
[COR90] Introduction `a lalgorithmique, Thomas Cormen, Charles Leiserson, Ronald Ri-
vest, Dunod, Paris, 1994
[GON79] Graphes et algorithmes, M. Gondran, M. Minoux, Eyrolles, Paris, 1979
Copyright c 2003 Soluscience 95