2013-10-28 77 views
0

經過幾天的優化後,這是我的枚舉過程的代碼,其中包括爲每行W找到最佳組合。該算法將矩陣W分開,其中W的元素爲(稱爲W_legali)的元素和僅具有低於極限的元素(稱爲W_nlegali)的元素。加速枚舉過程

使用一些參數,如Media(aka 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 
+0

你試過分析它嗎? – chappjc

+0

@chappjc我現在就做了,我預先分配了'FunzObb'和'W_tot_migl'。我希望有一件大事,因爲現在它非常慢...... – gmeroni

+0

探查器確定的熱點是什麼? – chappjc

回答

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的值有效地計算了三次。存儲這個商數矩陣。

+0

非常感謝,'bsxfun'就像一個魅力!我修正了'sum(W_tot_migl,2)'並添加了一些代碼更改。它快一點!如果您腦海中浮現出來的東西可隨意分享!現在,探查器(*真實的*)繪製此圖:http://f.cl.ly/items/3g0M1x0r092h3l0e4643/file18.html – gmeroni

+0

還有一件事,我試圖使用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))); ' – gmeroni

+1

我想這是一個你不應該想'bsxfun'的情況。 :)你不需要像'n_b + 1'這樣的標量使用'bsxfun'。相反,做'(n_b + 1)* ones(1,size(MatriceCombinazioni,1))'。 – chappjc