-2

我在 Matlab 中遇到了这个问题:调用了很多函数之一,达到了 500 的最大递归限制。这真是令人沮丧。网络上有很多关于这个问题的信息。但我看起来很好,这个问题没有单一的真正解决方案。即使使用 set(0,'RecursionLimit',N) 增加递归限制也无济于事,因为在我这样做并运行我的代码之后,Matlab 崩溃(并且对于任何值 N Ii 都会崩溃)

仅供参考,我的代码应该调用其中一个函数超过 500 次,所以它没有任何问题。那么有什么方法可以增加 Matlab 的递归限制(不让它崩溃)或者更好地让它没有限制?

4

3 回答 3

1

说 500 倍递归没有任何问题本身可能是错误的。

递归的一个问题是 MATLAB 必须在每次调用函数时设置单独的工作区,并建立一个堆栈。这可能非常低效,会占用大量时间和内存。因此,您所做的事情很可能有问题。

同样,我经常看到递归函数可以重写为非递归函数。可以使用诸如记忆化之类的技术来避免多次递归地评估相同输入上的函数。为什么相同的计算不止一次?

您可以更改堆栈大小的限制,但通常这些限制是相当合理的,并且放置在那里是为了防止内存和时间问题。所以你最好认真查看你的代码来决定这样的改变是否合适,而不是重新制定你的问题。

例如,您可以使用递归计算阶乘,但何必呢?当一个简单的循环效率更高时,这是一个非常愚蠢的解决方案。当循环足以解决问题时,堆栈的开销远远超过您想要的开销。

另一个例子是斐波那契数列。它可以递归地编写,这是一件容易的事,但这根本不是一件好事。完全递归计算,第 n 个斐波那契数将需要指数时间和内存来计算 F(n)。循环更好,它允许你做 O(n) 的工作量。更好的是,记忆方案加上正确的身份允许在 O(log2(n)) 时间内计算 F(n)。

关键是,你可以用递归解决很多问题,但这并不意味着这是正确的方法。

于 2013-05-05T23:18:37.123 回答
1

问题:达到最大递归限制 500。使用 set(0,'RecursionLimit',N) 更改限制。请注意,超出可用堆栈空间可能会使 MATLAB 和/或您的计算机崩溃。程序:

puma560;
robot=p560
N=5; % Numero de Iteraciones
z=linspace(0.432,0.482,N); % se mueve 0.05 unidades
x=zeros(1,N);
y=x;
for j=1:N
y(1,j)=-0.15;
x(1,j)=0.452;
end
phi=zeros(1,N);
for k=1:length(z)
phik=phi(k);
T(:,:,k)=[cos(phik) -sin(phik) 0 x(k); 
          sin(phik) cos(phik) 0 y(k); 
          0 0 1 z(k);
          0 0 0 1];
end
qzz=ikine(robot,T)
plot(robot,qzz)

y=linspace(-0.15,0.05,N); % se mueve 0.20 unidades
x=zeros(1,N);
z=x;
for j=1:N
x(1,j)=0.452;
z(1,j)=0.482;
end
phi=zeros(1,N);
for k=1:length(y)
phik=phi(k);
T(:,:,k)=[cos(phik) -sin(phik) 0 x(k); 
          sin(phik) cos(phik) 0 y(k);
          0 0 1 z(k);
          0 0 0 1];
end
qyy=ikine(robot,T)
plot(robot,qyy)

x=linspace(0.452,0.702,N); % se mueve 0.25 unidades
y=zeros(1,N);
z=y;
for j=1:N
y(1,j)=0.05;
z(1,j)=0.482;
end
phi=zeros(1,N);
for k=1:length(x)
phik=phi(k);
T(:,:,k)=[cos(phik) -sin(phik) 0 x(k);
          sin(phik) cos(phik) 0 y(k);
          0 0 1 z(k);
          0 0 0 1];
end
qxx=ikine(robot,T)
plot(robot,qxx)

y=linspace(0.05,-0.05,N); % se mueve 0.10 unidades
x=zeros(1,N);
z=x;
for j=1:N
x(1,j)=0.702;
z(1,j)=0.482;
end
phi=zeros(1,N);
for k=1:length(y)
phik=phi(k);
T(:,:,k)=[cos(phik) -sin(phik) 0 x(k);
          sin(phik) cos(phik) 0 y(k);
          0 0 1 z(k);
          0 0 0 1];
end
qyy=ikine(robot,T)
plot(robot,qyy)
于 2016-03-30T09:29:45.353 回答
0

您可以尝试增加 MATLAB 使用的堆栈大小,因为一旦堆栈已满,递归通常会中断。

请注意,调用500 次的函数和递归500 次的函数之间存在根本区别。在 MATLAB 中,后者相当少见。你确定你需要这个递归吗?

于 2013-05-05T22:54:24.090 回答