在树中遍历Lua函数管理内存

时间:2013-03-22 22:35:19

标签: memory recursion lua tree genetic-algorithm

我有两种算法用于在树中返回一个随机节点,其中一个节点可以有0-N个子节点(当前节点为node,节点的第一个子节点为node[1]等)。第一种算法,统一选择,从树中统一选择随机节点。它存储一个要返回的节点,因为它向下移动树,该节点被当前所在的节点替换,概率为1 /(到目前为止看到的节点数)。 Lua代码如下。

function uniformSelect(node)
    local chosen = node

    function choose(node, counter)
        counter = counter + 1
        local probability = 1/counter
        if math.random() < probability then
            chosen = node
        end

        for i = 1, node.arity do
            choose(node[i], counter)
        end
    end

    choose(node, 0)
    return chosen
end

第二个算法向下移动树,查看它当前所在的节点并以给定的概率P返回它。如果没有返回该节点,则移动到节点子节点的概率为P1,P2 ...... PN加起来为1. Lua代码。

function select(node, prob)
    local r = math.random()
    if r < prob or node.arity == 0 then
        return node
    end

    local p = {}
    if node.arity == 1 then
        table.insert(p, 1)
    else
        local total = count(node) -- total number of nodes below this one
        for i = 1, node.arity do
            -- insert probability of moving to child i into p
            table.insert(p, (count(node[i])+1)/total)
        end

    end
    -- move to a child node chosen by roulette wheel selection
    return select(node[roulette(p)], prob)
end

这些算法用于遗传编程框架。当我使用第一个算法,统一选择时,它首先在速度和内存方面工作正常。然而,第二个不能用于很多代的大量人口,它使用的内存会爆炸。我已经将这个内存增长绘制在下面,蓝线“prob”是第二个算法,select

Memory Use

对我而言,select看起来像尾递归。我也试过明确地调用垃圾收集器来看看它是否有帮助,它会略微减缓增长,但增长仍然很大。

谁能告诉我导致这种差异的原因是什么?

1 个答案:

答案 0 :(得分:1)

我绘制了正在生产的树木的平均深度,并找到了答案。使用select函数的交叉操作会增加总体中树的平均深度,从而导致程序变慢并占用更多内存。

enter image description here