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.
Update:
It works when I replaced
visited = [[False]*len(cells[0])]*len(cells)
with
visited = [[False for x in range(len(cells[0]))] for y in range(len(cells))]
Can someone explain the difference? Thanks a lot!