J'ai une variable de matrice de taille où 1 indique la cellule telle que:
Mask = [[0,0,1,0,0],
[0,1,1,1,0],
[1,1,0,1,1],
[0,1,1,1,0],
[0,0,1,0,0],
]
J'ai besoin de trouver des voisins en forme de diamant de taille paramétrique. Pas une boîte comme réponse donnée ici ou pas un diamant de taille fixe 1, réponse donnée ici . Par exemple, N = 2 Je veux connaître la colonne, les lignes ci-dessous:
Cells = [[0,0,0,0,0],
[0,0,0,0,0],
[0,0,1,0,0],
[0,0,0,0,0],
[0,0,0,0,0],
]
La fonction doit recevoir x et y pour la colonne et la ligne demandées, (pour ci-dessus, je vais entrer 2,2) et N (entrée 2) la taille du diamant. La fonction doit renvoyer une liste de tuples (x, y) pour la taille de diamant donnée.
J'ai eu du mal à définir la forme en fonction de x, y et k dans des boucles for. J'ai besoin de connaître à la fois une solution numpy (s'il y a quelque chose qui aide) et une solution non numpy.
3 Réponses :
Pour une approche itérative où vous construisez simplement le diamant:
dirs = [(1, 0), (0, 1), (-1, 0), (0, -1)]
def add_tuples(a, b):
return tuple([x + y for (x, y) in zip(a, b)])
def get_neighbors(center, n=1, seen=set()):
seen.add(center)
if n <= 0:
return seen
for dir in dirs:
newpos = add_tuples(center, dir)
if newpos in seen:
continue
get_neighbors(newpos, n - 1, seen)
return seen
Résultat de get_neighbors((2, 2), 2) :
[(0, 2), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (4, 2)]
Ou, pour une approche récursive:
def get_neighbors(center, n=1):
ret = []
for dx in range(-n, n + 1):
ydiff = n - abs(dx)
for dy in range(-ydiff, ydiff + 1):
ret.append((center[0] + dx, center[1] + dy))
return ret
l'utilisation d'abs est une manière élégante de résoudre ce problème. Probablement cette question recherchait ceci. J'ajouterai cette réponse.
Je commencerais par prendre une "sous-matrice" qui est le plus petit carré pouvant contenir vos cellules de résultat. C'est la partie sur laquelle numpy devrait pouvoir vous aider.
Définissez ensuite une fonction qui calcule la distance de Manhattan entre deux cellules (abs (x - x_p) + abs (y - y_p)) et parcourez les cellules de votre sous-matrice et renvoyez les valeurs avec une distance de Manhattan de moins de N à partir de votre origine.
import numpy as np
from scipy.ndimage import rotate, convolve
import matplotlib.pyplot as plt
def diamond_filter(radius):
s = radius * 2 + 1
x = np.ones((s, s), dtype=int)
x[radius, radius] = 0
return rotate(x, angle=45)
def make_diamonds(x, radius):
filter = diamond_filter(radius)
out = convolve(x, filter)
out[out > 1] = 1
out -= x
out[out < 0] = 0
return out
def plot(x):
plt.imshow(x)
plt.show()
plt.close()
def main():
cell = np.random.choice([0, 1], size=(200, 200), p=[0.95, 0.05])
plot(diamond_filter(2))
plot(cell)
result = make_diamonds(cell, 2)
plot(result)
if __name__ == '__main__':
main()
Veuillez répéter sur le sujet et comment demander à partir de la visite d'introduction . «Montrez-moi comment résoudre ce problème de codage» n'est pas un problème de débordement de pile. Nous attendons de vous que vous fassiez une tentative honnête, puis que vous posiez une question spécifique sur votre algorithme ou votre technique. Stack Overflow n'est pas destiné à remplacer la documentation et les didacticiels existants. En particulier, nous demander de fournir un code fini sous deux formes est hors de portée; ce n'est pas un service de codage.
Ce n'est qu'une petite partie de ce que j'essaie de réaliser. J'essayais d'être précis mais précis. J'ai fait une tentative et j'ai écrit sur les endroits où j'ai lutté. Pardon.