Python 低效扩展算法
所以我试着写一个程序,取一个网格和网格上的一个起点,然后向外展开这个点,用到达那个位置所需的展开次数来标记每个单元格 对于我的应用程序,扩展不能查看其他单元格并将其值用作参考,也不能覆盖以前设置的单元格的值。我已经编写了代码来实现这一点,它的工作方式正是我想要的,但当我尝试进行8次或更多的扩展时,我的计算机会遇到困难 有没有人能在我的代码中找到任何让这一点变得如此低效的东西,并给出如何改进的建议 提前谢谢Python 低效扩展算法,python,python-2.7,grid,performance,Python,Python 2.7,Grid,Performance,所以我试着写一个程序,取一个网格和网格上的一个起点,然后向外展开这个点,用到达那个位置所需的展开次数来标记每个单元格 对于我的应用程序,扩展不能查看其他单元格并将其值用作参考,也不能覆盖以前设置的单元格的值。我已经编写了代码来实现这一点,它的工作方式正是我想要的,但当我尝试进行8次或更多的扩展时,我的计算机会遇到困难 有没有人能在我的代码中找到任何让这一点变得如此低效的东西,并给出如何改进的建议 提前谢谢 grid = [[9 for col in range(25)] for row in r
grid = [[9 for col in range(25)] for row in range(25)]
start = [12, 12]
grid[start[0]][start[1]] = 0
numRips = 7
def handler():
allExpanded = [start]
expanded = [start]
num = 1
for r in range(numRips):
toExpand = []
for n in expanded:
toExpand = toExpand + (getUnvisitedNeighbors(n, allExpanded))
expanded = []
for u in toExpand:
grid[u[0]][u[1]] = num
expanded.append(u)
allExpanded.append(u)
num += 1
def getUnvisitedNeighbors(loc, visitedCells):
x, y = loc[0], loc[1]
neighbors = [[x - 1, y], [x + 1, y], [x, y - 1], [x, y + 1], \
[x - 1, y - 1], [x - 1, y + 1], [x + 1, y - 1], [x + 1, y + 1]]
f = lambda p: p[0] >=0 and p[0] < len(grid) and \
p[1] >= 0 and p[1] < len(grid[0]) and \
not p in visitedCells
unvisitedNeighbors = filter(f, neighbors)
return unvisitedNeighbors
handler()
for i in range(len(grid)):
print grid[i]
grid=[[9表示范围(25)中的列][9]表示范围(25)中的行]
开始=[12,12]
网格[start[0]][start[1]]=0
numRips=7
def处理程序():
allExpanded=[开始]
扩展=[开始]
num=1
对于范围内的r(numRips):
toExpand=[]
对于扩展中的n:
toExpand=toExpand+(GetUnvisitedNeights(n,allExpanded))
扩展=[]
对于toExpand中的u:
网格[u[0]][u[1]]=num
扩展。追加(u)
allExpanded.append(u)
num+=1
def GetUnvisitedNeights(loc,已访问单元格):
x、 y=loc[0],loc[1]
邻居=[[x-1,y],[x+1,y],[x,y-1],[x,y+1]\
[x-1,y-1],[x-1,y+1],[x+1,y-1],[x+1,y+1]]
f=lambda p:p[0]>=0和p[0]=0和p[1]
所以这就是我最终想到的,工作非常快,也非常简单。如果有人试图实现类似的算法:
grid = [[0 for col in range(25)] for row in range(25)]
start = [12,12]
rippleLoss = .01
rippleLimit = .5
reward = .6
def expansion(curLoc):
edge = int((reward - rippleLimit) / rippleLoss)
c = 0
for y in range(-edge, edge + 1):
for x in range(-edge, edge + 1):
if isValidCell([curLoc[0] + x, curLoc[1] + y]):
if abs(x) > abs(y):
c = abs(x) - abs(y)
else:
c = 0
grid[curLoc[1] + y][curLoc[0] + x] = abs(y) + c
def isValidCell(loc):
return loc[0] >=0 and loc[0] < len(grid) and loc[1] >= 0 and loc[1] < len(grid[0])
expansion(start)
for i in range(len(grid)):
print grid[i]
grid=[[0表示范围(25)中的列)]表示范围(25)中的行]
开始=[12,12]
rippleLoss=.01
rippleLimit=.5
奖励=.6
def扩展(CULLOC):
edge=int((奖励-rippleLimit)/rippleLoss)
c=0
对于范围内的y(-edge,edge+1):
对于范围内的x(-edge,edge+1):
如果isValidCell([curLoc[0]+x,curLoc[1]+y]):
如果abs(x)>abs(y):
c=防抱死制动系统(x)-防抱死制动系统(y)
其他:
c=0
网格[curLoc[1]+y][curLoc[0]+x]=abs(y)+c
def isValidCell(loc):
返回loc[0]>=0和loc[0]=0和loc[1]
我更改了您的代码以便可以计时:
import os
import sys
import timeit
setup_str = \
'''
from __main__ import setup, handler
setup()
'''
def setup():
global grid
grid = [[9 for col in range(25)] for row in range(25)]
global start
start = [12, 12]
grid[start[0]][start[1]] = 0
global numRips
numRips = 8
def handler():
global grid
global start
global numRips
allExpanded = [start]
expanded = [start]
num = 1
for r in range(numRips):
toExpand = []
for n in expanded:
toExpand = toExpand + (getUnvisitedNeighbors(n, allExpanded))
expanded = []
for u in toExpand:
grid[u[0]][u[1]] = num
expanded.append(u)
allExpanded.append(u)
num += 1
def getUnvisitedNeighbors(loc, visitedCells):
global grid
x, y = loc[0], loc[1]
neighbors = [[x - 1, y], [x + 1, y], [x, y - 1], [x, y + 1], \
[x - 1, y - 1], [x - 1, y + 1], [x + 1, y - 1], [x + 1, y + 1]]
f = lambda p: p[0] >=0 and p[0] < len(grid) and \
p[1] >= 0 and p[1] < len(grid[0]) and \
not p in visitedCells
unvisitedNeighbors = filter(f, neighbors)
return unvisitedNeighbors
print timeit.repeat(stmt="handler()", setup=setup_str, repeat=3, number=1)
for i in range(len(grid)):
print grid[i]
这花费了[0.0016090851488842293,0.0014349565512783052,0.001418698443765235]秒
基本上,您希望尽量减少分配、复制和迭代的工作量。谢谢dilbert!这是一个巨大的进步
import os
import sys
import timeit
setup_str = \
'''
from __main__ import setup, handler
setup()
'''
dirs = \
(
( - 1, 0),
( + 1, 0),
( 0, - 1),
( 0, + 1),
( - 1, - 1),
( - 1, + 1),
( + 1, - 1),
( + 1, + 1)
)
def setup():
global grid_max_x
grid_max_x = 25
global grid_max_y
grid_max_y = 25
global grid
grid = [[9 for col in range(grid_max_y)] for row in range(grid_max_x)]
global start
start = (12, 12)
grid[start[0]][start[1]] = 0
global numRips
numRips = 8
def handler():
global grid
global start
global numRips
border_expanded = set([start])
allExpanded = set([start])
num = 1
for r in range(numRips):
toExpand = set([])
map(lambda x: toExpand.update(x), [(getUnvisitedNeighbors(n, allExpanded)) for n in border_expanded])
border_expanded = toExpand
allExpanded.update(toExpand)
for u in toExpand:
grid[u[0]][u[1]] = num
num += 1
def getUnvisitedNeighbors(loc, visitedCells):
global grid_max_x
global grid_max_y
global dirs
x, y = loc
neighbors = set([((x + dx) % grid_max_x, (y + dy) % grid_max_y) for (dx, dy) in dirs])
unvisitedNeighbors = neighbors - visitedCells
return unvisitedNeighbors
print timeit.repeat(stmt="handler()", setup=setup_str, repeat=3, number=1)
for i in range(len(grid)):
print grid[i]