1. 程式人生 > >011 MATLAB進階筆記:告別for迴圈,走向新巔峰

011 MATLAB進階筆記:告別for迴圈,走向新巔峰

2015-12-8

最近在參加一個數學建模比賽,關於複雜網路的( 002C語言 驗證無標度網路的冪律定律004C語言 實現小世界網路)。想到之前已經對複雜網路有所接觸,這次雖不敢說胸有成竹,但至少努力了就會有所收穫!

拋開題目不談(畢竟還沒多少思路),今天做了一些基本工作(畢竟現在的水平也就這速度!!),即分析網路的基本特徵,即平均路徑、聚類係數、度分佈等。由於最近在學習MATLAB程式設計,這一次還是選擇了MATLAB來處理(其實我也想用igraph、Pajek等聽起來牛X哄哄的工具的,奈何之前沒學,臨時學時間有限),所以默默的堅守在了MATLAB。

由於剛剛從C語言轉型到matlab,一些C語言程式設計的‘惡習

’還是改不掉,比如不斷地for loops;看看比如寫無標度網路,不過這就是C語言:接近底層,大多數細節都要你自己實現。不過既然轉戰MATLAB了,怎麼還能那麼土裡土氣,隨便一下就來個for迴圈,像這樣:


甚至用了matlab還這樣


不像話啊,今天一開始還是一直在用for迴圈,但考慮到這是比賽,而且資料本來就很大(其中兩個社會結構的網路已經把我的電腦跑崩了),所以大刀闊斧的進行了一番改進,先貼上改完後的程式碼(當然也只是才寫了一點點)

 clc, clear
 tic
source = input('input filename\n');
Con =  load(source);%turn to matrix
ConNum = length(Con);%get number of connections
ConMap = unique(Con);%reset identifier
ConMapNum = length(ConMap);%number of nodes
NewCon = zeros(ConNum, 2);
<span style="color:#ff0000;">for i=1:ConMapNum
    NewCon(Con==ConMap(i))=i;
end</span>
clear Con;
<span style="color:#ff0000;">Logic = NewCon(:,1)>NewCon(:,2);
temp = NewCon(Logic,2);
NewCon(Logic,2) = NewCon(Logic,1);
NewCon(Logic,1) = temp;
NewCon = sortrows(NewCon, 1);</span>
clear temp;
clear Logic;
%test passed
SpMatrix = sparse(1:ConMapNum, 1:ConMapNum, 0);%initial sparse matrix
<span style="color:#ff0000;">SpMatrix(sub2ind(size(SpMatrix), NewCon(:,2),NewCon(:,1))) = 1;</span>
Paths = graphallshortestpaths(SpMatrix, 'directed', false);
temp = tril(Paths);
temp(isnan(temp)) = 0;
D = max(max(temp));%diamater
Sum = sum(nonzeros(temp));
L = Sum/nchoosek(ConMapNum, 2);
toc
在來揭露一下他們原來的熊樣:

1、

for i=1:ConMapNum
    NewCon(Con==ConMap(i))=i;
end

他們原來是這樣的:
for i=1:ConNum
    for j=1:2
        for k=1:ConMapNum
            if ConMap(k)==Con(i, j)
                NewCon(i, j) = k; 
            end
        end
    end
end
這麼多巢狀不忍直視!

不過神奇的matlab編輯器還提醒我繼續優化,


於是最後成了這樣:

for i=1:ConMapNum
    NewCon(Con==ConMap(i))=i;
end

2、

Logic = NewCon(:,1)>NewCon(:,2);
temp = NewCon(Logic,2);
NewCon(Logic,2) = NewCon(Logic,1);
NewCon(Logic,1) = temp;
他們原來是這樣的:
for i=1:ConNum
    if NewCon(i, 1)>NewCon(i,2)
        temp = NewCon(i,2);
        NewCon(i,2) = NewCon(i,1);
        NewCon(i,1) = temp;
    end
end
3、
SpMatrix(sub2ind(size(SpMatrix), NewCon(:,2),NewCon(:,1))) = 1;
它原來是這樣的:
for i=1:ConNum
    SpMatrix(NewCon(i,2), NewCon(i,1)) = 1;
end

MATLAB甚至直接的表達了對我的鄙視:



不過之前C語言雖然複雜,但是是自己的一些內建函式的理解更加容易,比如:

SpMatrix(sub2ind(size(SpMatrix), NewCon(:,2),NewCon(:,1))) = 1;
和C語言用指標p定位陣列(i,j)位置為(p+i*N+j)有就很相似。

鑑於時間比較緊張,所有不對優化的具體細節及函式的解釋作介紹,這部分有時間補上。

通過幾個優化,避免了不少for迴圈,而且對於我現在處理的大型複雜網路來時,這種優化節省的時間是相當可觀的,(有tic、toc為證!!)而這些函式的另也正是MATLAB的精髓之一,作為一門工具性的語言,MATLAB不善於進行for運算,也不需要進行for運算,更不應該進行過多的for運算。學語言學的因該是這門語言的核心思想,語言有多很多,自己也接觸了不少(當然只是初窺門路),發現語法大底是相同的,主要是每種語言因為其目標的不同而形成的不同核心思想,就像用PHP寫底層,用C語言寫網站一樣,顯然是不科學的。。。。好像扯遠了。

最後扯一句:世上有不絕的語言,願你(是願我)有不絕的心情,學啊學!!