我最近创建了一个脚本,使用从几个迷宫节点构建的自定义迷宫类生成随机迷宫。每个节点如下所示:
class mazeNode:
def __init__(self, pos, conn = None):
self.pos = pos
if conn:
self.conns = [conn]
else:
self.conns = []
conn
是另一个mazeNode对象,并且在创建迷宫期间更改self.conns
以包括该节点连接到的每个mazeNode对象。 pos
是具有节点位置的元组。在创建迷宫时,根据深度优先搜索算法创建mazeNode对象,并在分支中链接在一起。
脚本效果很好,可以在大约10秒内创建一个大小为500 * 500的迷宫。但是,它似乎没有非常高效的内存。我设法创建了一个大小为6000 * 6000的迷宫,但是当我尝试10000 * 10000时,无论我做什么,我都会收到内存错误,即使我分配了50GB的虚拟内存。对于那个大小,我最终得到10 ^ 8个mazeNode对象。
我尝试使用shelve
模块,但这会使脚本运行速度变慢而无法使用,对于更大的迷宫,我收到了一个递归深度错误(由于不必要的递归,脚本可能很慢)。
我想知道是否有任何方法可以优化脚本的内存使用量,同时保持速度。所有节点都链接在一起,但它们并不一定都在RAM中。
EDIT 迷宫课程如下:
class Maze:
def __init__(self, xSize, ySize):
self.pos = (xSize//2, ySize//2)
self.xSize = xSize
self.ySize = ySize
self.directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
self.visit = set([self.pos])
self.maze = mazeNode(self.pos)
self.node = self.maze
self.stack = Stack()
self.deadEnds = 0
for i in randPerm(list(range(4))):
self.stack.put(mazeNode(add(self.pos, self.directions[i]), self.node))
def makeMaze(self):
while True:
while self.node.pos in self.visit and not self.stack.isEmpty():
self.node = self.stack.pop()
if self.stack.isEmpty():
break
if self.node.pos not in self.visit:
self.visit.add(self.node.pos)
for conn in self.node.conns:
conn.conns.append(self.node)
tempCount = 0
for i in randPerm(list(range(4))):
pos = add(self.node.pos, self.directions[i])
if pos not in self.visit and check(pos, self.xSize, self.ySize):
self.stack.put(mazeNode(pos, self.node))
tempCount += 1
if tempCount == 0:
self.deadEnds += 1
if len(self.maze.conns) == 1:
self.deadEnds += 1
编辑2:
我使用了广告位:并按如下方式编辑了mazeNode类:
class mazeNode:
__slots__ = ('posx', 'posy', 'conns', )
def __init__(self, pos, conn = None):
self.posx = pos[0]
self.posy = pos[1]
self.conns = [conn] if conn else []
并使用sys.getsizeof()
来获取类实例的大小。
print(sys.getsizeof(self.maze), sys.getsizeof(self.maze.posx), sys.getsizeof(self.maze.posy), sys.getsizeof(self.maze.conns))
打印64 28 28 96
。但是,如果我删除__slots__
,我会56 28 28 96
,这看起来很奇怪。我该怎么解释这个? __slots__
无效吗?
答案 0 :(得分:0)
__slots__
使用非常简单,只需将它们添加到类定义中即可:
class MazeNode(object):
__slots__ = ('pos', 'conn', )
def __init__(self, pos, conn=None):
self.pos = pos
self.conns = [conn] if conn else []
唯一需要记住的是,插槽类型/类不能动态添加属性。只能设置和/或修改__slots__
中列出的属性。即使他们做会显着降低每个对象的内存使用量,也不要为你定义的每个类定义插槽。明智地使用它们。