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

avec Java Discussion :

Tri à bulles et complexité


Sujet :

avec Java

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 24
    Points : 15
    Points
    15
    Par défaut Tri à bulles et complexité
    Bonjour à tous,

    Voici mon un petit code que j'ai trouvé sur le net et que j'ai modifié pour me satisfaire :

    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
     
    public class Tri{
     
    public static void main(String [] args)
    {
     
     
        int tabk[] = {1029,8,1,4,2,190,2999,90,3,0};
        int Exchange;
        int compteurA=0;
        int compteurB=0;
        int v=0;
     
         //Tri à bulles
        //BOUCLE A
        for(int a=0;a<N;a++)
        {  
                //BOUCLE B
                for(int b=0;b<N;b++)
                {  
    	      //Echange des valeurs 
                   if (tabk[a]<tabk[b])
                   {  
                      Exchange=tabk[a]; 
                      tabk[a]=tabk[b];  
                      tabk[b]=Exchange; 
                   } 
                   //compte le nombre d'entrée dans la boucle b
                   compteurB=compteurB +1;
                } 
     
                //compte le nombre d'entrée dans la boucle a
                compteurA=compteurA +1;
        }
        System.out.println("COMPTEUR A: "+compteurA);
        System.out.println("COMPTEUR B: "+compteurB);
     
         System.out.println(""); 
         //Affiche le tableau trié
         while(v<10)
        {
          System.out.println(tabk[v]);
          System.out.println(",");
          v++;
        }
    }
    }
    Ce code fonctionne très bien et tri parfaitement mon tableau, le seul problème c'est qu'il ne ressemble pas du tout à un tri à bulles.
    En effet un tri a bulles est censé comparé l'élément courant du tableau avec son successeur, soit tab[i]>tab[i+1]. Or là, on dirait qu'il compare l'élément courant avec chacun des éléments du tableau et cela à tour de rôle (La boucle B le fait).

    De plus voici ce que me donne comme résultat les compteurA et compteurB :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    COMPTEUR A: 10
    COMPTEUR B: 100
    Or il me semble bien que la compléxité d'un tel algo est O(n), soit n*n, mais 10 * 100 = 1000 !!! Dois-je comprendre par là que mon algo n'est pas un tri à bulles car sa complexité ne semble pas la même, ou bien, que tout simplement COMPTEUR B = 100 car 10*10 !?

    Ma question est donc celle-ci, comment dois-je comprendre ce que j'ai codé ?

    Je vous remercie d'avance de vos réponses et de vos éclaircissements.

  2. #2
    Membre éclairé Avatar de JoeChip
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2008
    Messages : 536
    Points : 803
    Points
    803
    Par défaut
    Ma question est donc celle-ci, comment dois-je comprendre ce que j'ai codé ?
    Si tu ne comprend pas ce code, c'est que tu ne l'as pas codé...
    Sans danger si utilisé conformément au mode d'emploi.

    (anciennement BenWillard, enfin moins anciennement que ... enfin bon c'est une longue histoire... Un genre de voyage dans le temps...)

  3. #3
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par alcibiade Voir le message
    le seul problème c'est qu'il ne ressemble pas du tout à un tri à bulles.
    En effet un tri a bulles est censé comparé l'élément courant du tableau avec son successeur, soit tab[i]>tab[i+1]. Or là, on dirait qu'il compare l'élément courant avec chacun des éléments du tableau et cela à tour de rôle (La boucle B le fait).
    il ne s'agit effectivement pas d'un tri à bulles classique mais s'en rapproche tout de même. A chaque itération, les élements les plus petites sont remontés en début de tableau.

    De plus voici ce que me donne comme résultat les compteurA et compteurB :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    COMPTEUR A: 10
    COMPTEUR B: 100
    Or il me semble bien que la compléxité d'un tel algo est O(n), soit n*n, mais 10 * 100 = 1000 !!! Dois-je comprendre par là que mon algo n'est pas un tri à bulles car sa complexité ne semble pas la même, ou bien, que tout simplement COMPTEUR B = 100 car 10*10 !?

    Ma question est donc celle-ci, comment dois-je comprendre ce que j'ai codé ?

    Je vous remercie d'avance de vos réponses et de vos éclaircissements.
    Il y a plusieurs erreurs dans ton raisonnement :
    1. La complexité d'un tri à bulles est o(n^2) et non o(n)
    2. Pour calculer une complexité, il faut compter les nombre d'opération couteuses, ici les permutations, pas forcement les comparaisons.
    3. o(n^2) signifie que l'algo prendra k1 x n^2 + k2 x n + k3, où k1,k2 et k3 sont des constantes, c'est à dire que le temps d'execution est ploynomiale d'ordre 2 par rapport à n qui est ton nombre d'entrée.

      quand tu dis que o(n^2) correspondant à n x n, c'est faut, ca peut très bien correspondre à 10 x n x n, voir à 10 x n x n + 5000000 x n + 1209303... et ce n'est pas avec un seul test que tu vas pouvoir vérifier une complexité.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 24
    Points : 15
    Points
    15
    Par défaut
    Merci pour votre réponse benratti, en effet ce n'est pas O(n) mais O(n * n). Petit erreur de ma part je l'avoue. Quand au tri je pense que je peux tout de même le classer dans "la famille" des tris à bulles vu que les nombres les plus grand remontent en haut petit à petit.

    Quand à vous BenWillard relisez ma question, je dis dès la première phrase que j'ai repris le code sur le net et que je l'ai modifié. Je ne l'ai pas codé à 100 pour cent seul. De plus votre réponse ne sert à rien vu qu'elle ne m'aide nullement.

    Merci tout de même.

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    445
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2011
    Messages : 445
    Points : 622
    Points
    622
    Par défaut
    Citation Envoyé par alcibiade Voir le message
    Quand au tri je pense que je peux tout de même le classer dans "la famille" des tris à bulles vu que les nombres les plus grand remontent en haut petit à petit.
    Pas trop d'accord avec toi, je ne pense pas que ce soit un tri à bulle.
    A ce compte la, tous les tris seraient des tris à bulle car dans tous les tris, les nombres sont classés petit à petit...

    Dans ton code, le compteur A n'est pas important, il est préférable de compter le nombre de comparaisons et le nombre de permutations :

    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
     
    public class Tri{
     
    public static void main(String [] args)
    {
     
        int tabk[] = { 1029, 8, 1, 4, 2, 190, 2999, 90, 3, 0 };
        int Exchange;
        int compteurTest = 0;
        int compteurEchange = 0;
        int v = 0;
     
        //Tri à bulles
        //BOUCLE A
        for (int a = 0; a < tabk.length; a++) {
          //BOUCLE B
          for (int b = 0; b < tabk.length; b++) {
            //Echange des valeurs 
            if (tabk[a] < tabk[b]) {
              Exchange = tabk[a];
              tabk[a] = tabk[b];
              tabk[b] = Exchange;
     
              //compte le nombre d'echange
              compteurEchange++;
     
            }
            //compte le nombre de test
            compteurTest++;
          }
        }
        System.out.println("COMPTEUR Test: " + compteurTest);
        System.out.println("COMPTEUR Echange: " + compteurEchange);
     
        System.out.println("");
        //Affiche le tableau trié
        while (v < tabk.length) {
          System.out.print(tabk[v]);
          System.out.print(",");
          v++;
        }
    }
    }
    Pour ton tri, dans tout les cas, tu auras n^2 comparaisons.


    Voici un exemple de tri à bulle
    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
     
    int tabk[] = { 1029, 8, 1, 4, 2, 190, 2999, 90, 3, 0 };
        int Exchange;
        int compteurTest = 0;
        int compteurEchange = 0;
        int v = 0;
     
        boolean encore;
     
        int N = tabk.length;
        do {
          encore = false;
     
          for (int i = 0; i < (N - 1); i++) {
            if (tabk[i] > tabk[i + 1]) {
              Exchange = tabk[i];
              tabk[i] = tabk[i + 1];
              tabk[i + 1] = Exchange;
              compteurEchange++;
              encore = true;
            }
            compteurTest++;
          }
          N--;
        }
        while (encore);
     
     
        System.out.println("COMPTEUR Test: " + compteurTest);
        System.out.println("COMPTEUR Echange: " + compteurEchange);
     
        System.out.println("");
        //Affiche le tableau trié
        while (v < tabk.length) {
          System.out.print(tabk[v]);
          System.out.print(",");
          v++;
        }
    Dans ce tri, dans le pire des cas, il y aura (N-1)*(N/2) comparaisons.

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 24
    Points : 15
    Points
    15
    Par défaut
    Merci pour votre précieuse réponse Fred_34.

    Votre solution fonctionne très bien. Donc d'après ce que j'ai compris ce n'est pas le nombre d'entré dans la boucle qui est important, mais le nombre d'opérations que l'on fait. C'est donc pour cela que la complexité au pire est de N*N (ou plutôt (n-1)*(n/2) comme dans votre exemple). Ce que je remarque aussi c'est que j'ai l'impression qu'à chaque fois qu'il y'a ce genre de complexité, il y'a une boucle imbriquée dans une autre. Ce qui explique bien le N*N justement.

    Néanmoins il ne me reste plus que quelques questions encore :

    • Si le précédent programme n'est pas un tri à bulles, qu'est-ce que c'est alors?
    • Vous dites que la compléxité dans cet exemple est de N-1 *N/2. Je comprend bien pour quoi N-1 car si c'est N on serait mené à comparé N+1 à un moment et à sortir du tableau, mais pourquoi N/2. A aucun moment on ne divise le tableau. N-1*N/2 ne serait -il pas une complexité qui se raprocherai d'un tri dichotomique?


    Merci encore pour votre patience.

  7. #7
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par alcibiade Voir le message
    Vous dites que la compléxité dans cet exemple est de N-1 *N/2. Je comprend bien pour quoi N-1 car si c'est N on serait mené à comparé N+1 à un moment et à sortir du tableau, mais pourquoi N/2. A aucun moment on ne divise le tableau. N-1*N/2 ne serait -il pas une complexité qui se raprocherai d'un tri dichotomique?
    En fait, quand tu regardes la premiere itération de la boucle, tu vas faire N-1 comparaison. A la deuxième, ce sera N-2. et ainsi de suite.

    Le nombre de comparaison que tu vas faire sera
    (n-1) + (n-2) + ... + 1, soit la somme des entiers de 1 à (n-1), et cela est égale à n * (n-1) / 2, c'est juste mathématique.

    C'est expliqué ici

  8. #8
    Membre chevronné
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Points : 1 806
    Points
    1 806
    Par défaut
    Cela dit, on reste dans du O(n²), ce qui est plutôt lent.

    Pour des tris rapides - en O(n.log(n)) en moyenne et dans le pire des cas - il faut aller vers le tri fusion ou, si on accepte le O(n²) dans certains cas, du quick sort.

  9. #9
    Membre confirmé Avatar de benratti
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    471
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2004
    Messages : 471
    Points : 649
    Points
    649
    Par défaut
    Citation Envoyé par Rei Ichido Voir le message
    Pour des tris rapides - en O(n.log(n)) en moyenne et dans le pire des cas - il faut aller vers le tri fusion ou, si on accepte le O(n²) dans certains cas, du quick sort.
    C'est d'ailleurs le choix qui est pri dans l'API standard avec Collections.sort qui est un tri fusion légèrement modifé... mais il me semble qu'il s'agissait, dans le cadre de ce post, d'un cas d'école plus qu'une implémentation dans le cadre d'un réel projet.

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 24
    Points : 15
    Points
    15
    Par défaut
    Tout d'abord merci car j'ai compris beaucoup de choses grâce à vous et cela en peu de temps.

    Il est vrai que l'exemple que j'ai pris n'est pas très pertinent pour trier des valeurs. Vous avez donc raison benratti, il s'agit donc d'un cas d'école. Pour l'explication du (n-1) * (n/2). J'ai vu ça en cours le jour ou vous avez postez votre réponse.

    Bref je vous remercie encore. J'espère que tout ce dont nous avons parlé servira à d'autres.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. tri bulle (setValueAt )
    Par ghotique dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 28/06/2007, 19h42
  2. quelle instruction pour un tri à bulles?
    Par bandit_debutant dans le forum Langage
    Réponses: 2
    Dernier message: 30/11/2006, 07h16
  3. besoin d aide et de vrification algo tri bulle
    Par dju.ly dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 30/12/2005, 13h04
  4. Tri à bulle - Affichage de sprite
    Par Gory dans le forum Assembleur
    Réponses: 5
    Dernier message: 10/03/2005, 15h27

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