4

我有一个 Lua 函数,给定 n,生成从 1 到 n 的系列的所有排列,并将每个唯一系列以表格形式存储在容器表中。

这个生成的表的大小很快变得非常大(而且必然如此)。大约在我尝试 n = 11 的时候,脚本将运行几秒钟,然后出现“lua:内存不足”。我有 16gb 的物理 RAM,但是在 Windows 任务管理器中查看性能监视器可以让我看到运行时消耗的 ram,并且在脚本以内存错误结束之前它只达到了大约 20%。

我发现这篇文章看起来像是我需要前进的方向:记忆 Lua 中的一个进程

由于我使用 Lua.exe 运行我的脚本,我假设我受限于 Windows 为 Lua.exe 分配的内存量。我可以增加这个金额吗?我可以使用 C# 包装程序来简单地运行 Lua 脚本(想法是它将具有更高/更少限制的内存分配)?还是我看错了方向?


4

3 回答 3

8

您需要提前存储所有排列吗?您可以改为即时生成它们。

例子:

local function genPerm(self, i)
  local result = {}
  local f = 1
  for j = 1, self.n do
    f = f * j
    table.insert(result, j)
  end
  for j = 1, self.n-1 do
    f = f / (self.n + 1 - j)
    local k = math.floor((i - 1) / f)
    table.insert(result, j, table.remove(result, j+k))
    i = i - k * f
  end
  return result
end

local function perms(n)
  return setmetatable({n=n}, {__index=genPerm})
end

local generator = perms(11)
for _, i in ipairs {1, 42, 1000000, 39916800} do
  print(table.concat(generator[i], ','))
end
于 2012-09-04T11:05:52.320 回答
4

与 finn 的回答相同,这是另一个排列生成器:

local function perms(a,lo,hi,f)
    if lo>hi then f(a) end
    for i=lo,hi do
        a[lo],a[i]=a[i],a[lo]
        perms(a,lo+1,hi,f)
        a[lo],a[i]=a[i],a[lo]
    end
end

local function gperms(n,f)
    local a={}
    for i=1,n do a[i]=i end
    perms(a,1,#a,f)
end

local function show(a)
    for i=1,#a do io.write(a[i],' ') end
    io.write('\n')
end

gperms(4,show)
于 2012-09-04T16:24:52.790 回答
1

您也许可以在 Lua 的 C++ 端使用内存映射文件,您可以通过LuaBridge为其提供 API 。

更新 1:内存映射文件的替代方案可能是 NoSQL 数据库

于 2012-09-04T08:25:14.540 回答