gpt4 book ai didi

julia - 如何在 Julia 1.0 中进行记忆化或记忆化

转载 作者:行者123 更新时间:2023-12-02 00:39:09 25 4
gpt4 key购买 nike

我一直在尝试用 Julia 来内存斐波那契函数。这是我想出来的。

原始未修改的代码(用于控制目的)

function fib(x)
if x < 3
return 1
else
return fib(x-2) + fib(x-1)
end
end

这是我的第一次尝试

memory=Dict()

function memfib(x)
global memory
if haskey(memory,x)
return memory[x]
else
if x < 3
return memory[x] = 1
else
return memory[x] = memfib(x-2) + memfib(x-1)
end
end
end

我的第二次尝试

memory=Dict()

function membetafib(x)
global memory
return haskey(memory,x) ? memory[x] : x < 3 ? memory[x]=1 : memory[x] = membetafib(x-2) + membetafib(x-1)
end

我的第三次尝试

memory=Dict()

function memgammafib!(memory,x)
return haskey(memory,x) ? memory[x] : x < 3 ? memory[x]=1 : memory[x] = memgammafib!(memory,x-2) + memgammafib!(memory,x-1)
end

还有其他我不知道的方法吗?

最佳答案

正如评论中指出的,Memoize.jl包当然是最简单的选择。这需要您在定义时标记该方法。

然而,迄今为止最强大的方法是使用 Cassette.jl ,它允许您将内存添加到预先存在的函数中,例如

fib(x) = x < 3 ? 1 : fib(x-2) + fib(x-1)

using Cassette
Cassette.@context MemoizeCtx
function Cassette.overdub(ctx::MemoizeCtx, ::typeof(fib), x)
get(ctx.metadata, x) do
result = recurse(ctx, fib, x)
ctx.metadata[x] = result
return result
end
end

对正在发生的事情的一些描述:

  • MemoizeCtx 是我们定义的 Cassette“上下文”
  • overdub运行而不是原始函数定义
    • 我们用它来检查元数据字典中是否存在该参数。
    • recurse(...) 告诉 Cassette 调用该函数,但忽略顶级重载

现在我们可以通过内存来运行该函数:

Cassette.overdub(MemoizeCtx(metadata=Dict{Int,Int}()), fib, 80)

现在更酷的是,我们可以采用一个调用 fib 的现有函数,并在该函数内部记住对 fib 的调用:

function foo()
println("calling fib")
@show fib(80)
println("done.")
end
Cassette.overdub(MemoizeCtx(metadata=Dict{Int,Int}()), foo)

(Cassette 对编译器来说仍然相当困难,因此第一次运行可能需要一段时间,但之后会很快)。

关于julia - 如何在 Julia 1.0 中进行记忆化或记忆化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52050262/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com