2017-11-24 30 views
0

저는 파이썬에서 이상한 문제에 직면하고 있습니다. 나는 미로가있다. x는 벽을 의미하고, g는 목표이고, s는 출발점이며, 숫자는 하나의 숫자에서 다른 숫자로 이동하는 포털이다. (예를 들어, 2로 가면 당신을 기타 2).파이썬은 문자열을 비교하지 못합니다.

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 

모든 포털을 찾아서 배열에 넣으려고합니다. 지금까지이 작업을 통해 프로그램은 네 개의 포털을 모두 찾습니다.

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 

그런 다음부터는 다소 이상해집니다. 여기에 바로 작동하지 않는 코드는 다음과 같습니다

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) 

무엇 portalHeuristic 기본적으로이 반복 현재 포털의 동일한 기호 (maze[i][j] == maze[portal[0]][portal[1]])을 찾고 연이어 포털을 통해 지금 수행하지만 'didn를 보장 현재 포털의 좌표와 발견 된 포털의 좌표를 같은 기호/숫자 (portal[0] != i or portal[1] != j)와 비교하여 현재 포털 자체를 찾습니다. 결국 그것은 시작 지점과 현재 포털 및 쌍둥이 포털과 목표 사이의 거리를 계산합니다.

그러나 내 프로그램이 항상 다른 포털을 찾을 수 있기 때문에 maze[i][j] == maze[portal[0]][portal[1]]이 작동하지 않는 것 같습니다. i = 9, j = 19, 어떤 포털이든 상관 없습니다. 이상하게도 필자가 파이썬에서 문자열의 동등성을 테스트하면 항상 거짓이라는 것을 알 수 있습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? 나는 이제 오류를 찾기 위해 3 시간 이상을 보냈지 만 그것을 찾을 수없는 것 같습니다. 어쩌면 정말 바보예요? 또한 내 끔찍한 코드를 참아주십시오. 방금 파이썬으로 시작했습니다.

답변

0

하드는 지능형리스트

그러나 아마 내 예를 들어 목록에서 역방향으로 작동 나는 listcomps 내에서 줄 바꿈과 최고의 공백을 추가 http://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/

와 콤프 수와 familliar있어 일단 for 루프를 작성하는 atempt에 당신은 또한 enumerate 색인의이 유형에 많은 도움이 될 것입니다 것을 볼 수

가독성을 돕기 위해 요소에 대한 테스트와 루프

691,363,210
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)]]] 

이 많은 정말 수

[[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

도와 주셔서 대단히 감사합니다, 또한 기사를 게시하기 위해! 나는 아직도 내 경험적 방법을 어떻게 계산할 것인지는 아직 확실치 않다 ... 나는이 값을 내 함수에주기 위해서 동시에 두 튜플의 모든 값을 필요로 할 것이다. 두 번째 튜플이 먼저 발견 된 경우 나중에 값의 순서를 변경해야합니다. –

0

findPortal 방법에서는 포털의 좌표가 포함될 목록을 만듭니다. 말은 (는 난수의)이 같은해야한다 : 당신의 상태 maze[i][j] == maze[portal[0]][portal[1]], portal[0] = [2,5]portal[1] = [5,1]portalHeuristic에서 portals = [[2,5], [5,1], ...]

을. 그래서 기본적으로, 당신은 maze[i][j] == maze[[2,5]][[5,1]]을하고 있는데, 그것은 파이썬이 예외를 발생시키지 않았다는 것이 이상합니다. 그래서 당신의 상태는 항상 거짓입니다.


이렇게 말하면 코드는 매우 비효율적입니다. 미로를 반복하면서 포털을 찾은 다음 미로에 4 개의 포털이 있으므로 4 회 반복합니다. 포털을 검색 할 때 포털을 직접 페어링하는 것은 어떻습니까? 사전은 키가 포털 번호 (여기 1 또는 2)와 함께 사용할 수 있으며 숫자가 아닌 문자 "1"또는 "2"일 수도 있고 값은 2 개의 요소가있는 목록이 될 수 있습니다. 각 요소는 포털의 좌표입니다.

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 

행운을 내세요!


당신은 키가 귀하의 목록에있는 5 개 항목이있는 경우, 그들은 목록에 액세스 할 수 있습니다 (숫자가 될 필요가 없습니다 순차 될 필요가 없습니다 목록으로 사전을 볼 수 있습니다 [0] , list [1] 등). dict에서 항목에 액세스하려면 키를 전달하십시오. 경험적으로 볼 때 [x1, y1]과 목록에서 발견 된 첫 번째 포털 사이의 거리를 찾고 관련 포털과 [x2, y2] 간의 다른 거리와 합산하는 것이 좋습니다. 너무 구체적이어서 확인하려는 포털을 지정할 수 있습니다 (예 : '1'또는 '2').

따라서 함수가 될 :

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])) 

당신의 키가 문자 것을 잊지 마십시오 ('1'또는 '2')가 아니라 1 또는 2 (정수). portal_number은 문자 여야합니다.

+0

음, 당 덕분에 단 2 포털을 assmuming, 내 grpd_prtls에서 'Manhatten에 거리를'CALC 포털 수 sorted(set(p[0] for p in prtls))

으로 분류하지만, 방법을 배우고있다 사전 작업은 이제 모든 것을 훨씬 복잡하게 만듭니다. 적어도 각 키의 첫 번째 값을 얻을 수있는 방법을 알려주십시오. 따라서이를 휴리스틱을 계산하는 내 수식에 넣을 수 있습니까? 나는 인터넷에서 빠르고 쉬운 답을 찾을 수 없다. –

+0

내 대답을 편집했습니다. 더 나아 졌습니까? 더 많은 질문을 주저하지 마십시오! –