【问题标题】:Speed up an Enumeration process加快枚举过程
【发布时间】:2013-10-28 23:23:53
【问题描述】:

经过几天的优化,这是我的枚举过程代码,它包括为W 的每一行找到最佳组合。该算法将矩阵W 分离为一个矩阵,其中W 的元素大于LimiteInferiore(称为W_legali)和一个只有元素低于限制的矩阵(称为W_nlegali)。

使用Media(又名Mean)、rho_b_legali等一些参数,该算法最小化了总成本函数。在最后一部分,我找到目标函数的最低值的组合在哪里,并将其保存在W_ottimo

如您所见,该算法不是那么“干净”,并且矩阵非常大(142506x3000)非常慢......那么,有人可以帮我加快速度吗?

   for i=1:3000
   W = PesoIncertezza * MatriceCombinazioni';
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   W_legali = W;
   W_legali(W<LimiteInferiore) = nan;

   if i==1
        Media = W_legali;
        rho_b_legale = ones(size (W_legali,1),size(MatriceCombinazioni,1));
   else
        Media = (repmat(sum(W_tot_migl,2),1,size(MatriceCombinazioni,1))+W_legali)/(size(W_tot_migl,2)+1);
        rho_b_legale = repmat(((n_b+1)/i),1,size(MatriceCombinazioni,1));
   end

   [W_legali_migl,comb] = min(C_u .* Media .* (1./rho_b_legale) + (1./rho_b_legale) .* c_0 + (c_1./(i * rho_b_legale)),[],2);

   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

   MatriceCombinazioni_2 = MatriceCombinazioni;
   MatriceCombinazioni_2(sum(MatriceCombinazioni_2,2)<2,:)=[];

   W_nlegali = PesoIncertezza * MatriceCombinazioni_2';
   W_nlegali(W_nlegali>=LimiteInferiore) = nan;

   if i==1
        Media = W_nlegali;
        rho_b_nlegale = zeros(size (W_nlegali,1),size(MatriceCombinazioni_2,1));
   else
        Media = (repmat(sum(W_tot_migl,2),1,size(MatriceCombinazioni_2,1))+W_nlegali)/(size(W_tot_migl,2)+1);
        rho_b_nlegale = repmat(((n_b)/i),1,size(MatriceCombinazioni_2,1));
   end

   [W_nlegali_migliori,comb2] = min(C_u .* Media .* (1./rho_b_nlegale) + (1./rho_b_nlegale) .* c_0 + (c_1./(i * rho_b_nlegale)),[],2);

   z = [W_legali_migl, W_nlegali_migliori];

   [z_ott,comb3] = min(z,[],2);

   %Increasing n_b
   if i==1
       n_b = zeros(size(W,1),1);
   end

   index = find(comb3==1);
   increment = ones(size(index,1),1);
   B = accumarray(index,increment);
   nzIndex = (B ~= 0);
   n_b(nzIndex) = n_b(nzIndex) + B(nzIndex);

   %Using comb3 to find where is the best configuration, is in
   %W_legali or in W_nLegali?

   combinazione = comb.*logical(comb3==1) + comb2.*logical(comb3==2);
   W_ottimo = W(sub2ind(size(W),[1:size(W,1)],combinazione'))';

   W_tot_migl(:,i) = W_ottimo;
   FunzObb(:,i) = z_ott;


   [PesoCestelli] = Simulazione_GenerazioneNumeriCasuali (PianoSperimentale,NumeroCestelli,NumeroEsperimenti,Alfa);
   [PesoIncertezza_2] = Simulazione_GenerazioneIncertezza (NumeroCestelli,NumeroEsperimenti,IncertezzaCella,PesoCestelli);

   PesoIncertezza(MatriceCombinazioni(combinazione,:)~=0) = PesoIncertezza_2(MatriceCombinazioni(combinazione,:)~=0); %updating just the hoppers that has been discharged

end

【问题讨论】:

  • 你试过分析它吗?
  • @chappjc 我现在就做到了,我预先分配了FunzObbW_tot_migl。我希望有大事,因为现在它很慢......
  • 分析器识别的热点有哪些?
  • @chappjc 这是我得到的:f.cl.ly/items/0i1h1A1A362H1W3N1E22/file20.html(我用错误的输入值运行它以提高速度,但通常Enumerazione_fo 调用大约是 5000 秒或更多)

标签: performance matlab matrix heavy-computation


【解决方案1】:

当您看到repmat 时,您应该想到bsxfun。例如,替换:

Media = (repmat(sum(W_tot_migl,2),1,size(MatriceCombinazioni,1))+W_legali) / ...
    (size(W_tot_migl,2)+1);

Media = bsxfun(@plus,sum(W_tot_migl,2),W_legali) / ...
    (size(W_tot_migl,2)+1);

bsxfun 的目的是像 repmat 一样进行虚拟的“单例扩展”,而不是将数组实际复制到与W_legali 大小相同的矩阵中。

还要注意,在上面的代码中,sum(W_tot_migl,2) 被计算了两次。还有其他一些小的优化,但是改成bsxfun应该会给你一个很好的改进。

1./rho_b_legale 的值被有效计算了 3 次。存储这个商矩阵。

【讨论】:

  • 非常感谢,bsxfun 就像一个魅力!我修复了sum(W_tot_migl,2) 并添加了一些代码更改。它有点快!如果您的脑海中突然出现了什么,请随时分享!现在分析器(真正的)绘制这个:f.cl.ly/items/3g0M1x0r092h3l0e4643/file18.html
  • 还有一件事,我尝试使用 bsxfun。它是否正确? n_b_legale = repmat((n_b+1),1,size(MatriceCombinazioni,1)); 等于 n_b_legale = bsxfun(@times,n_b+1,ones(1,size(MatriceCombinazioni,1)));
  • 我猜这是你不应该认为bsxfun的情况。 :) 您不需要将bsxfunn_b+1 之类的标量一起使用。相反,请执行(n_b+1)*ones(1,size(MatriceCombinazioni,1))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 2020-05-19
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多