一旦N>>我的脚本似乎卡住了1

时间:2018-02-04 10:39:47

标签: python arrays

编辑:

所以我让代码运行了70个小时,但它没有返回。因此,我坚持我的观点,它确实卡在某些东西上,默默地失败并让bash挂起。从与N1和N2之间的相对小的跳跃相比的时间增加,它不是O(N) - >。 O(N²)可以解释。

(从N到2N的输入意味着执行时间从N²到4N²,因此它应该只需要4倍的时间。在2小时后不返回,而在15分钟内完成N则意味着某些操作失败)

接受的解决方案非常有效,直到(立即)达到非常干净的内存溢出。

  

$ py so_mysan.py 400000000回溯(最近一次调用最后一次):文件   “so_mysan.py”,第36行,in       sys.exit(main(sys.argv [1:]))文件“so_mysan.py”,第8行,主要       ordering = list(range(N))MemoryError

感谢您的时间。

/编辑

import sys
import numpy as np 
from random import randint

def main(arguments):
    N = int(sys.argv[1])
    # definissons notre ligne de maison : 
    houses = [0]*N
    emptySlot = list(range(0,N)) 
    # counter = 1 
    while (len(emptySlot)>0):
        # on prend une maison vide possiblement habitable par un mysanthrope, au hasard. 
        empt = randint(0, len(emptySlot)-1)
        houses[emptySlot[empt]] = 1
        # on enlève cette maison de notre liste de possibilité 
        # et éventuellement les maisons adjacentes si elles y étaient
        temp = emptySlot[empt]
        del emptySlot[empt]
        # on essaye d'enlever les autres si existes plus efficacement : 
        if (0<=empt and empt<len(emptySlot) and emptySlot[empt] == temp+1):
            del emptySlot[empt] # comme on a viré l'index empt, ça décale.
        if (empt-1 >= 0 and emptySlot[empt-1] == temp-1):
            del emptySlot[empt-1] # pour l'inférieur, cela ne change rien

    occupancyRate = sum(houses) / N
    print(occupancyRate)

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))

我想这与数组大小有关,但我的资源监控并没有显示CPU或RAM通过屋顶。它运行良好,最高可达N = 4.10 ^ 6

我不认为多线程是可能的或值得的,因为它只是一个数组被操纵。

我可以做些什么来优化它?

如何调试这样的脚本?我需要知道它是“卡住”还是只花了不可思议的时间。

由于

1 个答案:

答案 0 :(得分:2)

这可能应该是代码审查,因为它是一个复杂性问题,但是再次,编写的算法不适用于大N:s所以我将采用另一种方法。

删除列表中间的元素可能会导致很多(并且代价高昂)的内存操作。通过首先准备(随机)元素列表然后以线性方式访问它们,尝试将它们保持在最低限度要好得多。有一个非常漂亮的函数random.shuffle可用于生成随机列表:

import random

N = 10000000

ordering = list(range(N))
random.shuffle(ordering)

houses = [0]*N

for elem in ordering:
    if (elem == 0 or houses[elem-1] == 0) and (elem == N-1 or houses[elem+1] == 0):
        houses[elem] = 1

occupancyRate = sum(houses) / N
print(occupancyRate)

在此代码中,首先生成随机元素顺序(使用random.shuffle),然后线性访问此随机列表。我也不会在列表中删除任何元素,因为很少或根本没有增益,因为最大内存消耗仍然是相同的。

这可能会为您提供更好的运行时间,并允许您处理更大的列表。但是,算法在时间和内存消耗方面仍然是线性的,所以你也会为这个算法找到一个顶点。