Das in Vorheriger Artikel erstellte Programm hatte einen Stapelüberlauf. Die Ursache ist ziemlich klar, und da es zurückgerufen wird, wird es das Gedächtnis überwältigen, wenn es mehr als eine bestimmte Menge wiederholt. Ich dachte, dass es kein Problem geben würde, wenn die Daten für Forschungszwecke verwendet würden, aber die Daten, die ich tatsächlich verwendete, liefen über, also entschied ich mich, den Algorithmus zu ändern.
python | 3.7.4 |
---|
Ich habe die Bibliothek nicht besonders benutzt.
Die Ursache war, dass es den Speicher drückte, also entschied ich mich, es zu lösen, indem ich es mit for anstelle eines Rückrufs wiederholte. Es dauert jedoch zu lange, alle Zellen jedes Mal zu betrachten und zu verarbeiten. Erstellen Sie daher eine Funktion, die die 6 Richtungen (oben / unten / links / rechts + Z-Achse oben / unten) Ihrer eigenen Zelle ausfüllt und die Koordinaten der zu durchsuchenden Zelle speichert. Und nur diese Zelle verarbeiten. Ich weiß nicht einmal, ob ich es in Sätzen schreibe, also schreibe ich die Reihenfolge der Verarbeitung.
Zunächst zeigt eine Tabelle, in welchen Zellen sich die Zellen befinden.
Statussymbol | Inhalt des Staates |
---|---|
0 | Eine der Binarisierung |
1 | Eine der Binarisierung |
2 | Gefüllte Zelle |
Dann ist es der Inhalt der eigentlichen Verarbeitung. Ich werde den ersten nicht wiederholen (natürlich)
Es ist so. Beim letzten Mal habe ich jeweils eine Zelle durchsucht, aber diesmal ist es so, als würde ich mich daran erinnern, welche Zellen im Voraus durchsucht werden sollen, und sie alle gleichzeitig verarbeiten.
Werfen wir einen Blick auf den Code. Die erste ist die iterative Hauptfunktion.
new_fill.py
def fill(data, plot):
stack=[]
end_stack=[]
data, defaultvalue= plot_point(data, plot, stack) #Geben Sie den ersten Punkt an
while stack: #Wiederholen, sofern nicht leer
for pop_data in stack: #Daten aus dem Stapel extrahieren
stack.remove(pop_data) #
data = step_fill(data, pop_data["x"], pop_data["y"], pop_data["z"], defaultvalue, stack) #
end_stack.append(pop_data) #
return data
Das Programm, das den ersten Punkt angibt, ist fast das gleiche wie das vorherige. Der Unterschied besteht darin, dass die Koordinatendaten in den Stapel eingefügt werden, sodass sich der Rückgabewert ändert und intern in den Stapel eingefügt wird.
new_fill.py
def plot_point(data, plot, stack):
defaultvalue = data[plot["z"]][plot["y"]][plot["x"]]
data[plot["z"]][plot["y"]][plot["x"]]=2
stack.append(plot)
return data, defaultvalue
Sie haben gerade "stack.append (plot)" hinzugefügt.
Und obwohl es sich um eine Funktion handelt, die die Umgebung ausfüllt, ist dies die Funktion, die ursprünglich den Neustartaufruf ausgeführt hat. Dieses Mal fülle ich mich einfach selbst und lege die umgebenden nicht gesuchten Koordinaten in den Stapel Es ist eine Funktion wie.
new_fill.py
def step_fill(data, x, y, z, defaultvalue, stack):
data[z][y][x]=2
if (data[z][y][x-1]==defaultvalue) and (not {"x":x-1, "y":y, "z":z} in stack):
stack.append({"x":x-1, "y":y, "z":z})
if (data[z][y][x+1]==defaultvalue) and (not {"x":x+1, "y":y, "z":z} in stack):
stack.append({"x":x+1, "y":y, "z":z})
if (data[z][y-1][x]==defaultvalue) and (not {"x":x, "y":y-1, "z":z} in stack):
stack.append({"x":x, "y":y-1, "z":z})
if (data[z][y+1][x]==defaultvalue) and (not {"x":x, "y":y+1, "z":z} in stack):
stack.append({"x":x, "y":y+1, "z":z})
if (data[z-1][y][x]==defaultvalue) and (not {"x":x, "y":y, "z":z-1} in stack):
stack.append({"x":x, "y":y, "z":z-1})
if (data[z+1][y][x]==defaultvalue) and (not {"x":x, "y":y, "z":z+1} in stack):
stack.append({"x":x, "y":y, "z":z+1})
return data
Es ist einfach. Ich habe das Gefühl, dass ich etwas Schöneres schreiben kann, also werde ich darüber nachdenken.
Mit den oben genannten drei können Sie 3D-Füllung implementieren.
Übrigens habe ich die Zeit des vorherigen ursprünglichen Experiments verglichen.
Vorherige Füllung | Diese Füllung | |
---|---|---|
1 | 0.004987001419067383 | 0.12566423416137695 |
2 | 0.003987789154052734 | 0.10970711708068848 |
3 | 0.003989219665527344 | 0.11269998550415039 |
4 | 0.004986763000488281 | 0.11568784713745117 |
5 | 0.00598454475402832 | 0.11369585990905762 |
6 | 0.015959978103637695 | 0.11469197273254395 |
7 | 0.004986763000488281 | 0.11768507957458496 |
8 | 0.003989934921264648 | 0.11369562149047852 |
9 | 0.003988981246948242 | 0.1136932373046875 |
10 | 0.005983829498291016 | 0.11469554901123047 |
durchschnittlich | 0.00588448047637 | 0.115191650390625 |
Die Bearbeitungszeit hat sich um das 200-fache erhöht. Vielleicht gibt es eine Mischung aus nutzloser Verarbeitung, also werde ich noch einmal darüber nachdenken.
Recommended Posts