首页 > 解决方案 > 提高 Julia 网络随机化算法的效率

问题描述

我的问题如下。我有Mat神经网络的邻接矩阵。我想随机化这个网络,因为我想随机选择 4 个音符(比如 i、j、p、q),使得 i 和 p 连接(这意味着Mat[p,i] = 1)并且 j 和 q 连接并且 i 和 q 不是已连接 ( Mat[q,j] = 0) 且 j 和 p 未连接。然后我连接 i 和 q 以及 j 和 p 并断开之前的节点。在一次运行中,我想这样做 10^6 次。

到目前为止,我有两个版本,一个使用for循环,一个使用递归。

newmat = copy(Mat)
for trial in 1:Niter
        count = 0
        while count < 1
            i,j,p,q = sample(Nodes,4,replace = false) #Choosing 4 nodes at random   
            if (newmat[p,i] == 1 && newmat[q,j] == 1) && (newmat[p,j] == 0 && newmat[q,i] == 0)
                newmat[p,i] = 0
                newmat[q,j] = 0
                newmat[p,j] = 1
                newmat[q,i] = 1
                count += 1
            end 
        end
end

递归执行此操作的速度大约与 = 10^4 一样快,Niter之后我收到 Stack Overflow 错误。我该如何改进呢?

标签: for-looprecursionjulia

解决方案


我假设您正在谈论for trial in 1:Niter.

为了避免这样的堆栈溢出,一般的经验法则(在没有尾递归消除的语言中)是不使用递归,除非你知道递归深度不会超过对数。

适用的情况主要是类似于树遍历的算法,具有“自然发生的”递归结构。您的简单 for 循环的情况可以看作是它的退化变体,带有“链表”树,但不是完全自然的。

只是不要这样做。对于像这样的一些顺序处理,循环没有什么不好。毕竟,Julia 是一种命令式语言。

(如果你想用递归结构来做这个有趣或锻炼:查找蹦床。它们允许你编写结构为尾递归的代码,但分配是通过突变和堆​​上发生的。)


推荐阅读