封存 Archive
封存 Archive
計算數學入門系列 - 編寫程式模擬社會隔離(一)
- 取得連結
- X
- 電子郵件
- 其他應用程式
以往其中一篇科普系列裏面提到一個簡單的數學模型,去解釋社會隔離現象的產生。 (有興趣的讀者,可以先參閱《數學、社會隔離與生命遊戲》)假設在一個社區內只有兩個不同的群體,我們用標籤A跟標籤B表示這兩個不同的背景群體。所代表的,可能是貧與富,也可能是華人與白人,也可能是喜歡自由黨或喜歡民主黨的。數學上,這個社區內所有的標籤,我們都可以用一個矩陣外表是,我們將它寫X(i,j)。這一個矩陣X裏面這個成員X(i,j),我們可以用1表示這個平房內的家庭有着標籤A,用2表示這個房間內家庭都有着標籤B。而如果這個房子還沒有成交,沒有人居住,我們就可以用0表示。這個我們以前提到的數學模型,用上下左右以及左上,右上,左下,和右下一共八間房子去定義「鄰居」。假設現在看(i,j)這個地方,他的鄰居將會是這八個,(i-1,j-1), (i-1,j), (i-1,j+1), (i,j-1), (i,j+1), (i+1,j-1), (i+1,j), (i+1,j+1)。要去定義「喜好」最簡單的方法,就是看這八個鄰居有百分之多少是跟我自己的標籤一樣。如果這個百分比太少,住在原本(i,j) 的人,就會搬離這個房子到其他地方居住。
如果我們要編寫一個MATLAB程式,如何可以簡單地說出在我旁邊有多少鄰居是跟我同一個標籤的呢?用一個簡單一點的例子,我們只考慮3×3的範圍,而我自己就住在(2,2) 這個地方。所以編寫程式的目的,就要看看在這個X矩陣裏面有多少個元素是跟X(2,2) 一樣。最簡單(亦是最簡陋)的編寫方法是,
count1=0;
if (X(1,1)==X(2,2))
count1=count1+1;
end
if (X(1,2)==X(2,2))
count1=count1+1;
end
…
if (X(3,3)==X(2,2))
count1=count1+1;
end
中間包含了八個condition。這個編寫的方式沒有錯誤,可是編寫起來非常麻煩,中間需要有很多copy-and-paste 和改動(所以編寫時,忘記了改寫某一些行的時候就很大機會有bug),而且看起來程式會非常長。另外一個好一點的辦法,是編寫兩個for-loop,程式將會大大縮短。
count1=0;
for i=1:3
for j=1:3
if (X(i,j)==X(2,2))
count1=count1+1;
end
end
end
count1=count1-1;
要留意的是,由於我們沒有(也不想,要不是編寫起來也相當麻煩)把中間的這一個點分開來考慮,所以在兩個for-loop 裏面我們是把我自己的標籤多算了一次。這就解釋了為什麼我們需要在最後一行把數字減去1。如果不想這樣做,我們剛開始的時候可以定義count1 為 -1,這樣就可以刪去最後一句。一個更好(而且執行起來也更快) 的方法,是用MATLAB自己的內置程式,
count1=[X==X(2,2)];
count1=sum(count1(:))-1;
第一項把矩陣變成一個logical 矩陣放到count1,如果矩陣的那一個元素是等於X(2,2),在矩陣count1 的那一個位置,將會是等於1。其他的情況,count1 那一個元素將會等於0。然後第二行,count1(:) 會將count 這個矩陣變成一支向量,在這個情況他就是一個9×1的矩陣。而MATLAB 的內置函數sum 就可以將這個向量每一個元素加起來。最後我們將之前的答案減去1 (就是X(2,2) 這個位置得出來的1),再放回count1這個變量裏面。
- 取得連結
- X
- 電子郵件
- 其他應用程式
留言
發佈留言