mardi 2 février 2016

Python - Multiple if statement get ignored

I'm implementing BFS on a 2D-array with a list serve as "queue". I add each unvisited neighbor of current cell(i, j) to the queue, and in each loop, pop the head of the queue as the current cell, until the queue is empty. Standard stuff.

The problem seems that only one "if" statement is executed in each loop. I can't see why it happens.

for tgroup in targets.keys(): #group of targets
    for t in targets[tgroup]: #each target in group
        visited = [[False]*len(cells[0])]*len(cells)
        queue = []
        cur = None
        queue.append(t)
        visited[t[0]][t[1]] = True
        cells[t[0]][t[1]].fields[tgroup-3] = 0
        while len(queue) > 0:
            cur = queue[0]
            queue = queue[1:]

            if cur[0] > 0 and visited[cur[0]-1][cur[1]] is False:
                queue.append((cur[0]-1,cur[1]))
                visited[cur[0]-1][cur[1]] = True
                cells[cur[0]-1][cur[1]].fields[tgroup-3] = min(cells[cur[0]-1][cur[1]].fields[tgroup-3], cells[cur[0]][cur[1]].fields[tgroup-3]+1)
                print 't', cur

            if cur[0] < len(cells)-1 and visited[cur[0]+1][cur[1]] is False:
                queue.append((cur[0]+1,cur[1]))
                visited[cur[0]+1][cur[1]] = True
                cells[cur[0]+1][cur[1]].fields[tgroup-3] = min(cells[cur[0]+1][cur[1]].fields[tgroup-3], cells[cur[0]][cur[1]].fields[tgroup-3]+1)
                print 'b', cur

            if cur[1] > 0 and visited[cur[0]][cur[1]-1] is False:
                queue.append((cur[0],cur[1]-1))
                visited[cur[0]][cur[1]-1] = True
                cells[cur[0]][cur[1]-1].fields[tgroup-3] = min(cells[cur[0]][cur[1]-1].fields[tgroup-3], cells[cur[0]][cur[1]].fields[tgroup-3]+1)
                print 'l', cur

            if cur[1] < len(cells[0])-1 and visited[cur[0]][cur[1]+1] is False:
                queue.append((cur[0],cur[1]+1))
                visited[cur[0]][cur[1]+1] = True
                cells[cur[0]][cur[1]+1].fields[tgroup-3] = min(cells[cur[0]][cur[1]+1].fields[tgroup-3], cells[cur[0]][cur[1]].fields[tgroup-3]+1)
                print 'r', cur

            if cur[0] > 0 and cur[1] > 0 and visited[cur[0]-1][cur[1]-1] is False:
                queue.append((cur[0]-1,cur[1]-1))
                visited[cur[0]-1][cur[1]-1] = True
                cells[cur[0]-1][cur[1]-1].fields[tgroup-3] = min(cells[cur[0]-1][cur[1]-1].fields[tgroup-3], cells[cur[0]][cur[1]].fields[tgroup-3]+1)
                print 'tl', cur

            if cur[0] > 0 and cur[1] < len(cells[0])-1 and visited[cur[0]-1][cur[1]+1] is False:
                queue.append((cur[0]-1,cur[1]+1))
                visited[cur[0]-1][cur[1]+1] = True
                cells[cur[0]-1][cur[1]+1].fields[tgroup-3] = min(cells[cur[0]-1][cur[1]+1].fields[tgroup-3], cells[cur[0]][cur[1]].fields[tgroup-3]+1)
                print 'tr', cur

            if cur[0] < len(cells)-1 and cur[1] > 0 and visited[cur[0]+1][cur[1]-1] is False:
                queue.append((cur[0]+1,cur[1]-1))
                visited[cur[0]+1][cur[1]-1] = True
                cells[cur[0]+1][cur[1]-1].fields[tgroup-3] = min(cells[cur[0]+1][cur[1]-1].fields[tgroup-3], cells[cur[0]][cur[1]].fields[tgroup-3]+1)
                print 'bl', cur

            if cur[0] < len(cells)-1 and cur[1] < len(cells[0])-1 and visited[cur[0]+1][cur[1]+1] is False:
                queue.append((cur[0]+1,cur[1]+1))
                visited[cur[0]+1][cur[1]+1] = True
                cells[cur[0]+1][cur[1]+1].fields[tgroup-3] = min(cells[cur[0]+1][cur[1]+1].fields[tgroup-3], cells[cur[0]][cur[1]].fields[tgroup-3]+1)
                print 'br', cur

targets are the starting coordinates of this algorithm. I need to traverse the entire map to fill out some 'floor field' to find the shortest path from each location of the map to these targets. Each t in target is stored as a tuple (i,j)

visited are the markers for visited nodes.

cur is the current node, stored as a tuple (i,j).

cells is the 2D-array. Each cell has a list attribute .fields containing "floor field" weight for each target, representing the distance from this cell to the target. The weight of non-target cells are default to 9, for now, for simplicity. The weight for the targets are default to 0.

Here's a sample 9*9 input map:

4 1 1 1 1 1 1 1 1
0 1 1 0 0 0 0 1 0
0 1 1 1 1 2 0 1 0
0 1 1 1 1 2 0 1 0
0 1 1 0 0 0 0 1 0
3 1 1 0 0 0 1 1 0
3 1 1 0 0 0 1 1 0
0 1 1 0 0 0 1 0 0
0 5 5 5 0 0 1 0 0

But the floor field generated for the target represented as number 3 is:

9 9 9 9 9 9 9 9 9
9 9 9 9 9 9 9 9 9
9 9 9 9 9 9 9 9 9
9 9 9 9 9 9 9 9 9
9 9 9 9 9 9 9 9 9
0 1 2 3 4 5 6 7 8
0 1 2 3 4 5 6 7 8
9 9 9 9 9 9 9 9 9
9 9 9 9 9 9 9 9 9

It doesn't traverse all nodes.

Aucun commentaire:

Enregistrer un commentaire