Saturday, July 25, 2015
Python : Breadth-First Search (4) floodfile in a map
Abstract: make colors with a given point in a map
There is a map with some islands circulating by sea. calculate the area of all islands in this map.
The result:
The area is 19
The area is 7
The area is 81
The area is 42
Total number of lands= 4
ok
The script:
# -*- coding: utf-8 -*-
"""
Created on Fri Jul 24 09:44:46 2015
@author: yuan
"""
import numpy as np
# search areas of islands in a map
#record a queue using circling list
class queue:
def __init__(self,arr, q_len=1):
self.size=len(arr)
if q_len==1 or q_len<self.size:
self.q=[None]*self.size
self.q_len=self.size
else:
self.q=[None]*q_len
self.q_len=q_len
self.q[0]=0
self.q[1:self.size]=arr
self.head=1 #skip the index 0
self.tail=len(arr)+1 #the index of next element of arr
#print 'Initiate queue:', self.q
def q_size(self):
#print 'Size of the queue:', self.size
return self.size
def isFull(self):
return self.tail==(self.q_len+1)
def export_arr(self):
if self.tail>self.head:
arr=self.q[self.head:self.tail]
elif self.tail==self.head:
arr=[]
else:
arr=self.q[self.head:(self.q_len+1)] + self.q[1:self.tail]
return arr
def enqueue(self, value):
if self.size<self.q_len:
#increase size
self.size +=1
#increase tail
if self.tail==(self.q_len+1):
self.tail=1
#add value
self.q[self.tail]=value
self.tail += 1
else:
print "queue is full, fail to adding", value
#print '##', self.q, self.head,self.tail
#return self.export_arr()
def dequeue(self):
#increase head
value='NA'
#print self.head, self.tail
if self.size>0:
value=self.q[self.head]
if self.head==self.q_len:
self.head=1
else:
self.head +=1
#decrease size
self.size -= 1
#print 'remove', value, self.export_arr()
return value
##################
class breadth_first_search(queue):
def __init__(self, pool):
self.pool=pool
self.nrow=len(pool)
self.ncol=len(pool[1])
self.book=list(pool)
self.next=[[1,0],[-1,0], [0,1],[0,-1]]
self.area={}
#print self.pool
def possible_points(self):
points=[]
for row_index,row in enumerate(self.book):
for col_index,element in enumerate(row):
#print row_index, col_index, element
if element>0:
points.append((row_index,col_index))
return points
def export_land(self):
if not self.area=={}:
for point in self.area.keys():
points_num=len(self.area[point])
print 'The area is', points_num
print 'Total number of lands=', len(self.area)
def largest_area(self):
#get all land points
points=self.possible_points()
#print self.pool[25][16]
#
for candidate_point in points:
q=queue([candidate_point], self.nrow*self.ncol)
land_points=[candidate_point]
while q.q_size()>0:
start_point=q.dequeue()
for i in range(4):
next_move=self.next[i]
x=start_point[0]+next_move[0]
y=start_point[1]+next_move[1]
#out of bound or sea point
if 0<x<self.nrow and 0<y<self.ncol:
#print candidate_point, x, y, self.nrow, self.ncol
if self.pool[x][y]==1 and self.book[x][y]==1:
new_point=(x, y)
land_points.append(new_point)
self.book[x][y]=3
q.enqueue(new_point)
points.remove(new_point)
self.area[candidate_point]=land_points
#
self.export_land()
#main
if __name__ == "__main__":
#0 is sea point, 1 is land point, 3 is visited land point
pool=[
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0],
[1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0],
[0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0],
[0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0],
[0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0],
[0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0],
[0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0] ]
#coordinate of the end point
s=breadth_first_search(pool)
s.largest_area()
print 'ok'
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment