Changes between Version 2 and Version 3 of CaoCourseTme8


Ignore:
Timestamp:
Apr 4, 2007, 6:03:09 PM (18 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • CaoCourseTme8

    v2 v3  
    99On souhaite implanter en langage C un algorithme de partitionnement de graphe utilisant
    1010la méthode Min-Cut, dont le principe a été présenté en cours.
    11 
    12 {{{
    13 #!html
    14 <h1>TME 8 : Partitionnement de Graphe/MinCut</h1>
    15 }}}
    1611
    1712= A. Introduction =
     
    182177On dispose d'un ensemble de fonctions permettant de construire et de manipuler les deux structures de données graph_t et move_manager_t.
    183178
    184 == D.1. graph_t * parse_graph(char *filename) ==
    185 
    186 Cette fonction prend pour argument un nom de fichier au format.dot
    187 représentant le graphe à partitionner, et construit en mémoire la structure
    188 graph_t correspondante, et renvoie un pointeur sur cette structure. Si aucune
    189 partition initiale n'est définie dans le fichier .dot, les noeuds d'index
    190 inférieur à NBNODE/2 sont arbitrairement rangés dans le sous-ensemble L,
    191 et les noeuds d'index supérieur à NBNODE/2 sont rangés dans le sous-ensemble R.
    192 
    193 Un exemple de fichier au format .dot est donné ci-dessous. Les noeuds du graphe
    194 sont identifiés par un index, il y a une ligne par arête, les deux sous-graphes
    195 cluster0 et cluster1 définissent la partition initiale et sont optionnels.
     179 '''graph_t * parse_graph(char *filename)'''::
     180        Cette fonction prend pour argument un nom de fichier au format.dot
     181        représentant le graphe à partitionner, et construit en mémoire la structure
     182        graph_t correspondante, et renvoie un pointeur sur cette structure. Si aucune
     183        partition initiale n'est définie dans le fichier .dot, les noeuds d'index
     184        inférieur à NBNODE/2 sont arbitrairement rangés dans le sous-ensemble L,
     185        et les noeuds d'index supérieur à NBNODE/2 sont rangés dans le sous-ensemble R.
     186
     187        Un exemple de fichier au format .dot est donné ci-dessous. Les noeuds du graphe
     188        sont identifiés par un index, il y a une ligne par arête, les deux sous-graphes
     189        cluster0 et cluster1 définissent la partition initiale et sont optionnels.
    196190
    197191{{{
     
    211205}}}
    212206
    213 == D.2. void drive_graph(graph_t *p, char *filename) ==
    214 
    215 Cette fonction prend en paramètre un pointeur p sur une structure graph_t,
    216 ainsi que le nom du fichier de sortie, et écrit sur disque un fichier au
    217 format .dot, en conservant dans le fichier les informations de partition
    218 (sous-ensemble L et R). Ce format est affichable sous forme graphique et
    219 permet de visualiser la partition.
    220 
    221 == D.3. bichain_t * cons_bichain (bichain_t *prev, bichain_t *next, unsigned inode, int igain, unsigned part) ==
    222 
    223 Cette fonction alloue la mémoire nécessaire pour créer un élément d'une liste
    224 doublement chaînée, elle initialise les différents champs de cette structure,
    225 et renvoie un pointeur sur cette structure.
    226 
    227 == D.4. void free_bichain (bichain_t *p) ==
    228 
    229 Cette fonction libère la mémoire allouée lors de la construction de l'objet
    230 bichain_t par la donction cons_bichain().
    231 
    232 == D.5. move_manager_t * cons_move_manager(graph_t *p) ==
    233 
    234 Cette fonction pend pour argument un pointeur sur la structure représentant
    235 le graphe partitionné, et construit en mémoire la structure move_manager_t
    236 correspondant à cette partition.
    237 
    238 == D.6. void add_node (move_manager_t *mm, bichain_t *node) ==
    239 
    240 Cette fonction prend pour arguments un pointeur sur la structure représentant
    241 les gestionnaire de mouvements, un pointeur sur un élément de liste doublement
    242 chaînée (représentant un noeud), contenant l'index du nSud dans le graphe,
    243 un entier représentant l'index dans le tableau GAIN_R ou GAIN_L, et un entier
    244 définissant le sous-ensemble d'appartenance (0 pour R, 1 pour L). Elle range
    245 ce noeud dans la liste doublement chaînée correspondante, elle met à jour
    246 le tableau NODES et les index LX ou LR. Les champs NEXT et PREV du nSud ne
    247 sont pas utilisés, ils sont initialisés par la fonction add_node elle-même.
    248 
    249 == D.7. bichain_t * del_node(move_manager_t *mm, bichain_t *node) ==
    250 
    251 cette fonction prend pour arguments un pointeur sur la structure représentant
    252 les gestionnaire de mouvements, et un pointeur sur un élément de liste
    253 doublement chaînée (représentant un noeud). Elle retire cet élément de la
    254 liste doublement chaînée, et renvoie un pointeur sur la structure bichain_t
    255 pour une éventuelle libération de la mémoire.
    256 
    257 == D.8. int compute_gain (graph_t *g, unsigned index) ==
    258 
    259 Cette fonction prend pour argument un pointeur sur la structure représentant le
    260 graphe, un index désignant un noeud particulier, et calcule le gain associé
    261 à ce noeud, pour la partition courante.
    262 
    263 == D.9. int global_cost (graph_t *g) ==
    264 
    265 Cette fonction prend pour argument un pointeur sur la structure représentant
    266 le graphe, calcule la fonction de coût globale pour la partition courante,
    267 et renvoie la valeur calculée.
     207 '''void drive_graph(graph_t *p, char *filename)'''::
     208        Cette fonction prend en paramètre un pointeur p sur une structure graph_t,
     209        ainsi que le nom du fichier de sortie, et écrit sur disque un fichier au
     210        format .dot, en conservant dans le fichier les informations de partition
     211        (sous-ensemble L et R). Ce format est affichable sous forme graphique et
     212        permet de visualiser la partition.
     213
     214 '''bichain_t * cons_bichain (bichain_t *prev, bichain_t *next, unsigned inode, int igain, unsigned part)'''::
     215        Cette fonction alloue la mémoire nécessaire pour créer un élément d'une liste
     216        doublement chaînée, elle initialise les différents champs de cette structure,
     217        et renvoie un pointeur sur cette structure.
     218
     219 '''void free_bichain (bichain_t *p)'''::
     220        Cette fonction libère la mémoire allouée lors de la construction de l'objet
     221        bichain_t par la donction cons_bichain().
     222
     223 '''move_manager_t * cons_move_manager(graph_t *p)'''::
     224        Cette fonction pend pour argument un pointeur sur la structure représentant
     225        le graphe partitionné, et construit en mémoire la structure move_manager_t
     226        correspondant à cette partition.
     227
     228 '''void add_node (move_manager_t *mm, bichain_t *node)'''::
     229        Cette fonction prend pour arguments un pointeur sur la structure représentant
     230        les gestionnaire de mouvements, un pointeur sur un élément de liste doublement
     231        chaînée (représentant un noeud), contenant l'index du nSud dans le graphe,
     232        un entier représentant l'index dans le tableau GAIN_R ou GAIN_L, et un entier
     233        définissant le sous-ensemble d'appartenance (0 pour R, 1 pour L). Elle range
     234        ce noeud dans la liste doublement chaînée correspondante, elle met à jour
     235        le tableau NODES et les index LX ou LR. Les champs NEXT et PREV du nSud ne
     236        sont pas utilisés, ils sont initialisés par la fonction add_node elle-même.
     237
     238 '''bichain_t * del_node(move_manager_t *mm, bichain_t *node)'''::
     239        cette fonction prend pour arguments un pointeur sur la structure représentant
     240        les gestionnaire de mouvements, et un pointeur sur un élément de liste
     241        doublement chaînée (représentant un noeud). Elle retire cet élément de la
     242        liste doublement chaînée, et renvoie un pointeur sur la structure bichain_t
     243        pour une éventuelle libération de la mémoire.
     244
     245 '''int compute_gain (graph_t *g, unsigned index)'''::
     246        Cette fonction prend pour argument un pointeur sur la structure représentant le
     247        graphe, un index désignant un noeud particulier, et calcule le gain associé
     248        à ce noeud, pour la partition courante.
     249
     250 '''int global_cost (graph_t *g)'''::
     251        Cette fonction prend pour argument un pointeur sur la structure représentant
     252        le graphe, calcule la fonction de coût globale pour la partition courante,
     253        et renvoie la valeur calculée.
    268254
    269255= E. Travail à réaliser =
     
    272258progressivement les fichiers objets fournis par vos propres fichiers objet.
    273259
    274 == E.1. Construction et initialisation du gestionnaire de mouvements ==
    275 
    276 C'est un point important puisque que c'est la structure de base de
    277 l'algorithme. Vous disposez pour vous aidez d'une fonction dump_move_manager()
    278 qui affiche le contenu de la structure.
    279 
    280 == E.2. Ecriture de l'algorithme MinCut glouton ==
    281 
    282 Ecrivez la boucle réalisant les transferts de cellules tant que le transfert
    283 d'une paire de cellules améliore la fonction de coût FC.
    284 
    285 == E.3. Exécution et évaluation ==
    286 
    287 Exécutez cet algorithme sur différents graphes que vous définirez
    288 vous-mêmes. La partition résultante est-elle toujours la partition
    289 optimale? Pourquoi? Donnez un contre-exemple.
    290 
    291 == E.4. Ecriture des fonctions ==
    292 
    293 Ecrire les différentes fonctions d'accès aux structures de données définies
    294 dans la partie D, et validez ces fonctions en les intégrant peu à peu dans
    295 votre programme.
    296 
    297 == E.5. construction du graphe en mémoire ==
    298 
    299 L'objectif est ici d'écrire la fonction parse_graph(), en utilisant lex et
    300 yacc. Nous vous suggérons de supposer qu'il n'y a pas de clusters dans le
    301 fichier, puis de les introduire. Si vous n'avez pas le temps de construire
    302 le graphe, étudiez au moins la grammaire de ce petit langage.
     260 '''1. Construction et initialisation du gestionnaire de mouvements'''::
     261       C'est un point important puisque que c'est la structure de base de
     262       l'algorithme. Vous disposez pour vous aidez d'une fonction dump_move_manager()
     263       qui affiche le contenu de la structure.
     264
     265 '''2. Ecriture de l'algorithme !MinCut glouton'''::
     266       Ecrivez la boucle réalisant les transferts de cellules tant que le transfert
     267       d'une paire de cellules améliore la fonction de coût FC.
     268
     269 '''3. Exécution et évaluation'''::
     270       Exécutez cet algorithme sur différents graphes que vous définirez
     271       vous-mêmes. La partition résultante est-elle toujours la partition
     272       optimale? Pourquoi? Donnez un contre-exemple.
     273
     274 '''4. Ecriture des fonctions'''::
     275       Ecrire les différentes fonctions d'accès aux structures de données définies
     276       dans la partie D, et validez ces fonctions en les intégrant peu à peu dans
     277       votre programme.
     278
     279 '''5. construction du graphe en mémoire'''::
     280       L'objectif est ici d'écrire la fonction parse_graph(), en utilisant lex et
     281       yacc. Nous vous suggérons de supposer qu'il n'y a pas de clusters dans le
     282       fichier, puis de les introduire. Si vous n'avez pas le temps de construire
     283       le graphe, étudiez au moins la grammaire de ce petit langage.