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 :

[Manipulation de matrices] Elements adjacents


Sujet :

Algorithmes et structures de données

  1. #1
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Points : 58
    Points
    58
    Par défaut [Manipulation de matrices] Elements adjacents
    Bonjour,

    Dans le cadre d'un projet (je précise que je ne suis pas encore expert en programmation) je suis amené à déterminer toute la zone d'éléments adjacents identiques à un élément donné d'une matrice de caractère (je travaille en C++)

    J'explique ce que j'entends par là :

    J'ai une matrice m*n composée de trois caractères différents (il y a donc des répétitions). Un élément est adjacent à un autre élément s'il est situé en dessous, au dessus, à droite ou à gauche de celui-ci (par exemple : les éléments adjacents à l'élément central M[i][j] sont M[i + 1][j], M[i - 1][j], M[i]j+1] et M[i][j - 1])

    Soit donc un élément M[i][j] contenant le caractère X je dois trouver toute la zone d'éléments adjacentes à M[i][j] et contenant le même caractère X.
    Pour ce faire je dois donc :

    - déterminer tous les éléments adjacents à M[i][j] et contenant X
    - déterminer tous les éléments contenant X adjacents à une case adjacente à M[i][j] contenant X
    - ... (je continue ainsi jusqu'a être arrivé au bout de la zone)

    Graphiquement sur un exemple :

    Voilà M (contenant les caractères 1,a et y) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    a a a a a y y y y 1 1 a a a
    1 1 1 1 a a a a a 1 y y 1 y
    y y y y y a a a a 1 a 1 y y
    1 y 1 a 1 y y y a y 1 1 1 1
    a y 1 1 a a 1 a a 1 1 1 y y
    y y 1 1 1 1 1 1 y 1 1 1 1 1
    Si je prends l'élément M[0][2] (ligne 0, colonne 2) la zone que je dois déterminer est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    a a a a a 
            a a a a a 
              a a a a 
                    a 
                  a a
    Savez-vous comment je pourrais écrire un tel algorithme en C++ ?
    Je pense que par récurrence c'est faisaible mais je n'ai pas encore étudié cette méthode de programmation donc je dois y parvenir sans elle.

    Si vous avez une idée je suis preneur

    merci

  2. #2
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Recherche "Flood Fill", c'est le nom de l'algorithme le plus courant pour faire ce genre de chose.

    En gros, il faut nourrir une pile avec tous les voisins non encore visités puis prendre l'élément au sommet et ainsi de suite jusqu'à ce que la pile soit vide.

  3. #3
    Membre éprouvé Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Points : 1 213
    Points
    1 213
    Par défaut
    disons que tu stockes tes couples dans un vector E d'éléments (a,b).

    Pour déterminer la zone à partir de M[i,j] où i,j sont donnés, tu fais (en franco algo ):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    booléen b=true;
    E=vide
    Ajouter (i,j) à E
    Tant que b=true{
       booléen c=false
       Pour tout (a,b) de E{
          si(a<m){si M[a+1,b]=M[i,j] alors (Ajouter (a+1,b) à E et c=true)}
          si(a>1){si M[a-1,b]=M[i,j] alors (Ajouter (a-1,b) à E et c=true)}
          si(b<n){si M[a,b+1]=M[i,j] alors (Ajouter (a,b+1) à E et c=true)}
          si(b>1){si M[a,b-1]=M[i,j] alors (Ajouter (a,b-1) à E et c=true)}
       }
       si c=false alors b=false
    }
    Nemerle, mathématicopilier de bars, membre du triumvirat du CSTM, 3/4 centre

  4. #4
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Points : 58
    Points
    58
    Par défaut
    Ah d'accord je vais voir ça !

    merci bien pour vos deux réponses

  5. #5
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Points : 58
    Points
    58
    Par défaut
    Ton algorithme marche assez bien nemerle, merci bien

    Mais j'ai toutefois un problèmes. Il ne s'arrête jamais et je n'ai pas eu trop de mal à trouver pourquoi :

    Il ne faut pas que j'ajoute deux fois le même élément dans le vecteur E sinon forcément

    1) J'ai des éléments en trop de le vecteur

    et alors pire

    2) L'algo ne s'arrête jamais :

    Mettons que la zone contienne 2 éléments disposé ainsi :

    y
    y

    L'algo va tester pour le y du dessus (élément N°1 de E) , il ne va trouver comme élément à ajouter que celui du dessous (elément N°2 de E). Ok, après cela il passe à l'élément du dessous (il faut bien car il a été rajouté au vecteur). Il va trouver l'élément du dessus et va le rajouter ( élément N°3, alors qu'il s'y trouve déja), etc.

    Il faut donc à tout pris que j'évite de rajouter des éléments qui s'y trouvent déja.
    Sais-tu comment je pourrais faire ça de manière efficace ? Bien sûr en faisant une recherche préalable dans le vecteur avant d'ajouter un élément ça s'arrangera mais je perderai de l'efficacité

    en tout cas merci beaucoup !

  6. #6
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Points : 58
    Points
    58
    Par défaut
    J'ai vite fait implémenté une petite recherche

    Je ne sais pas s'il est possible d'éviter d'en faire une ? J'ai pas encore calculer la complexité de ce code mais ça ne doit pas etre fameux

    En tout cas comme ça ça fonctionne, merci infiniment

  7. #7
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Pour éviter une recherche tu peux utiliser une matrice de booléens pour marquer les éléments déjà visités et ne pas les visiter à nouveau.

  8. #8
    Membre éprouvé Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Points : 1 213
    Points
    1 213
    Par défaut
    sorry du retard, j'étais en déplacement à Panam

    Effectivement, j'ai oublié un mini-truc:

    les 4 conditionnelles
    doivent être remplacées par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    si (M[a+1,b]=M[i,j] ET (a+1,b) n'appartient pas à E)...
    Voila. Tu peux utiliser une matrice de booléen, ou toute fonction d'appartenance. [EDIT] OU MIEUX: après avoir ajouté (x,y) à E, tu "détruis" M[x,y] en passant la valeur à 0. Cela t'oblige de dupliquer ta matrice avant d'appliquer cet algo, mais cela t'évite la matrice de booléens ou la fct d'appartenance dans le vecteur !! [/EDIT]

    Franchement, tu aurais pu trouver tout seul
    Nemerle, mathématicopilier de bars, membre du triumvirat du CSTM, 3/4 centre

  9. #9
    Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Points : 58
    Points
    58
    Par défaut
    Désolé pour le restard de ma réponse j'étais aussi assez occupé ces derniers jours et j'ai délaissé mon ordinateur.

    Ah mais j'y suis parvenu (en détruisant M[x][y] comme tu dis), je n'ai meme pas eu besoin de dupliquer la matrice vu que je n'ai plus besoin des éléments en questions.

    Mais sinon ceci suffit en fait :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Pour tout (a,b) de E{
          si(a<m){si M[a+1,b]=M[i,j] alors (Ajouter (a+1,b) à E et c=true)}
          si(a>1){si M[a-1,b]=M[i,j] alors (Ajouter (a-1,b) à E et c=true)}
          si(b<n){si M[a,b+1]=M[i,j] alors (Ajouter (a,b+1) à E et c=true)}
          si(b>1){si M[a,b-1]=M[i,j] alors (Ajouter (a,b-1) à E et c=true)}
       }
    Pas besoin de chipoter avec des variables booléennes a et b

    Ca fonctionne très bien maintenant, un grand merci à tous

    P.S. : Si quelqu'un désire le code C++ du petit programme que vous m'avez aider à concevoir (c'est un bête jeu à 4 sous sur la ligne de commande) je peux lui envoyer en guise de remerciement (même si c'est sans doute sans intérêt pour vous )

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

Discussions similaires

  1. manipulation des matrices sous SSRS
    Par linram dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 09/07/2007, 12h31
  2. Question sur l'exponentiation d'une matrice d'adjacence
    Par Mike888 dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 28/05/2007, 16h09
  3. Fonctions manipulant des matrices
    Par panda31 dans le forum C
    Réponses: 24
    Dernier message: 14/06/2006, 10h28
  4. Théorie des graphes : Représentation GRAPHIQUE d'une matrice d'adjacence
    Par jm_gouy dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 03/05/2006, 16h53
  5. Manipulation de matrices.
    Par TeKa dans le forum C
    Réponses: 28
    Dernier message: 16/11/2005, 15h53

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