【问题标题】:Python - Optimizing Memory Usage, genetic algorithmPython - 优化内存使用,遗传算法
【发布时间】:2017-07-19 21:46:16
【问题描述】:

我最近完成了遗传算法的编写。该算法创建了一个包含 50 个测试用例的列表,并通过模拟运行该试验,并存储结果。我使用了许多自定义类,存储的结果包含类实例的列表。

当我运行这个模拟时,它运行我的内存使用率高达 90+%。我的代码中一定有某个地方只是占用内存,但我不确定如何找到它。这是我的代码的主要部分,循环内循环内循环......

        # ----------------------------------------------------------------------------------------------------
    for i in range(1,numberOfRunsToSolve,1): # begin genetic algo loop
        temp = trial_cases
        for ii, stored_trial in enumerate(temp): # run through stored trial cases
            new_trials = []
            for jj in range(1,numberOfTrialsPerRound):
                tc = []
                tc = randomTrials_GenAlgo_ARRAY(stored_trial, True) # create new trial set, based on indexed stored results
                new_trials.append(tc)
            print(new_trials)

            for j, trial in enumerate(new_trials):
                x = OneGenerationSimulation(trial) #returns [ObjArray, ErrorArray]
                rev = revenueAndLoss(x[0])
                DEBUG_ARRAY.append(str(revenue)+' trial: ' + str(trial))
                results.append((revenue, trial, x[0],x[1]))


        results.sort(reverse=True)  # sort to bring best revenue to top
        results = results[0:numberOfResultsToKeepPerRound-1] 

        trial_cases = []
        for i, r in enumerate(results):
            trial_cases.append(r[1])

        # end of the genetic algo loop
    # ----------------------------------------------------------------------------------------------------

关于如何在我的脚本中跟踪内存使用情况并追查罪魁祸首有什么建议吗?我对 Python 很陌生,所以请随意说明这一点。

编辑:上面的过程本质上是这样做的: 1) 创建 50 次试运行。
2) 在每次试验中运行模拟。此模拟创建数百个自定义对象,并在它们上运行脚本,返回结果。 3) 使用所有返回的结果,检索最好的 5 个结果。 4) 有了这 5 个结果,创建新的试验集,并再次重复该过程。

我担心质量对象实例创建,然后被过滤到最好的 5 个结果,没有在内存或其他东西中正确清理......并且所有这些对象都隐藏在后台....

谢谢 - KC。

【问题讨论】:

  • 我首先要看的是递归,但如果我理解正确,那么您已经发现这些循环肯定是问题所在;对吗?
  • 是的,当然。自定义对象的东西可能也不是最有效的 - 但除了上面看到的之外没有太多代码(我在 Juypter fwiw 中这样做)
  • 我会尝试的一件事是通过尝试较小的数字(对于numberOfTrialsPerRoundnumberOfRunsToSolve)来查看这些巨大的数组数组是否会导致问题,并查看这是否会产生重大影响。不过,我还没有看到任何明显浪费的东西……
  • “收入”在哪里设置?您指的是 “rev” 吗?我不确定您获得了多少结果与保留了多少结果。但是,不是得到所有结果,而是对所有结果进行排序,然后丢弃一些。只保留你需要的呢? IE。做一个“插入排序”类型的事情。你能摆脱 DEBUG_ARRAY 看看它是否有帮助?如果内存是一个问题,你可以看看垃圾收集是否有帮助。此外,没有理由在最终循环中使用enumerate,只需使用trial_cases = [ r[1] for r in results]
  • 对不起 - 你是对的。收入 = 转。我试图在上面缩短我的变量。

标签: python algorithm


【解决方案1】:

这是您可以使用的快速而肮脏的插入排序。您可以内联此代码而不是函数,以避免函数调用开销。

def top_insert(my_list, item, keep_only = 10):
    rev = item[0]
    newlist = [ i for i in my_list if i[0] > rev] 
    if len(newlist) >= keep_only:
        return newlist[:keep_only]
    elif len(newlist) == (keep_only - 1):
        return newlist + [item]
    else:
        return newlist + [item] + my_list[len(newlist):keep_only-len(newlist)-1]

【讨论】:

  • 根据编辑,这可能不是解决方案。对 50 个事物进行排序不会对性能造成巨大影响。
  • 我认为问题在于它正在排序的每个项目都包含大量信息/使用大量内存。在这里查看我的另一个问题:stackoverflow.com/questions/42517635/… 一旦我进行了排序插入,它就会降低我存储的项目数量
猜你喜欢
  • 2020-07-08
  • 2015-02-18
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多