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

Algorithmes et structures de données Discussion :

Recherche dichotomique dans une matrice n*n


Sujet :

Algorithmes et structures de données

  1. #1
    Futur Membre du Club
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Points : 9
    Points
    9
    Par défaut Recherche dichotomique dans une matrice n*n
    Bonjour, j'essaye d'implémenter un algorithme de recherche d'élément par dichotomie (récursif si possible) sur une matrice trié par ligne et par colonne mais je n y arrive pas trop voir même pas du tout.
    Sur un tableau 1D j' y arrive parfaitement mais sur une autre matrice c'est une autre affaire.

    Voici un exemple de matrice triée :

    1 2 5 9
    8 12 15 17
    10 13 16 19
    11 14 17 23

    J'ai pensé à diviser à prendre l'élément du milieu par exemple 13, puis comparer l'élément x recherché a 10 (premier élément de la ligne du milieu) et a 19 (dernier élément de la ligne du milieu). Si x > 10 et x > 19 alors on recherchera en bas de du milieu.
    Si x < 10 et x < 19 on recherchera en haut du milieu etc ..
    Ensuite faire de même à gauche et a droite, donc on divise la matrice en 4 en quelque sorte.
    Mais il reste plusieurs sous cas que je ne trouve pas et je ne suis même pas sur que c'est faisable.
    Merci de m'aider

  2. #2
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Bonjour.

    D'abord j'imagine que tes lignes sont triées en fonction de leur premier élément seulement ? Mais qu'entre deux lignes consécutives, deux éléments de la même colonne (hormis le premier) peuvent être arbitrairement ordonnés ? Autrement dit on peut affirmer que M[i,0] < M[j,0] mais on ne peut rien dire sur M[i,k] et M[j,k] ?

    Si oui tu ne peux pleinement exploiter la dichotomie que sur la dimension horizontale, au sein d'une ligne. Mais entre les lignes tu ne peux utiliser la dichotomie que pour rechercher la dernière des lignes à scanner. En effet tu ne dois scanner que les i tels que M[i,0] <= x. Mais tu dois impérativement scanner tout ce sous-ensemble. Soit un O(n.log(n))



    Si en revanche je me trompe et que M[i,k] < M[j,k] quel que soit k et quels que soient i < j, alors je pense que la bonne stratégie est de chercher (en utilisant la dichotomie) la dernière des ligne à parcourir d'après le premier élément, puis au sein de ce sous-ensemble la dernière des colonnes à parcourir en utilisant la dernière ligne, puis au sein de ce sous-ensemble la première des lignes en utilisant la dernière colonne, puis la première colonne en utilisant la première ligne, etc. Autrement dit tu décrirais une spirale pour circonscrire un rectangle de plus en plus petit. C'est du O(2*log(n) + 2*log(n/2) + 2*log(n/4) + ...). C'est inférieur à O(log(n)*log(n)) puisqu'on a log2(n) termes. Je pense qu'on ne peut pas faire mieux.

  3. #3
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Bonjour,

    dans le cas d'une matrice, la dichotomie n'est plus l'algorithme le plus approprié : tu ne supprimes plus la moitié des éléments, mais un quart.
    Il existe une recherche beaucoup plus rapide.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  4. #4
    Futur Membre du Club
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Points : 9
    Points
    9
    Par défaut
    @donquiche
    Si il y a une relation d ordre entre deux elements d'une même colonne :

    1 2 5 9
    8 12 15 17
    10 13 16 19
    11 14 17 23

    Ici : 1<8<10<11 et même raisonnement pour les autres colonnes
    Pour les lignes : 1<2<5<9

    Je pense qu'un algo en o(n) est faisable : en comparant l element cherché à chaque premier élement des lignes de la matrice, puis en effectuant une dichotomie sur la ligne qui correspond.
    Mais y aurai-t-il un un algorithme de meilleur complexité??

  5. #5
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Citation Envoyé par kenzo75 Voir le message
    Mais y aurai-t-il un un algorithme de meilleur complexité??
    Pour une matrice de taille NxM, il y a un algorithme en O(N+M). Il suffit de partir d'en bas à gauche et de comparer la valeur avec celle cherchée : plus petit tu montes, plus grand tu vas à droite.
    Cela est possible car ta matrice est doublement triée.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  6. #6
    Futur Membre du Club
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Points : 9
    Points
    9
    Par défaut
    Je pense aussi que c'est la meilleure implémentation, j vais essayer ça, biensur si quelqu'un d'autre à meilleure j'suis preneur.
    Merci pour tout

  7. #7
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par ToTo13 Voir le message
    Pour une matrice de taille NxM, il y a un algorithme en O(N+M). Il suffit de partir d'en bas à gauche et de comparer la valeur avec celle cherchée : plus petit tu montes, plus grand tu vas à droite.
    Cela est possible car ta matrice est doublement triée.
    Citation Envoyé par kenzo75 Voir le message
    @donquiche
    Si il y a une relation d ordre entre deux elements d'une même colonne :
    Alors c'est le second cas de figure pour lequel j'avais proposé un algo en O(ln(n) * ln(n)), ce qui est meilleur que du O(n+n).

  8. #8
    Futur Membre du Club
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Points : 9
    Points
    9
    Par défaut
    @donquiche
    Je ne comprends pas trop l'algo, y aurait moyen de l'expliquer un peu plus , ou donner un exemple ? Merci

  9. #9
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Imagine que tu as un rectangle qui recouvre toute ta matrice, la valeur cherchée est quelque part là-dedans. Le principe de l'algorithme c'est de rétrécir le rectangle à chaque itération en bougeant un bord à chaque fois et en exploitant l'information obtenue à l'itération précédente. D'abord le côté inférieur, puis le gauche, puis le supérieur, puis le droit, et bis repetita.

    Si on cherche 9 dans cet exemple:
    1 2 5 7
    8 9 15 17
    10 13 16 19
    11 14 17 23

    En regardant (O(log 4)) la première colonne et on peut exclure les deux dernières lignes (tout y est supérieur ou égal à 10), ce qui laisse :
    1 2 5 7
    8 9 15 17

    Maintenant on cherche (O(log 4)) dans la dernière ligne et on peut exclure la première colonne (tout y est inférieur ou égal à 8), ce qui laisse :
    2 5 7
    9 15 17

    Maintenant on cherche (O(log 2)) dans la colonne de droite et on peut exclure la première ligne (tout y est inférieur ou égal à 7), ce qui laisse :
    9 15 17


    Pour une petite matrice l'algo en O(n+n) sera plus rapide. Mais si ta matrice est grande mieux vaut celui-ci.

  10. #10
    Futur Membre du Club
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Points : 9
    Points
    9
    Par défaut
    Oui mais dans cet exemple je ne pense pas que cela foncionne : cherchons 14 dans
    1 2 5 14
    3 4 6 16
    13 17 19 24
    32 64 69 96

    Il va chercher dans
    13 17 19 24
    32 64 69 96

    Alors qu il est en premiere ligne nan?

  11. #11
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Non à la première itération tu gardes les trois premières lignes : celles qui sont susceptibles de contenir la valeur d'après la colonne de gauche. Tu recherches dans la colonne de gauche et par dichotomie le dernier élément inférieur ou égal à la valeur souhaitée.

  12. #12
    Futur Membre du Club
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Points : 9
    Points
    9
    Par défaut
    Ici :

    1 2 5 14
    3 4 6 16
    13 17 19 24
    32 64 69 96

    On recherche 16 par dichotomie dans la premiere colonne, on se débrouille pour que l indice renvoyé soit celui de 32.
    Puis on garde que la sous matrice excluant la derniere ligne et on recommence mais cette fois ci avec la derniere ligne

    1 2 5 14
    3 4 6 16
    13 17 19 24

    Et on garde ce qui >= 16 donc on exclu la premiere colonne etc c est ça?
    Mais j vois pas comment l 'implément ca a l'air compliqué à coder
    Aurais tu une idee de pseudo code? Merci

  13. #13
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Quelque chose comme :
    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
    M, X1, Y1, X2, Y2, X, Y, Valeur
     
    fonction chercher(valeur)
       Valeur = valeur
       tant que vrai
          si ChercheX1OuModifieY2() retourner
          si ChercheY1OuModifieX2() retourner
          si ChercheX2OuModifieY1() retourner
          si ChercheY2OuModifieX1() retourner
       fin
    fin
     
    fonction ChercheX1OuModifieY2()
        Y = RechercheBinaireX(X1, Y1, Y2) // Renvoie plus grand inférieur ou égal à Valeur
        Y2 = Y
        retourner M[X1, Y] == Valeur
    fin
     
    fonction ChercheX2OuModifieY1()
        Y = RechercheBinaireX(X2, Y1, Y2)
        Y1 = Y + 1
        retourner M[X2, Y] == Valeur
    fin

  14. #14
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut Robert Sedgewick
    Robert Sedgewick donne un algo génia que j'utilise aussi
    tu fais une recherche dichotomique sur les lignes -> suppression de la moitié des lignes restantes.
    puis la même chose sur les colonnes -> suppression de la moitié des colonnes restantes.
    et ainsi de suite.

    Pour +d'info je te conseille ce livre magnifique : http://www.amazon.fr/Algorithmes-en-.../dp/2744072567
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

  15. #15
    Futur Membre du Club
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Points : 9
    Points
    9
    Par défaut
    @ol9245
    C est ce que m a proposé donquiche nan?

    @donquiche
    Je t avoue que je comprends pas trop ton pseudo code.. peux tu me détailler un peu ?
    Merci

  16. #16
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut
    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
    fonction couper-matrice(double Matrice : M, double clé : cx, xy, integer bas-gauche : x0, x1, integer haut-droite : y0, y1, integer direction)
    si direction = 1
    si x1 == x0 -> il y a rien à couper : sortie
    sinon     
        couper = (x0+x1)/2
        si cx < couper : x1 = couper
        sinon : x0 = couper
        fin si
    fin si
     
    sinon si direction = 2
    si y1 == y0 -> il n'y a rien à couper : sortie
    sionon
        couper = (y0+y1)/2
        si cy < couper : y1 = cx
        sinon : y0 = couper
       fin si
    fin si
    puis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    x0 = 1, x1 = nombre de colonnes
    y0 = 1, y1 = nombre de lignes
    direction = 1
     
    tant que on n'a pas à la fois x0=x1 et y0=y1
        couper-matrice(M, cx, xy, x0, x1, y0, y1, direction)
        direction = 3 - direction (bascule 1-2 2-1)
    fin tant-que
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

  17. #17
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Points : 9 860
    Points
    9 860
    Par défaut
    Mon algo est aussi trivial que rapide et s'implémente en quelques minutes. Commence donc par faire un test avec, puis tu essaies d'optimiser en testant les autres.
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  18. #18
    Futur Membre du Club
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Points : 9
    Points
    9
    Par défaut
    @ ol9245

    Dans ton algo je ne comprends pas ce que sont cx et cy, qui ne sont pas de plus initialisées. Et je ne comprends pas pourquoi on fait aucun test avec la valeur chercher ..
    Merci

  19. #19
    Membre éprouvé
    Avatar de ol9245
    Homme Profil pro
    Chercheur
    Inscrit en
    Avril 2007
    Messages
    985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Avril 2007
    Messages : 985
    Points : 1 158
    Points
    1 158
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par kenzo75 Voir le message
    @ ol9245

    Dans ton algo je ne comprends pas ce que sont cx et cy, qui ne sont pas de plus initialisées. Et je ne comprends pas pourquoi on fait aucun test avec la valeur chercher ..
    Merci
    c'est les arguments de la fonction, comme indiqué.
    "La vraie grandeur se mesure par la liberté que vous donnez aux autres, et non par votre capacité à les contraindre de faire ce que vous voulez." Larry Wall, concepteur de Perl.

  20. #20
    Futur Membre du Club
    Inscrit en
    Février 2013
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 33
    Points : 9
    Points
    9
    Par défaut
    @donquiche
    pourquoi pas Y1 = Y au lieu de Y1 = Y +1??

Discussions similaires

  1. [XL-2007] VBA Recherche titre dans une matrice
    Par vivi4561 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 31/05/2011, 15h43
  2. [XL-2007] Recherche chronologique dans une matrice
    Par lebonprince dans le forum Excel
    Réponses: 20
    Dernier message: 10/05/2010, 17h18
  3. [find] Comment rechercher une valeur dans une matrice
    Par VanessaDu67 dans le forum MATLAB
    Réponses: 6
    Dernier message: 06/06/2007, 14h55
  4. [Débutant] Recherche de minimum non nul dans une matrice
    Par sebastien69 dans le forum MATLAB
    Réponses: 2
    Dernier message: 05/06/2007, 16h00
  5. Réponses: 1
    Dernier message: 24/05/2007, 14h46

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