1

我是一个几乎新的程序员,学习了几个月的 Python。在过去的两周里,我一直在编写一个脚本来搜索构成魔方的数字排列。

最后,我成功地在 30 秒内搜索了整个 880 个 4x4 幻方数集。之后,我制作了一些不同的 Perimeter Magic Square 程序。它发现了超过 10,000,000 个排列,因此我想将它们部分存储到文件中。问题是我的程序没有使用我的所有进程,当它正在将一些部分数据存储到文件中时,它会停止搜索新的数字集。我希望我可以让我的 CPU 的一个进程继续搜索,而其他进程将搜索到的数据存储到文件中。

以下是与我的幻方程序类似的结构。

while True:
    print('How many digits do you want? (more than 20): ', end='')
    ansr = input()
    if ansr.isdigit() and int(ansr) > 20:
        ansr = int(ansr)
        break
    else:
        continue

fileNum = 0
itemCount = 0

def fileMaker():
    global fileNum, itemCount
    tempStr = ''
    for i in permutationList:
        itemCount += 1
        tempStr += str(sum(i[:3])) + ' : ' + str(i) + ' : ' + str(itemCount) + '\n'
    fileNum += 1
    file = open('{0} Permutations {1:03}.txt'.format(ansr, fileNum), 'w')
    file.write(tempStr)
    file.close()

numList = [i for i in range(1, ansr+1)]

permutationList = []
itemCount = 0

def makePermutList(numList, ansr):
    global permutationList
    for i in numList:
        numList1 = numList[:]
        numList1.remove(i)
        for ii in numList1:
            numList2 = numList1[:]
            numList2.remove(ii)
            for iii in numList2:
                numList3 = numList2[:]
                numList3.remove(iii)
                for iiii in numList3:
                    numList4 = numList3[:]
                    numList4.remove(iiii)
                    for v in numList4:
                        permutationList.append([i, ii, iii, iiii, v])
                        if len(permutationList) == 200000:
                            print(permutationList[-1])
                            fileMaker()
                            permutationList = []
    fileMaker()

makePermutList(numList, ansr)

from multiprocessing import Pool在顶部添加。最后我用以下内容替换了两个“fileMaker()”部分。

if __name__ == '__main__':
    workers = Pool(processes=2)
    workers.map(fileMaker, ())

结果?不好了。它只是笨拙地工作。目前,多处理对我来说看起来太难了。

任何人,请教我一些东西。我的代码应该如何修改?

4

1 回答 1

1

好吧,在回答您提出的问题之前,先解决一些困扰我的事情。

numList = [i for i in range(1, ansr+1)]

我知道列表推导很酷,但是list(range(1, ansr+1))如果您需要将可迭代对象作为列表(您可能不需要,但我离题了),请这样做。

def makePermutList(numList, ansr):
...

这是相当的黑客。你有没有理由不能使用itertools.permutations(numList,n)?它肯定会更快,内存更友好。

最后,回答您的问题:如果您希望提高 i/o 性能,您应该做的最后一件事是使其成为多线程的。我并不是说你不应该这样做,我的意思是它应该是你做的最后一件事。首先重构/改进其他东西。

您需要获取所有使用全局变量的顶级代码,对其应用退格键,并重写正确传递数据的函数。然后你可以考虑使用线程。我会亲自使用from threading import Thread并手动生成线程来执行每个 I/O 单元,而不是使用多处理。

于 2013-07-15T13:08:15.040 回答