Was ist der beste Weg, um ein Labyrinth bei einem bestimmten Bild darzustellen und zu lösen?
Wie kann man ein JPEG-Bild (wie oben gezeigt) am besten einlesen, in eine Datenstruktur analysieren und das Labyrinth lösen? Mein erster Instinkt ist, das Bild Pixel für Pixel zu lesen und in einer Liste (Array) von Booleschen Werten zu speichern: True
für ein weißes Pixel und False
für ein nicht weißes Pixel (die Farben können verworfen werden). Das Problem bei dieser Methode ist, dass das Bild möglicherweise nicht "pixelgenau" ist. Damit meine ich einfach, dass ein weißes Pixel irgendwo an einer Wand einen unbeabsichtigten Pfad erzeugen kann.
Eine andere Methode (die mir nach einigem Nachdenken einfiel) besteht darin, das Bild in eine SVG-Datei zu konvertieren - eine Liste von Pfaden, die auf einer Leinwand gezeichnet sind. Auf diese Weise könnten die Pfade in dieselbe Art von Liste (Boolesche Werte) eingelesen werden, in der True
ein Pfad oder eine Wand angegeben ist, False
die einen befahrbaren Raum angibt. Ein Problem bei dieser Methode tritt auf, wenn die Konvertierung nicht 100% genau ist und nicht alle Wände vollständig verbunden werden, wodurch Lücken entstehen.
Ein Problem bei der Konvertierung in SVG ist auch, dass die Linien nicht "perfekt" gerade sind. Dies führt dazu, dass die Pfade kubische Bezierkurven sind. Mit einer Liste (Array) von Booleschen Werten, die durch Ganzzahlen indiziert sind, würden die Kurven nicht einfach übertragen, und alle Punkte, die auf der Kurve liegen, müssten berechnet werden, stimmen jedoch nicht genau mit den Listenindizes überein.
Ich gehe davon aus, dass eine dieser Methoden zwar funktioniert (wenn auch wahrscheinlich nicht), dass sie bei einem so großen Bild jedoch äußerst ineffizient sind und dass es einen besseren Weg gibt. Wie wird dies am besten (am effizientesten und / oder am wenigsten komplex) durchgeführt? Gibt es überhaupt einen besten Weg?
Dann kommt das Lösen des Labyrinths. Wenn ich eine der ersten beiden Methoden verwende, erhalte ich im Wesentlichen eine Matrix. Nach dieser Antwort ist die Verwendung eines Baums eine gute Möglichkeit, ein Labyrinth darzustellen, und eine gute Möglichkeit, es zu lösen, die Verwendung des A * -Algorithmus . Wie würde man aus dem Bild einen Baum erstellen? Irgendwelche Ideen?
TL; DR
Beste Art zu analysieren? In welche Datenstruktur? Wie würde diese Struktur beim Lösen helfen / behindern?
UPDATE
Ich habe versucht, das zu implementieren, was @Mikhail in Python geschrieben hat, numpy
und zwar wie von @Thomas empfohlen. Ich denke, dass der Algorithmus korrekt ist, aber er funktioniert nicht wie erhofft. (Code unten.) Die PNG-Bibliothek ist PyPNG .
import png, numpy, Queue, operator, itertools
def is_white(coord, image):
""" Returns whether (x, y) is approx. a white pixel."""
a = True
for i in xrange(3):
if not a: break
a = image[coord[1]][coord[0] * 3 + i] > 240
return a
def bfs(s, e, i, visited):
""" Perform a breadth-first search. """
frontier = Queue.Queue()
while s != e:
for d in [(-1, 0), (0, -1), (1, 0), (0, 1)]:
np = tuple(map(operator.add, s, d))
if is_white(np, i) and np not in visited:
frontier.put(np)
visited.append(s)
s = frontier.get()
return visited
def main():
r = png.Reader(filename = "thescope-134.png")
rows, cols, pixels, meta = r.asDirect()
assert meta['planes'] == 3 # ensure the file is RGB
image2d = numpy.vstack(itertools.imap(numpy.uint8, pixels))
start, end = (402, 985), (398, 27)
print bfs(start, end, image2d, [])
visited.append(s)
unter a wechseln for.if
und es durch ersetzen sollten visited.append(np)
. Ein Scheitelpunkt wird besucht, sobald er der Warteschlange hinzugefügt wurde. Tatsächlich sollte dieses Array den Namen "Warteschlange" tragen. Sie können BFS auch beenden, sobald Sie das Ziel erreicht haben.