IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

maillage , table de connectivité


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mai 2010
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 79
    Points : 35
    Points
    35
    Par défaut maillage , table de connectivité
    bonjour

    voilà , ici je vous présente , le problème que je dois résoudre ,
    en gros j'ai un maillage à faire , il y a deux fichiers , le premier contient des points(noeuds) et chaque point a deux coordonnés . le second donne un tableau de triangle(chaque triangle est appelé élément) , dont chacun des point représente"un point du premier tableau"
    chaque élément passe donc par 3 noeuds
    chaque noeud a 2 coordonnées
    comment créer une table de connectivité entre chaque élément(triangle) et les noeuds qui le forment
    puis un tableau de connectivité entre chaque noeud et ses coordonnées ?
    si quelqu'un a une premiere idée ,

    merci d avance

  2. #2
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Bonsoir,
    Si j'ai bien compris, tu veux, à partir d'un élément, retrouver les nœuds qui le composent, et à partir d'un nœud, retrouver les éléments dans lesquels il intervient.

    Déjà, chaque élément devrait connaître tous les nœuds qui le composent, donc dans ce cas là je ne vois pas vraiment le problème.
    Enfin, tout dépend de ta représentation, mais conceptuellement, je ne vois pas de raison pour qu'il en soit autrement.

    Pour l'autre sens, je créerais un tableau associatif (dont les clés sont les nœuds et les valeurs sont les éléments) que je remplirais au fur et à mesure que les éléments sont construits.

    Une autre méthode serait de mettre un attribut membre dans la classe des nœuds qui aurait pour rôle de garder une référence vers les éléments impliqués.
    L'avantage de cette méthode est que, si elle est bien implémentée, le tableau se remplit tout seul en fonction des créations et destructions d'éléments.

    Mais encore une fois, tout dépend de ton implémentation, et ce que tu veux faire exactement avec ces « tables d'association ».
    Pourrais-tu mettre un peu de code et donner quelques précisions, s'il-te-plaît ?

    Cordialement.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mai 2010
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 79
    Points : 35
    Points
    35
    Par défaut c++, maillage table de connectivité
    voilà je vous présente un exemple
    j'ai un premier fichier
    qui se présente comme ci-dessous(les noeuds)
    "fichier2"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    30  2  0  1
       1    1  0    1
       2    0.80901699999999999  0.587785    1
       3    0.30901699999999999  0.95105700000000004    1
       4    -0.30901699999999999  0.95105700000000004    1
       5    -0.80901699999999999  0.587785    1
       6    -1  3.5897899999999999e-09    1
       7    -0.80901699999999999  -0.587785    1
       8    -0.30901699999999999  -0.95105700000000004    1
       9    0.30901699999999999  -0.95105700000000004    1
      10    0.80901699999999999  -0.587785    1
      11    3  0    2
      12    2.4270499999999999  1.76336    2
      13    0.92705099999999996  2.85317    2
      14    -0.92705099999999996  2.85317    2
      15    -2.4270499999999999  1.76336    2
      16    -3  1.07694e-08    2
      17    -2.4270499999999999  -1.76336    2
      18    -0.92705099999999996  -2.85317    2
      19    0.92705099999999996  -2.85317    2
      20    2.4270499999999999  -1.76336    2
      21    -1.8470647354641934  -0.60014770447655841    0
      22    -1.1415502165304945  -1.5712075628654207    0
      23    -1.1415502165304945  1.5712075628654207    0
      24    0  1.9421197131879349    0
      25    -1.8470647239512119  0.60014770806634843    0
      26    1.1415502165304945  -1.5712075628654207    0
      27    1.8470647297077027  -0.60014770627145331    0
      28    0  -1.9421197131879349    0
      29    1.1415502165304945  1.5712075628654207    0
      30    1.8470647297077027  0.60014770627145331    0

    et celui là (les éléments):
    "fichier1"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    40  3  0
       1       6    25    21
       2       6    21     7
       3      21    22     7
       4      19    26    28
       5      24    23     4
       6       7    22     8
       7      12    13    29
       8      13    14    24
       9      23    25     5
      10      21    25    16
      11      23    15    25
      12      23     5     4
      13      22    21    17
      14       4     3    24
      15       6     5    25
      16      15    16    25
      17      28    22    18
      18      24    29    13
      19      14    15    23
      20       9    26    10
      21      27     1    10
      22      22    28     8
      23      27    11    30
      24      26    20    27
      25       8    28     9
      26      17    18    22
      27      30    29     2
      28      16    17    21
      29       2    29     3
      30       2     1    30
      31      26    27    10
      32      19    20    26
      33      27    30     1
      34      14    23    24
      35      20    11    27
      36      29    24     3
      37      18    19    28
      38      28    26     9
      39      11    12    30
      40      29    30    12
    le principe est le suivant :

    pour le "fichier1":
    la premiere ligne contient le nombre d’éléments de ton maillage, la geometrie (3=triangle) et le milieu
    l'idée est de faire une boucle sur le nombre d'éléments de lire le fichier (avec fscanf) pour créer la table de connectivité c'est grosso modo un tableau qui associe au numero d'un élement les numeros des noeuds associés.

    Pour le "fichier2" :
    meme chose que pour le fichier1 sauf que la premier ligne contien le nombre de noeuds, la dimension (ici 2) une condition 1 et une condition 2.
    il faut faire une boucle sur le nombre de noeuds pour créer un tableau qui associe au n° du noeuds ses coordonnées et la conditions.

    comment faire ça ? je veux des idées , pour que pas une méthode pour que je puisse commencer mon code(je ne sais pas bien comment commencer le code ) c'est ma première fois de faire du c++

    merci bien

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Comme chaque noeud est identifiable de manière unique au travers de la première valeur que l'on récupère dans le fichier, je te proposerais volontiers de travailler en deux classes pour les noeuds:

    Une classe "Coordonnee" qui contient simplement les coordonnées du noeud, qui a sémantique de valeur, sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Coordonnee
    {
        public:
            Coordonnee(double x, double y):x_(x),y(y){}
            double x() const{return x_;}
            double y() const{return y_;}
        private:
            double x_;
            double y_; 
    };
    et une classe "Noeud", dont la responsabilité sera de créer la relation entre l'identifiant unique et la coordonnée correspondante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Noeud
    {
        public:
            Noeud(int ind, double x, double y):index_(ind),coord_(x,y){}
            int index() const {return index_;}
            double x() const{return coord_.x();}
            double y() const{return coord_.y();}
        private:
            int index_;
            Coordonnee coord_;
    };
    Cette deuxième classe sera avantageusement complétée par les opérateurs < et == en fonction libre, car ce sont les deux fonctions qui nous permettront de trier et de retrouver le noeud au départ de son index.

    Elles prendront la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    inline bool operator <(Noeud const & first, Noeud const & second)
    {
        return first.index() < second.index();
    }
    inline bool operator ==(Noeud const & first, Noeud const & second)
    {
        return first.index() == second.index();
    }
    inline bool operator <(Noeud const & first, int index)
    {
        return first.index() < index;
    }
    inline bool operator ==(Noeud const & first, int index )
    {
        return first.index() == index;
    }
    De cette manière, tu peux gérer l'ensemble des noeuds avec un "simple" set (ou un vector), sous la forme de std::vector<Noeud> tab; ou de [CODEINLINE]std::set<Noeud> list[CODEINLINE] en fonction de l'évolution éventuelle de la liste des noeud (le set sera préférable si les noeuds ne changent pas, le vector si il est question, à terme, de modifier certains noeuds sous certaines circonstances )

    Pour la gestion des triangles, nous partirions sur le même principe:
    Une classe Triangle dont la responsabilité est de gérer les index des noeuds qui les composent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class Triangle
    {
        public:
            Triangle(int first, int second, int third):first_(first),second_(second),third_(third){}
            int firstIndex() const{return first_;}
            int secondIndex() const{return second_;}
            int thirdInedex() const{return third_;}
            bool useNode(int ind) const
            {
                return first_ == ind || second_ == ind || third_ == ind;
            }
        private:
            int first_;
            int second_;
            int third_;
    };
    et une classe Element dont la responsabilité est de faire correspondre un index avec un triangle:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Element
    {
        public:
            Element(int index, int first, int second, int third):index_(index),elem_(first,second, third){}
            int index() const{return index_;}
            int firstAngle() const{return elem_.firstIndex();}
            int secondAngle() const{return elem_.secondIndex();}
            int thirdAngle() const{return elem_.thirdIndex();}
            bool useNode(int ind) const{return elem_.useNode(ind);}
        private:
            int index_;
            Triangle elem_;
    };
    Cette classe sera également avantageusement complétée par les opérateur < et == permettant de déterminer si nous avons bien affaire à un noeud donné sur base de son index :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    inline bool operator <(Elementconst & first, Elementconst & second)
    {
        return first.index() < second.index();
    }
    inline bool operator ==(Elementconst & first, Noeud Element& second)
    {
        return first.index() == second.index();
    }
    inline bool operator <(Elementconst & first, int index)
    {
        return first.index() < index;
    }
    inline bool operator ==(Elementconst & first, int index)
    {
        return first.index() == index;
    }
    De cette manière, tu pourras gérer les éléments de manière similaire à celle que j'ai expliquée pour les Noeuds

    S'il te faut la possibilité de gérer l'ensemble des éléments dans lesquels apparait un noeud donné, il est toujours possible de gérer une map dont la clé est l'index du noeud en question et dont la valeur est un tableau des indexes des éléments dans lesquels il apparait, sous la forme de std::map<int, std::vector<int> > lalist;Le remplissage de cette map pourrait s'effectuer sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    void addNodeRelation(std::map<int, std::vector<int> & list, Element const & elem)
    {
        int count = 0;
        for(std::map<int, std::vector<int> >::iterator it=list.begin();
            it!=list.end();++it)
        {
            count = 0;
            if(elem == it->first)
            {
                it->second.push_back(elem.index()) ;
                ++ count;
            }
        }
        /* normalement, count doit etre égal à 3 car on doit avoir ajouté l'index 
         * à chacun des noeuds correspondant
         *
         * Si ce n'est pas le cas, il faut trouver le(s) noeud(s) qui n'apparaissent
         * pas encore dans la map
         */
        if(count == 3)
            return;
        if(list.find(elem.firstAngle() == list.end())
        {
            std::vector<int> tab;
            tab.push_back(elem.index());
            list.insert(std::make_pair(elem.firstAngle(),elem.index());
        }
     
        if(list.find(elem.firstAngle() == list.end())
        {
            std::vector<int> tab;
            tab.push_back(elem.index());
            list.insert(std::make_pair(elem.firstAngle(),elem.index());
        }
        if(list.find(elem.secondAngle() == list.end())
        {
            std::vector<int> tab;
            tab.push_back(elem.index());
            list.insert(std::make_pair(elem.secondAngle(),elem.index());
        }
        if(list.find(elem.thirdAngle() == list.end())
        {
            std::vector<int> tab;
            tab.push_back(elem.index());
            list.insert(std::make_pair(elem.thirdAngle(),elem.index());
        }
    }
    (il faudrait même, idéalement, factoriser l'ajout des éléments dans la map, mais ainsi, on voit exactement ce qui se fait )

    Avec tout cela, tu devrais être capable de faire toutes les relations entre tes éléments et tes noeuds
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    +1

    Personnellement, j'aurais fait disparaître les index.
    Enfin sauf s'il y a un réel intérêt de les garder.

  6. #6
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    +1

    Personnellement, j'aurais fait disparaître les index.
    Enfin sauf s'il y a un réel intérêt de les garder.
    Ben, je me dis que c'est surement le critère discriminant le plus intéressant à utiliser, du moins si l'on est sur que, au pire, la modification des coordonnées d'un noeud ne provoque pas de changement au niveau de l'index

    Cela permet d'ailleurs de pouvoir avoir une idée particulièrement précise de l'ensemble des modifications qui peuvent être apportées aux différents éléments et aux triangles si l'on décide, par exemple, de modifier les coordonnées correspondant au noeud 15
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  7. #7
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Bon, quand je disais « faire disparaître les index », je voulais dire « sous leur forme actuelle ».
    Je pensais les remplacer par les adresses des objets.

    Si on construit l'association entre les éléments et les nœuds au fur et à mesure de la lecture des fichiers, on n'a plus besoin de ces index par la suite.
    Je suis conscient qu'ils sont au contraire indispensables tant que cette association n'est pas faite.
    Ensuite, si l'on veut rajouter un élément, il faudra bien parcourir la liste des nœuds pour retrouver ceux qui sont impliqués ; et retourner leurs index ou leurs adresses, c'est similaire...

    De même, si on veut modifier un élément ou un nœud, quelle est la différence si on y accède par son index ou par son adresse ?

    Au pire, si on les stocke dans un vector, on garde une association entre un objet et son index (à condition de ne pas en supprimer, nous sommes d'accord).
    On peut toujours les stocker dans un map dont la clé est l'index. (...)

    Encore une fois, ce que je propose reste sous la condition que les index ne servent qu'à maintenir l'association entre les éléments et les nœuds lors de l'écriture dans les fichiers (du coup, ils sont un peu « artificiels »).

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    De manière générale, un index peut etre parfaitement stable, alors que l'adresse d'un élément dépendra d'un ensemble de circonstances sur lesquelles nous n'avons aucun pouvoir...

    Cela implique plusieurs choses :

    L'adresse du premier point créé pourrait tout aussi bien être plus grande ou plus petite que celle du point créé juste après.

    De plus, il faut te dire que, à moins de stocker des pointeurs, c'est une copie de l'objet que l'on insère qui se retrouve effectivement dans le vector (ou dans n'importe quelle collection de la stl, d'ailleurs).

    Pour pallier ces différents problèmes, tu n'aurais pas d'autre choix que de créer les éléments en ayant recours à l'allocation dynamique de la mémoire.

    Non seulement, ce n'est pas forcément utile (il n'y a pas de relation d'héritage qui pourrait le justifier), mais, en plus, cela rend l'ensemble de la gestion de la mémoire bien plus complexe

    Enfin, une adresse ou un index, cela reste malgré tout une valeur numérique entière, et nous n'avons donc rien de particulier à gagner à l'usage des adresses

    Bref, au vu des inconvénients qu'il y aurait à utiliser l'adresse, on peut décemment estimer que l'utilisation d'index "fixe" est définitvement la moins mauvaise solution, car indépendante de toute circonstance particulière
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Citation Envoyé par koala01 Voir le message
    L'adresse du premier point créé pourrait tout aussi bien être plus grande ou plus petite que celle du point créé juste après.
    J'en suis bien conscient, et franchement, je ne vois pas le problème.
    Une relation d'ordre totale sur des points n'a pas de sens (sauf si la comparaison lexicographique est satisfaisante), et encore moins pour des ensembles de points (comme les triangles).
    Alors à moins que l'ordre dans lequel ont été créés les objets est importante, n'importe quelle relation capable de les différencier fait l'affaire.

    Citation Envoyé par koala01 Voir le message
    De plus, il faut te dire que, à moins de stocker des pointeurs, c'est une copie de l'objet que l'on insère qui se retrouve effectivement dans le vector (ou dans n'importe quelle collection de la stl, d'ailleurs).
    Désolé, je suis encore allé trop vite.
    Il faudra bien stocker tous les objets dans des conteneurs, quels qu'il soient.
    Et quand je disais de référencer un objet par son adresse, je parlais de l'objet qui est effectivement stocké via le conteneur.
    Du coup, pas besoin de stocker des pointeur, ni d'avoir recours à l'allocation dynamique.

  10. #10
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Le problème, même si tu le fais ainsi, c'est que tu force la lecture des fichiers à se faire dans un ordre particulier: les points en premiers, les triangles en second.

    Tu devras, en outre, de toutes manières retrouver les indexes lors de l'écriture des fichiers (si tu dois les réécrire) à moins que ce soit l'ordre même dans laquelle les différents fichiers seront écrits (l'ordre des points et / ou des triangles dans les fichiers) deviendra importante.

    Par contre, si tu garde les indexes, rien ne t'empêche de lire le fichiers triangles en premier, si le nom du fichier fait qu'il apparait en premier dans la liste des fichiers à lire, et tu peux même faire écrire les fichiers au départ de listes non triées : l'index 5 restera l'index 5, même si, d'aventure, cela correspond en fait au 10 eme élément de la liste
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  11. #11
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Le problème, même si tu le fais ainsi, c'est que tu force la lecture des fichiers à se faire dans un ordre particulier: les points en premiers, les triangles en second.
    Euh... franchement, c'est vraiment un problème ?


    Citation Envoyé par koala01 Voir le message
    Tu devras, en outre, de toutes manières retrouver les indexes lors de l'écriture des fichiers (...) à moins que ce soit l'ordre même dans laquelle les différents fichiers seront écrits (...) deviendra importante.
    Euh...
    C'est normal que je ne comprenne pas cette phrase ?

    Ceci dit, ce ne doit pas être très compliqué de fabriquer des indexes à partir des adresses, même s'il ne se suivront probablement pas.
    Mais il faudrait écrire une fonction qui le fait, c'est vrai...
    Le plus simple est en effet de conserver les indexes de départ (ou alors de faire une table d'association entre les adresses et les indexes ? ) ; mais dans ce cas, ma garde est bloquante, et on ne peut pas appliquer ce que je propose.


    Citation Envoyé par koala01 Voir le message
    Par contre, si tu garde les indexes, (...) tu peux même faire écrire les fichiers au départ de listes non triées : l'index 5 restera l'index 5, même si, d'aventure, cela correspond en fait au 10 eme élément de la liste
    Euh... je ne vois pas vraiment le rapport.
    Ces indexes sont des identifiants, et le seul intérêt de trier une liste sur les identifiants des individus qu'elle contient, c'est de pouvoir utiliser des algorithmes efficaces de recherche (dichotomie, etc.).
    S'il n'existe aucune relation d'ordre sur les identifiants choisis, ma proposition reste valable.
    Sauf que ces identifiants seraient certainement moins artificiels que des indexes rajoutés pour faire le liens entre les fichiers...

    Encore une fois, tout dépend de ce que l'on veut faire avec ces indexes, et de quelle importance on leur accorde.

  12. #12
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Euh... franchement, c'est vraiment un problème ?
    si tu crées une liste de fichiers à lire sur base du contenu d'un dossier, cela peut le devenir : seule l'extension éventuelle des fichiers peut devenir éventuellement discriminante (ou non), et tu ne peux avoir aucune certitude que le nom du fichier qui contient les points apparait forcément avant le nom du fichier qui contient les triangles

    Si tu dois commencer à lire un fichier avant de te dire "ah, ben non, il faut que j'en lise un autre avant", cela devient un problème


    Euh...
    C'est normal que je ne comprenne pas cette phrase ?
    Je reformule :

    Soit, tu dois recréer l'index des noeuds et des triangles pour les placer dans le fichier, ce qui prendra du temps (et peut demander pas mal de travail), soit tu t'oblige à travailler sur des liste que tu pourras considérer comme "triées".

    Comme tu ne sais, a priori, pas quel sera l'usage fait des triangles et des points, il me semble préférable d'éviter ce genre de soucis... d'autant plus que ca ne mange pas de pain

    Ceci dit, ce ne doit pas être très compliqué de fabriquer des indexes à partir des adresses, même s'il ne se suivront probablement pas.
    Mais il faudrait écrire une fonction qui le fait, c'est vrai...
    Le seul moyen serait de se baser sur l'index de l'élément dans la collection qui le contient...

    Cela va déjà en grande partie à l'encontre du principe qui conseille de travailler avec des itérateurs, et ce n'est, en outre, pleinement effectif qu'avec des vector (autrement, il faut ajouter un compteur )

    Euh... je ne vois pas vraiment le rapport.
    Ces indexes sont des identifiants, et le seul intérêt de trier une liste sur les identifiants des individus qu'elle contient, c'est de pouvoir utiliser des algorithmes efficaces de recherche (dichotomie, etc.).
    S'il n'existe aucune relation d'ordre sur les identifiants choisis, ma proposition reste valable.
    Le fait est que tu vas sans doute passer ton temps à justement rechercher des éléments, ne serait-ce que pour faire tes relations point -> triangle ou pour déterminer quel point utiliser lors du tracer...

    Mais maintenir une liste triée si l'idée est, pour une raison ou une autre, de rajouter des points peut s'avérer assez compliqué, et gourmand en ressources selon les situations, surtout si tu n'as pas de facteur discriminant
    Sauf que ces identifiants seraient certainement moins artificiels que des indexes rajoutés pour faire le liens entre les fichiers...
    N'oublies pas que l'on part d'une spécification de fichier, qu'il faut donc veiller à la respecter autant que faire se peut!

    Nous pourrions d'ailleurs, même si cela tient sans doute de l'optimisation prématurée, faire valoir le fait que, fonction du nombre de points ( de triangles), nous pouvons gagner pas mal de place en choisissant correctement le type d'entier pour les indexes, par rapport au size_t
    Encore une fois, tout dépend de ce que l'on veut faire avec ces indexes, et de quelle importance on leur accorde.
    A priori : ils sont dans les fichiers, et utilisés pour faire la relation entre eux... L'importance à leur accorder est donc grande
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  13. #13
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Citation Envoyé par koala01 Voir le message
    si tu crées une liste de fichiers à lire sur base du contenu d'un dossier, cela peut le devenir : seule l'extension éventuelle des fichiers peut devenir éventuellement discriminante (ou non), et tu ne peux avoir aucune certitude que le nom du fichier qui contient les points apparait forcément avant le nom du fichier qui contient les triangles

    Si tu dois commencer à lire un fichier avant de te dire "ah, ben non, il faut que j'en lise un autre avant", cela devient un problème
    Cela implique que tu détermines s'il s'agit d'un fichier listant des éléments ou des nœuds à la lecture.
    Dans ce, je suis d'accord, c'est un problème.
    Mais si tu dois savoir quel type de fichier tu as avant de l'ouvrir, afin de remplir la bonne table, il suffit d'ouvrir le bon fichier d'abord.


    Citation Envoyé par koala01 Voir le message
    Soit, tu dois recréer l'index des noeuds et des triangles pour les placer dans le fichier, ce qui prendra du temps (et peut demander pas mal de travail), soit tu t'oblige à travailler sur des liste que tu pourras considérer comme "triées".

    Comme tu ne sais, a priori, pas quel sera l'usage fait des triangles et des points, il me semble préférable d'éviter ce genre de soucis... d'autant plus que ca ne mange pas de pain
    C'est bien pour cela que je conditionne ma proposition.


    Citation Envoyé par koala01 Voir le message
    Le fait est que tu vas sans doute passer ton temps à justement rechercher des éléments, ne serait-ce que pour faire tes relations point -> triangle ou pour déterminer quel point utiliser lors du tracer...
    Comme je le disais, à la création il faut conserver les index.
    Par contre, une fois les objets créés, on a directement l'adresse des nœuds, et on n'a plus besoin de les chercher.


    Citation Envoyé par koala01 Voir le message
    Mais maintenir une liste triée si l'idée est, pour une raison ou une autre, de rajouter des points peut s'avérer assez compliqué, et gourmand en ressources selon les situations, surtout si tu n'as pas de facteur discriminant
    Si on veut rajouter un nœud ou un élément, soit on vérifie d'abord s'il est présent (et dans ce cas l'index ne sert pas), soit on considère que quoi qu'il arrive il est différent de tous les autres, et alors on crée un nouvel index.
    Dans les deux cas, on n'utilise pas les indexes lors de l'ajout.
    Utiliser les adresses ne change rien.


    Citation Envoyé par koala01 Voir le message
    N'oublies pas que l'on part d'une spécification de fichier, qu'il faut donc veiller à la respecter autant que faire se peut!
    Certes, mais certaines informations peuvent ne plus être utiles (dans la forme dans laquelle elles sont données) une fois le tout mis en mémoire.


    Citation Envoyé par koala01 Voir le message
    A priori : ils sont dans les fichiers, et utilisés pour faire la relation entre eux... L'importance à leur accorder est donc grande
    Oui, sauf s'ils ont été ajoutés artificiellement.

  14. #14
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Comme je le disais, à la création il faut conserver les index.
    Par contre, une fois les objets créés, on a directement l'adresse des nœuds, et on n'a plus besoin de les chercher.
    <snip>
    Certes, mais certaines informations peuvent ne plus être utiles (dans la forme dans laquelle elles sont données) une fois le tout mis en mémoire.



    Oui, sauf s'ils ont été ajoutés artificiellement.
    Mais le fait est que tu en as besoin au début de l'application (lors de la lecture) et à la fin de l'application.

    Tout le travail effectué entre ces deux points peut non seulement parfaitement s'adapter à l'utilisation d'indexes fixes, mais peut, en outre, en profiter amplement, entre autres, au niveau des algorithmes à mettre en place (la dichotomie peut parfaitement ne pas servir qu'à la recherche, mais peut aussi servir à la récupération d'un subset de données, selon l'implémentation de l'arbre de recherche )

    Il serait vraiment dommage de perdre ces informations, et ce, d'autant plus que la seule alternative que tu y donnes se base sur des valeurs sur lesquelles on n'a strictement aucune prise : Même si tu te base bel et bien sur l'adresse utilisée par les éléments de ta collection, tu ne peux pas assurer qu'elles seront identiques d'une exécution à l'autre, du simple fait de l'implémentation interne de ta collection !
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  15. #15
    Membre éprouvé Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Points : 997
    Points
    997
    Par défaut
    Ne t'inquiète pas, je suis parfaitement conscient que les adresses sont spécifiques à une exécution donnée.
    Enfin, du moins qu'il ne faut pas compter sur le fait que l'on obtiendra les mêmes adresses d'une exécution sur l'autre.
    Mais des identifiant locaux à une exécution, ça peut être suffisant.
    Enfin, tout dépend de ce que l'on veut faire...

    Bon allez, j'arrête de pinailler, sinon je vais me prendre des mauvais points...

    En fait, en ce moment je travaille sur un projet où certains objets créés à la lecture d'un fichier sont stockés dans un conteneur, et on se sert par la suite de leurs adresses comme identifiants.
    La notion d'index n'existe pas dans le fichier d'origine, et les objets n'ont pas vocation à être réutilisés après l'exécution.
    Ceci dit, la notion d'identifiant est bien présente, mais c'est une chaîne de caractères ; une fois la lecture du fichier d'entrée terminée et tous les objets créés, on peut considérer qu'ils ont une sémantique d'entité (tous les objets existants sont différents les uns des autres, et on n'aura pas besoin d'en créer d'autres), et c'est plus simple et surtout plus rapide de les identifier par leurs adresses.

    C'est pour ça que je proposais ça.
    Mais ce n'est pas forcément applicable ici.

    Voilà.
    Je pense que le débat est clos.

  16. #16
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Steph_ng8 Voir le message
    Bon allez, j'arrête de pinailler, sinon je vais me prendre des mauvais points...
    Pas par moi, je peux te rassurer
    En fait, en ce moment je travaille sur un projet où certains objets créés à la lecture d'un fichier sont stockés dans un conteneur, et on se sert par la suite de leurs adresses comme identifiants.
    La notion d'index n'existe pas dans le fichier d'origine, et les objets n'ont pas vocation à être réutilisés après l'exécution.
    Si elle n'existe pas à la base (dans le fichier lu), il peut tout à fait etre cohérent de décider de ne pas la rajouter...

    Mais, à partir du moment où elle existe, il serait dommage de la perdre en cours d'exécution
    Ceci dit, la notion d'identifiant est bien présente, mais c'est une chaîne de caractères ; une fois la lecture du fichier d'entrée terminée et tous les objets créés, on peut considérer qu'ils ont une sémantique d'entité (tous les objets existants sont différents les uns des autres, et on n'aura pas besoin d'en créer d'autres), et c'est plus simple et surtout plus rapide de les identifier par leurs adresses.
    Mais, déjà, vouloir faire une recherche sur une chaine de caractères n'a aucun sens, du fait même de la logique de comparaison de celle-ci...

    Il est donc parfaitement cohérent, si le seul identifiant unique est une chaine de caractère, de préférer se tourner vers une autre valeur discriminante!!!

    L'adresse de l'objet devient alors un candidat des plus logiques

    Seulement, tu te trouves dans une situation totalement différente dans ton boulot que dans celle qui est exposée par le PO
    C'est pour ça que je proposais ça.
    Mais ce n'est pas forcément applicable ici.
    Ce n'est très certainement pas applicable ici... situation différente, effets différents
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  17. #17
    Nouveau membre du Club
    Inscrit en
    Mai 2010
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 79
    Points : 35
    Points
    35
    Par défaut table de connectivité en c++
    bonjour , et merci pour votre aide ,

    mais je me perd un peut dans votre discutions , elle est à un niveau tellement élevé , part rapport à mon niveau de débutant en c++
    tout y est surement dans ces codes , mais je ne peut les prendre comme ça sans bien comprendre ce que fait chaque ligne .

    est ce qu'il est possible de me donner des commentaires ligne par ligne ??
    merci bien ,
    aussi j'ai vu dans la classe coordonnée , à la ligne 4 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Coordonnee(double x, double y):x_(x),y(y){}
    ce n'est pas plutot :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Coordonnee(double x, double y):x_(x),y_(y){}
    (j'ai ajouté un underscore "_", à y )

    merci d'avance ,

  18. #18
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par dianbobo Voir le message
    aussi j'ai vu dans la classe coordonnée , à la ligne 4 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Coordonnee(double x, double y):x_(x),y(y){}
    ce n'est pas plutot :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Coordonnee(double x, double y):x_(x),y_(y){}
    (j'ai ajouté un underscore "_", à y )

    merci d'avance ,
    Oui, évidemment, il manquait l'underscore (j'ai écrit un peu vite lors de ma première réponse :p )
    bonjour , et merci pour votre aide ,
    mais je me perd un peut dans votre discutions , elle est à un niveau tellement élevé , part rapport à mon niveau de débutant en c++
    Quand, d'ici quelques mois, tu reliras la discussion, elle t'apparaitra beaucoup plus claire, mais, c'est vrai qu'il te manque peut etre quelques prérequis pour en apprécier le sel...

    Mais ne t'en fais pas, il arrive souvent que l'on se chamaille un peu de la sorte, et tu pourras surement bientot prendre part à ces discussions
    tout y est surement dans ces codes , mais je ne peut les prendre comme ça sans bien comprendre ce que fait chaque ligne .

    est ce qu'il est possible de me donner des commentaires ligne par ligne ??
    merci bien
    Bon, on va essayer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Coordonnee
    {
        public:
            Coordonnee(double x, double y):x_(x),y(y){}
            double x() const{return x_;}
            double y() const{return y_;}
        private:
            double x_;
            double y_; 
    };
    définit une classe nommé coordonnée.

    La ligne 4 fournit le constructeur de la classe, c'est à dire la fonction qui s'occupe de fournir un objet correctement initialisé lorsqu'on en a besoin : x_(x) et y_(y) participent à la liste d'initialisation : ils appellent le constructeur de chaque membre de la classe, même si, dans le cas présent, cela correspond à un "pseudo constructeur", étant donné que x_ et y_ sont des entiers, et donc d'un type primitif.

    Les lignes 5 et 6 fournissent ce que l'on appelle des "accesseurs" (en anglais on parle de getter) : ce sont des fonctions qui permettent de récupérer la valeur d'un membre particulier en cas de besoin.

    Le const qui termine la signature de la fonction indique que la fonction s'engage à ne pas modifier l'objet au départ duquel elle est appelée.

    Cela prend toute son importance pour le respect de ce que l'on appelle la "const correctness" (je n'ai pas encore vraiment trouvé de traduction correcte pour le terme :p ) : c'est le fait que seules les fonctions déclarées constantes peuvent être appelées depuis des objets constants.

    Les lignes 8 et 9 définissent des membres de la classe Coordonnee : ils sont déclarés private parce qu'il n'est pas utile de permettre à n'importe qui d'y accéder comme il l'entend.

    Le seul moyen d'y accéder est, en l'état, au travers des deux accesseurs définis en lignes 5 et 6.

    Il n'est pas utile de prévoir des mutateur (en anglais, on parle de setter) pour ces membres car la classe a "sémantique de valeur" : deux instances différentes composées des mêmes valeurs pour x_ et pour y_ peuvent parfaitement exister en même temps, mais, si on change une de ces valeurs, nous obtenons une coordonnée différente.

    Pour ce qui est de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Noeud
    {
        public:
            Noeud(int ind, double x, double y):index_(ind),coord_(x,y){}
            int index() const {return index_;}
            double x() const{return coord_.x();}
            double y() const{return coord_.y();}
        private:
            int index_;
            Coordonnee coord_;
    };
    tu reconnaitra certains points déjà expliqués, par contre, tu peux t'étonner que je n'aie pas placé un accesseur sur la coordonnée elle même, mais que je l'aie remplacé par les fonctions qui se trouvent en ligne 7 et 8.

    Si j'ai travaillé de la sorte, c'est parce qu'il existe une "loi" nommée "demeter" qui dit que, si une classe A utilise en interne une classe B, l'utilisateur de la classe A ne devrait pas avoir à savoir que la classe B existe, et qu'il est donc préférable de permettre d'accéder à certaines fonctions de la classe B au travers de la classe A
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    inline bool operator <(Noeud const & first, Noeud const & second)
    {
        return first.index() < second.index();
    }
    inline bool operator ==(Noeud const & first, Noeud const & second)
    {
        return first.index() == second.index();
    }
    inline bool operator <(Noeud const & first, int index)
    {
        return first.index() < index;}
    inline bool operator ==(Noeud const & first, int index)
    {
        return first.index() == index;
    }
    sont de classiques opérateurs de comparaison.

    l'opérateur < est nécessaire pour permettre de trier des objet (on considère que si non ( a<b ) et non ( b < a ), alors a == b )
    l'opérateur == est utile pour savoir si nous avons effectivement un objet particulier.

    La deuxième version (celle qui prend un entier en deuxième paramètre) permet de comparer un objet avec un entier, car, au final, nous utiliserons souvent des indexes pour transmettre les informations

    Tu devrais pouvoir comprendre, suite à ces explications, tout ce qui est fait pour la classe Triangle et la classe Element
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  19. #19
    Nouveau membre du Club
    Inscrit en
    Mai 2010
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 79
    Points : 35
    Points
    35
    Par défaut maillage,table de connectivité
    Bonjour , et merci pour vos explications

    bon j'ai commencé à coder selon votre model , "je code sous code::bloc"
    j'ai donc créer pour l'instant:
    4 headers (coordonne.h,noeud.h,triangle.h et element.h) comme j'ai 4 classes et pour chaque header correspond un fichier source (coordonnee.cpp,noeud.cpp,element.cpp et triangle.cpp) , tout ceci plus le main.cpp

    déjà est ce quelle est bonne mon organisation ?
    maintenant que j'ai les classes , les constructeurs et les attributs , que me reste t-il à faire ?
    -initialiser les attributs dans leurs fichiers.cpp respectives ??
    -implémenter les méthodes dans les fichiers.cpp respectives??


    et le dernier code , <map> ? il doit etre placé ou ? dans le main.cpp??

  20. #20
    Nouveau membre du Club
    Inscrit en
    Mai 2010
    Messages
    79
    Détails du profil
    Informations forums :
    Inscription : Mai 2010
    Messages : 79
    Points : 35
    Points
    35
    Par défaut
    bonjour ,

    il y a quelque chose que je ne comprend pas bien
    dans les attributs membre de la classe noeud par exemple il y a :

    comment se fait-il que Coordonnée soit un type ??

    merci de votre réponse

Discussions similaires

  1. [MySQL] MySql: jointure de tables pour maillage interne
    Par amdawb dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 23/11/2014, 22h39
  2. Réponses: 9
    Dernier message: 31/03/2014, 11h25
  3. Réponses: 2
    Dernier message: 09/07/2013, 15h52
  4. Réponses: 1
    Dernier message: 25/03/2011, 16h30
  5. Réponses: 1
    Dernier message: 14/07/2009, 09h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo