2017-11-24 12 views
0

Ich habe ein seltsames Problem in Python. Ich habe ein Labyrinth, x steht für Wände, g ist ein Ziel, s ist der Startpunkt und die Zahlen sind Portale, die dich von einer Zahl zur anderen bringen (zB wenn du auf eine der 2 geht, wird es dich zur andere 2).Python kann Strings nicht vergleichen

xxxxxxxxxxxxxxxxxxxx 
x2     x 
x  xxx  x 
x 1 x xxxxx x 
x s  x  x 
x  x x xxxxxxx 
x xx xxxxx  x 
x  x  g x 
x 1 x 2  x 
xxxxxxxxxxxxxxxxxxxx 

Ich versuche, alle Portale zu finden und sie in ein Array zu setzen. Soweit das funktioniert, findet das Programm alle vier Portale.

import tkinter as tk 
from tkinter import filedialog 

root = tk.Tk() 
root.withdraw() 
file = filedialog.askopenfilename() 

def readMazeToArray(path): 
    with open(path) as f: 
     return [list(line.strip()) for line in f] 

maze = readMazeToArray(file) 

def findPortals(maze): 
    portals = [] 
    for i in range(0, len(maze)): 
     for j in range(0, len(maze[i])): 
      if (maze[i][j] != 'g' and maze[i][j] != 's' 
      and maze[i][j] != 'x' and maze[i][j] != ' '): 
       portals.append([i, j]) 
    return portals 

Und von da an werden die Dinge ein bisschen seltsam. Hier ist der Code, der nicht arbeiten richtig scheint:

def portalHeuristic(maze, x1, x2, y1, y2): 
    portals = findPortals(maze) 
    for portal in portals: 
     for i in range(0, len(maze)): 
      for j in range(0, len(maze[i])): 

       if maze[i][j] == maze[portal[0]][portal[1]] 
       and (portal[0] != i or portal[1] != j): 

        return abs(x1 - portal[0]) + abs(y1 - portal[1]) 
          + abs(x2 - i) + abs(y2 - j)) 

     print(maze[i][j] == maze[portal[0]][portal[1]]) 

     print("x1 = ", x1, ", y1 = ", y1, ", portal0 = ", 
     portal[0], ", portal1 = ", portal[1], ", x2 = ", 
     x2, ", y2 = ", y2, ", i = ", i, ", j = ", j) 


portalHeuristic(maze, 4, 4, 7, 14) 

Was portalHeuristic im Grunde tut, ist es jetzt iteriert durch ein Portal nach dem anderen suchen das gleiche Symbol (maze[i][j] == maze[portal[0]][portal[1]]) des aktuellen Portal sondern sorgt dafür, dass es didn‘ Das aktuelle Portal selbst finden Sie, indem Sie die Koordinaten des aktuellen Portals und des gefundenen Portals mit demselben Symbol/derselben Nummer vergleichen (portal[0] != i or portal[1] != j). Schließlich berechnet es die Entfernung zwischen Startpunkt und aktuellem Portal und seinem Zwillingsportal und dem Ziel.

Aber es scheint wie maze[i][j] == maze[portal[0]][portal[1]] scheint nicht zu funktionieren, da mein Programm immer sagt mir das andere Portal wurde bei i = 9, j = 19 gefunden, egal welches Portal. Seltsamerweise, wenn ich für die Gleichheit der Strings auf eigene Faust teste, erkennt Python, dass es immer falsch ist. Was mache ich falsch? Ich habe jetzt mehr als 3 Stunden damit verbracht, nach dem Fehler zu suchen, aber ich kann es nicht finden. Vielleicht ist es wirklich blöd? Bitte tragen Sie auch mit meinem schrecklichen Code. Ich habe gerade mit Python begonnen.

Antwort

0

seine harte for Schleifen zu schreiben, wenn Sie mit Listenkomprehensionen familliar sind

aber vielleicht können Sie arbeiten nach hinten aus meinem Beispiel Liste comps mit http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/

Ich addierte Zeilenumbrüche und führende Leerzeichen innerhalb der listcomps in einem atempt sehen sollte, um die Lesbarkeit

Sie auch, dass enumerate in dieser Art von Indexierung sehr hilfreich Schleifen mit Test auf Elemente

maze = ['xxxxxxxxxxxxxxxxxxxx', 
'x2     x', 
'x  xxx  x', 
'x 1 x xxxxx x', 
'x s  x  x', 
'x  x x xxxxxxx', 
'x xx xxxxx  x', 
'x  x  g x', 
'x 1 x 2  x', 
'xxxxxxxxxxxxxxxxxxxx'] 

prtls = [[c, (j, k)] 
     for k, ln in enumerate(maze) 
      for j, c in enumerate(ln) if c.isdigit()] 
prtls 
Out[206]: [['2', (1, 1)], ['1', (4, 3)], ['1', (4, 8)], ['2', (10, 8)]] 

grpd_prtls = [[n, [p[1] 
       for p in prtls if p[0] == n]] 
       for n in sorted(set(p[0] for p in prtls))] 
grpd_prtls 
Out[207]: [['1', [(4, 3), (4, 8)]], ['2', [(1, 1), (10, 8)]]] 

die grpd_prtls wird durch Portalnummer sortiert sorted(set(p[0] for p in prtls))

'Manhatten Distance' aus meinem grpd_prtls Calc assmuming nur 2 Portale pro Anzahl

[[p[0], sum(abs(a-b) 
      for a, b in zip(*p[1]))] 
for p in grpd_prtls] 
Out[214]: [['1', 5], ['2', 16]] 
+0

Vielen Dank für die Hilfe, auch für den Artikel! Ich bin mir immer noch nicht ganz sicher, wie ich meine Heuristik berechnen soll ... Ich würde jeden Wert beider Tupel von '1' gleichzeitig brauchen, um diese Werte meiner Funktion zu geben. Ich müsste auch später die Reihenfolge der Werte ändern, falls das zweite Tupel zuerst entdeckt wird. –

0

In Ihrer findPortal Methode erstellen Sie eine Liste, die die Koordinaten Ihrer Portale enthält. Am Ende sollte es so etwas wie diese (es ist Zufallszahlen) sein: portals = [[2,5], [5,1], ...]

In Ihrem portalHeuristic, in Ihrem Zustand maze[i][j] == maze[portal[0]][portal[1]], portal[0] = [2,5] und portal[1] = [5,1]. Also im Grunde tun Sie maze[i][j] == maze[[2,5]][[5,1]], die es seltsam ist, dass Python keine Ausnahme ausgelöst hat. Deshalb ist dein Zustand immer falsch.


Das heißt, Ihr Code ist sehr ineffizient. Du iterierst über das Labyrinth, um Portale zu finden und wiederholst es dann (und 4 Mal, da du 4 Portale hast) auf deinem Labyrinth. Wie wäre es, die Portale direkt zu verknüpfen, wenn Sie sie suchen? Sie können ein Wörterbuch verwenden, dessen Schlüssel die Nummer Ihres Portals ist (hier 1 oder 2), es kann sogar das Zeichen "1" oder "2" sein und nicht die Nummer, und der Wert wäre eine Liste mit 2 Elementen, Jedes Element ist die Koordinate des Portals.

def findPortals(maze): 
    portals = {} #That's a dict 
    for i in range(0, len(maze)): 
     for j in range(0, len(maze[i])): 
      if (maze[i][j] != 'g' and maze[i][j] != 's' 
      and maze[i][j] != 'x' and maze[i][j] != ' '): 
       if maze[i][j] in portals: 
        # We already have one, put the other 
        portals[maze[i][j]].append([i,j]) 
       else: 
        # It is the first one 
        portals[maze[i][j]] = [[i,j]] 
    return portals 

Viel Glück von dort!


Sie können Wörterbücher als Liste sehen, wo der Schlüssel brauchen keine Nummer und nicht sein müssen sequenzielle sein (wenn Sie 5 Elemente in der Liste haben, werden sie mit der Liste zugänglich sein [0] , Liste [1], etc ..). Wenn Sie also auf ein Element in Ihrem Diktat zugreifen möchten, übergeben Sie einfach den Schlüssel. In Ihrer Heuristik scheinen Sie den Abstand zwischen [x1, y1] und dem ersten in Ihrer Liste gefundenen Portal zu finden und ihn mit der anderen Entfernung zwischen dem zugeordneten Portal und [x2, y2] zu summieren. Das ist etwas zu spezifisch, Sie können das Portal angeben, das Sie überprüfen möchten (wie '1' oder '2').

Deshalb ist ihre Funktion werden:

def portalHeuristic(portals, x1, y1, x2, y2, portal_number): 
    # Check if the portal exist in you list 
    if portal_number not in portals: 
     print("This portal number is not in the list") 
     return 
    # This line is a shortcut. Since we know that portals[x] is a list of 
    # two elements (coordinates of both portals with the same number), 
    # you can assign the first element with first_portal and the second element 
    # with second_portal. 
    first_portal, second_portal = portals[portal_number] 
    return abs(x1 - first_portal[0]) + abs(y1 - first_portal[1]) 
         + abs(x2 - second_portal[0]) + abs(y2 - second_portal[1])) 

Vergessen Sie nicht, dass Ihr Schlüssel Charakter gibt es ('1' oder '2') und nicht mehr als 1 oder 2 (Integer). portal_number sollte dann ein Zeichen sein.

+0

Nun, vielen Dank wirklich, aber lernen, wie man Die Arbeit mit Wörterbüchern kompliziert jetzt alles viel mehr. Könntest du mir bitte wenigstens sagen, wie ich den ersten Wert jedes Schlüssels bekommen kann, damit ich sie in meine Formel schreiben kann, die die Heuristik berechnet? Ich kann nicht wirklich eine schnelle und einfache Antwort im Internet finden. –

+0

Ich habe meine Antwort bearbeitet, ist es jetzt besser? Zögern Sie nicht, weitere Fragen zu stellen! –