目錄

20200718 想法源起 20200719 我們在做什麼(一) 20200722 我們在做什麼(二) 20200725 竟然成為數學家(一) 20200729 竟然成為數學家(二) 20200801 竟然成為數學家(三) 20200805 不同職級(一) 20200808 不同職級(二) 20200812 趕客系列(一)為什麼讀大學? 20200815 趕客系列(二)不同大學學位跟工作的關係 20200819 趕客系列(三)大學的目的 20200822 趕客系列(四)大學為什麼要有主修 20200826 趕客系列(五)要挑選一個什麼樣的主修 20200829 沒有無緣無故的恨(一) 20200831 科普系列 - 數學與電影動畫製作(一) 20200902 沒有無緣無故的恨(二) 20200905 沒有無緣無故的恨(三) 20200907 科普系列 - 數學與電影動畫製作(二) 20200909 終身職位的評核 20200912 學術界吸引人的地方 20200914 科普系列 - 數學與電影動畫製作 (三) 20200916 學術界辛苦的地方(一) 20200919 學術界辛苦的地方(二) 20200921 科普系列 - 數學與電影動畫製作 (四) 20200923 大學的讀書成績有多重要 20200926 本科生研究機會 20200928 科普系列 - 數學與圖像修復(一) 20200930 用創新的方法去教育科學 20201003 參加研討會的重要 20201005 科普系列 - 數學與圖像修復(二) 20201007 教授與教學 20201010 研究是什麼(一) 20201012 科普系列 - 數學與圖像修復(三) 20201014 研究是什麼(二) 20201017 研究是什麼(三) 20201019 科普系列 - 數學與圖像修復(四) 20201021 如何閱讀研究論文 20201024 研究生應該修什麼課 20201026 科普系列 - 數學與圖像修復(五) 20201029 本科生的多主修多副修 20201102 科普系列 - 數學與數獨(一) 20201105 幾位教授(一) 20201109 科普系列 - 數學與數獨(二) 20201112 幾位教授(二) 20201116 科普系列 - 數學與數獨(三) 20201119 幾位教授(三) 20

計算數學入門系列 - 編寫程式模擬社會隔離(一)


以往其中一篇科普系列裏面提到一個簡單的數學模型,去解釋社會隔離現象的產生。 (有興趣的讀者,可以先參閱《數學、社會隔離與生命遊戲》)假設在一個社區內只有兩個不同的群體,我們用標籤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這個變量裏面。


留言