2

我一直在寻找没有“for循环”的情况下编写以下代码。我研究了数组操作,例如bsxfun(),arrayfun或其他 MATLAB 内置函数,但无法真正弄清楚。

n = 10;
d= 2;

x = rand(n,d);
P_best = rand(n,d);
V_i = rand(n,d)
g = rand(1,d);
r_t = rand(n,1);


a1 = 0.91;
a2 = 0.21;
a3 = 0.51;
a4 = 0.58;

l = a1*a3/(n^a2*d^a4);

for i=1:n
    N_p(i,:) = 1.4962*r_t(i)*(normrnd(P_best(i,:),l*norm(x(i,:)-P_best(i,:),2))-x(i,:));
    N_g(i,:) = 1.4962*r_t(i)*(normrnd(g,l*norm(x(i,:)-g,2))-x(i,:));
end

V_o = 0.7298*V_i+N_p+N_g

任何解决方案将不胜感激。另外,我的第二个问题是,替换上述循环是否会减少运行时间,尤其是对于大型数据集?还有其他可以减少运行时间的技巧吗?我问这样的问题的原因是我正在处理大型数据集,显然减少我工作每一步的运行时间将导致流程成本的大幅降低。

4

2 回答 2

3

讨论和代码

您可以loop使用bsxfun基于矢量化的版本删除它 -

N_g_sigma = l*sqrt(sum(bsxfun(@minus,x,g).^2,2));
N_g_normrnd = bsxfun(@plus,randn(size(N_g_sigma)).*N_g_sigma,g);
N_g = bsxfun(@times,N_g_normrnd - x,1.4962*r_t);

N_p_sigma = l*sqrt(sum(bsxfun(@minus,x,P_best).^2,2));
N_p_normrnd = bsxfun(@plus,randn(size(N_p_sigma)).*N_p_sigma,P_best);
N_p = bsxfun(@times,N_p_normrnd - x,1.4962*r_t);

它基于一个黑客版本的normrnd.mas 也在另一个问题中被利用Stackoverflow-为 MATLAB 中的一系列发行版提高 NORMRND 的速度,它给了我们巨大的加速。

需要注意的是,这里使用给定标量和的normrnd.m随机数生成,如其语法所示 -musigma

function r = normrnd(mu,sigma,varargin); 
%NORMRND Random arrays from the normal distribution...

使用所提出的矢量化技术,我们在每次迭代时都输入' 和' 的数组,musigma而不是标量值,从而vectorization生效。


快速运行结果

*****************  Datasize : n = 100000 , d = 10 *******************
-------------------------------------- With original loopy code
Elapsed time is 82.344671 seconds.
-------------------------------------- With Proposed vectorized code
Elapsed time is 0.033276 seconds.

*****************  Datasize : n = 10000 , d = 100 *******************
-------------------------------------- With original loopy code
Elapsed time is 7.776902 seconds.
-------------------------------------- With Proposed vectorized code
Elapsed time is 0.032324 seconds.

这里看到的巨大加速与通过向量化的其他normrnd相关问题获得的加速一致。

于 2015-02-03T16:43:24.253 回答
1

对不起,我的错,我再次检查了你的问题,我无法帮助删除 for-loop 的部分。关于提高 for 循环速度的一些建议:

% fastest way: Elapsed time is 0.000006 seconds.
tic
for i=n:1
  N_p(i,:) = 1.4962*r_t(i)*(normrnd(P_best(i,:),l*norm(x(i,:)-P_best(i,:),2))-x(i,:));
  N_g(i,:) = 1.4962*r_t(i)*(normrnd(g,l*norm(x(i,:)-g,2))-x(i,:));
end
toc

% slowest way: Elapsed time is 0.004444 seconds.
tic
for i=1:n
  N_p(i,:) = 1.4962*r_t(i)*(normrnd(P_best(i,:),l*norm(x(i,:)-P_best(i,:),2))-x(i,:));
  N_g(i,:) = 1.4962*r_t(i)*(normrnd(g,l*norm(x(i,:)-g,2))-x(i,:));
end
toc

% 2nd choice: Elapsed time is 0.000969 seconds.
tic
N_p2(n, 2) = nan;
N_g2(n, 2) = nan;
for i=1:n
  N_p2(i,:) = 1.4962*r_t(i)*(normrnd(P_best(i,:),l*norm(x(i,:)-P_best(i,:),2))-x(i,:));
  N_g2(i,:) = 1.4962*r_t(i)*(normrnd(g,l*norm(x(i,:)-g,2))-x(i,:));
end
toc
于 2015-02-03T16:22:50.693 回答