Pathfinding code produces unexpected results

不羁的心 提交于 2019-12-23 16:12:06

问题


First of all, excuse the bad title, but I don't know how to describe this in just one sentence...

Given a grid with 3 kinds of fields, empty fields, walls and exits, I wrote a program that checks for every empty field, whether that field is "safe". A person walks through that grid, but can only walk non-diagonally and can't go through walls. The person, starting at one field, chooses one direction at random and starts walking that way. Once it hits a wall, it chooses a direction at random again, starting to move into that direction and so on. A field is considered safe if a person traversing the grid as described above, starting at that field, is guaranteed to find an exit at some point.

I wrote a Python program to solve this problem. It builds a "tree" for every field it checks, containing every possible route from that field. I have a function that just returns the "parent" of a given node, by recursively adding the parent of the current node to a list of nodes until it reaches the topmost node.

The program works as expected when checking only one field, for example (1, 4). However it doesn't work when checking all fields of the example grid.

I already looked into it and realized that the alle_parents() function which returns all parents of a given node yields unexpected results when checking all nodes. E.g. when checking the field (1, 4), one child of that node is (1, 8). The parents of (1, 8) should just be (1, 4). That's not the case, though. alle_parents((1, 8)) returns many different fields that shouldn't be there. However I can't figure out why it behaves as it does. My only guess is that it has to do with "left-over" data/GC not working as intended.

Relevant code:

class Knoten():
    def __init__(self, x, y, parent = None):
        self.x = x
        self.y = y
        self.parent = parent
        self.children = []

n = len(spielfeld)
m = len(spielfeld[0])
for k in range(n):
    for j in range(m):      
        if spielfeld[k][j] not in [None, '#', 'E']:
            baum = []
            i = 0
            ebene = []
            ebene.append(Knoten(k, j))
            baum.append(ebene)

            i += 1
            while i <= 100:
                ebene = []

                for knoten in baum[i - 1]:
                    children = []

                    if spielfeld[knoten.x][knoten.y] == 'E':
                        continue

                    for feld in next_feld(knoten.x, knoten.y):
                        knoten_neu = Knoten(feld[0], feld[1], knoten)

                        hinzufuegen = True
                        for parent in alle_parents(knoten_neu):
                            if knoten_neu.x == parent.x and knoten_neu.y == parent.y:
                                hinzufuegen = False

                        if hinzufuegen:
                            ebene.append(knoten_neu)
                            children.append(knoten_neu)

                    knoten.children = children

                    if children == []:
                        if spielfeld[knoten.x][knoten.y] != 'E':
                            spielfeld[k][j] = '%' # Field not safe

                baum.append(ebene)
                i += 1

def alle_parents(knoten, parents = []):
    if knoten.parent == None:
        return parents
    else:
        parents.append(knoten.parent)
        return alle_parents(knoten.parent, parents)

The example map I'm using:

############
# #      # #
#   ##     #
#   #   E# #
#       ## #
#          #
# #E    E###
############

Full code (parts of it are German, sorry for that): http://pastebin.com/3XUBbpkK


回答1:


I suspect your issue is a common Python gotcha. This line:

def alle_parents(knoten, parents = []):

Creates an empty array when the module is loaded, NOT every time the function is called. Future calls to alle_parents() will reuse the same array (which may have grown in size) instead of a new empty array! A good way to fix is to do this:

def alle_parents(knoten, parents = None):
    parents = parents or []


来源:https://stackoverflow.com/questions/34815882/pathfinding-code-produces-unexpected-results

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!