Python实现数据量较大的生命游戏

我现在要用串行的方法实现一个生命游戏,这个生命游戏是在一个100000 x 100000的棋盘上,并且繁衍500代。我选择用list形成一个二维数组来装这个棋盘上的数据,可是程序运行到一半,报错说memory error,如果数据量小一点的话运行时没问题的。请问我应该怎么改进呢

# 棋盘的行列数
row = 100000
column = 100000

# 进化代数
count = 50

nCellSta = [[random.randint(0, 1) for i in range(column)] for j in range(row)]
nTempSta = [[0 for p in range(column)] for q in range(row)]


def CellCount(nRow, nColumn):
    global row, column, nCellSta
    nSum = 0
    for i in range(nRow - 1, nRow + 2):
        for j in range(nColumn - 1, nColumn + 2):
            if i < 0 or i > row - 1 or j < 0 or j > column - 1 or i == nRow and j == nColumn:
                continue
            if nCellSta[i][j] == 1:
                nSum += 1
    if nSum == 0 or nSum == 1 or nSum == 4 or nSum == 5 or nSum == 6 or nSum == 7 or nSum == 8:
        return 0
    elif nSum == 2:
        return nCellSta[nRow][nColumn]
    elif nSum == 3:
        return 1


# 输出列表nCellSta的值
def printValue():
    nSum = 0
    global row, column
    for i in range(row):
        for j in range(column):
            # 打印效果
            # print(nCellSta[i][j], ' ', end='')
            nSum += nCellSta[i][j]
        # print('\n')
    return nSum


def main():
    global count, nCellSta, nTempSta
    printValue()
    startTime = time.perf_counter()
    for k in range(count - 1):
        # print('新一轮游戏:\n')
        for i in range(row):
            for j in range(column):
                nTempSta[i][j] = CellCount(i, j)
        nCellSta = copy.deepcopy(nTempSta)
        if not printValue():
            print('全部死亡,进化结束')
            break
    endTime = time.perf_counter()
    seconds = endTime - startTime
    m, s = divmod(seconds, 60)
    h, m = divmod(m, 60)
    print('花费时间为:%d:%02d:%.3f' % (h, m, s))
阅读 3.3k
3 个回答

你算过内存需求量没?
list里一个元素占4字节,所以:
100000**2 * 4 / 1024**3 = 37G
两个数组就是 74G !
再算上其他的消耗,至少要80G内存。
可以考虑的办法:
改用bitarraybitarray,这样每个元素占1bit,内存大概降为1.5G
改善算法,去掉临时数组Temp

是不是中间结果占用内存太多了,可以把之前繁衍的那些代回收了.

In [1]: import sys

In [2]: a = [0] * 100000

In [3]: len(a)
Out[3]: 100000

In [4]: sys.getsizeof(a)
Out[4]: 400036

In [5]: b = "0"*100000

In [6]: len(b)
Out[6]: 100000

In [7]: sys.getsizeof(b)
Out[7]: 100021

算是提供一个思路吧

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题