12
votes

Manière pythonique et efficace de trouver des cellules adjacentes dans la grille

Je construis une application à base de carrelage en Python à l'aide de Pyglet / OpenGL dans laquelle je devrai trouver la toutes les cellules adjacentes pour une cellule donnée. Je travaille dans un quadrant d'une grille cartésienne. Chaque cellule a une valeur X et Y indiquant sa position dans la grille (X_COORD et Y_COORD). Ce ne sont pas des valeurs de pixels, des positions plutôt des grilles. Je cherche un moyen efficace d'obtenir les cellules adjacentes. Au maximum, il y a huit cellules adjacentes possibles, mais en raison des limites de la grille, il pourrait y en avoir aussi peu que 3. pseudo-code pour une approche simple mais probablement inefficace ressemble à ceci:

def get_adjacent_cells( self, cell ):
     result = []
     x_coord = cell.x_coord
     y_coord = cell.y_coord
     for c in grid.cells:
          if c.x_coord == x_coord and c.y_coord == y_coord: # right
               result.append( c )
          if c.x_coord == x_coord - 1 and c.y_coord == y_coord + 1: # lower right
               result.append( c )
          if c.x_coord == x_coord - 1 and c.y_coord == y_coord: # below
               result.append( c )
          if c.x_coord == x_coord - 1 and c.y_coord == y_coord - 1: lower left
               result.append( c )
          if c.x_coord == x_coord and c.y_coord == y_coord - 1: right
               result.append( c )
          // -- similar conditional for remaining cells


1 commentaires

Si vous voulez garder avec votre façon de le faire, je ferais au moins un compteur pour compter combien de résultats ont été mis en résultat. Quand il atteint 8, sortez de la boucle. En outre, seuls Vérifiez s'il est égal à 8 lorsque vous appendez une cellule.


6 Réponses :


2
votes

Eh bien, cela ne facilitera aucune performance, mais vous pouvez éviter la duplication de code en disant xxx

pour affecter les performances, vos cellules de réseau doivent savoir qui sont leurs voisins, soit par un attribut comme C.Eighbors ou via une structure implicite, comme une liste de listes, vous pouvez donc accéder par coordonnée. xxx

alors vous pouvez vérifier Pour le voisinage en utilisant les indices de liste.


0 commentaires

1
votes

Ceci est probablement le moyen le plus efficace de rechercher des voisins si la grille.cells est implémentée comme un ensemble (bien qu'il y ait une erreur dans la première déclaration IF - vous devez tester pour l'égalité à X_COORD + 1 plutôt qu'à X_COORD) .

Toutefois, la mise en œuvre de la grille.Cells comme liste de listes vous permettrait de désigner des cellules individuelles par numéro de rangée et de colonne. Cela vous permettrait également de mesurer le nombre total de lignes et de colonnes. get_adjacent_cells pourrait alors fonctionner en vérifiant d'abord les bords qui bordent la cellule actuelle, puis recherchant les voisins dans toutes les autres directions et les ajouter à la liste des résultats.


0 commentaires

9
votes

Votre code va être aussi lent que votre grille, car vous êtes itération sur les cellules simplement pour obtenir 8 d'entre eux (dont vous connaissez déjà leurs coordonnées).

Si vous pouvez faire un accès aléatoire par leurs indices, je suggère quelque chose comme ce qui suit: xxx

max_x et max_y sont censés être la taille de La grille et la grille .__ getItem __ est censée accepter un tuple avec les coordonnées et renvoyer la cellule dans cette position.


0 commentaires

11
votes

Ce n'était pas clair pour moi s'il y avait d'autres informations dans les cellules que les coordonnées X et Y. Dans tous les cas, je pense qu'un changement de structures de données est nécessaire pour rendre cela plus rapide.

J'ai supposé qu'il y a des informations supplémentaires dans les cellules et effectuée grid.cells comme dictionnaire avec les touches étant des tuples des coordonnées. Une chose similaire pourrait être faite avec grid.cells comme défini s'il n'y a que les informations de coordonnées dans les cellules. xxx

selon ce que vous Voulez-vous faire avec les données, vous ne voudrez peut-être pas faire en résultat un dict, mais j'espère que vous obtenez l'idée. Cela devrait être beaucoup plus rapide que votre code, car votre code fait 8 chèques sur chaque cellule dans grid.cells .


1 commentaires

Cette approche ressemble à la plus rapide car elle n'implique pas itérant sur chaque cellule. Utiliser des tuples comme des clés est une excellente alternative. Merci



1
votes

Dans une grille, l'adjacence signifie que vous n'avez besoin que d'une seule étape de la coordonnée pour atteindre l'autre si je ne suis pas à tort ou élevé.

 if abs(c.x_coord-x_coord+c.y_coord-y_coord) == 1:
     print("They are adjacent!")


1 commentaires

Je me demande si cette déclaration fonctionne dans ce cas: (5, 5) et (3, 6)



0
votes

Ceci fonctionne avec des tableaux numpus xxx


0 commentaires