<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mr./Ms. Days (MMDays) - 網路, 資訊, 觀察, 生活MMDays &#8211; Computer Science</title>
	<atom:link href="http://mmdays.com/tag/computer-science/feed/" rel="self" type="application/rss+xml" />
	<link>http://mmdays.com</link>
	<description>網路, 產業, 資訊, 觀察, 生活, 電影, 技術, 新知, 科技, 媒體, 趨勢, Web 2.0</description>
	<lastBuildDate>Wed, 08 Feb 2012 17:35:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>遞迴之美: 數學, 電腦科學與碎形</title>
		<link>http://mmdays.com/2007/05/24/recursive/</link>
		<comments>http://mmdays.com/2007/05/24/recursive/#comments</comments>
		<pubDate>Thu, 24 May 2007 04:21:52 +0000</pubDate>
		<dc:creator>mmdays</dc:creator>
				<category><![CDATA[Mr. Saturday]]></category>
		<category><![CDATA[Mr. Thursday]]></category>
		<category><![CDATA[專欄]]></category>
		<category><![CDATA[數學]]></category>
		<category><![CDATA[程式設計]]></category>
		<category><![CDATA[電腦科學]]></category>
		<category><![CDATA[.kkrieger]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[computer graphics]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Fractal]]></category>
		<category><![CDATA[Hanoi Tower]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Recursion]]></category>
		<category><![CDATA[Recursive]]></category>
		<category><![CDATA[演算法]]></category>
		<category><![CDATA[碎形]]></category>
		<category><![CDATA[遊戲]]></category>
		<category><![CDATA[遞迴]]></category>
		<category><![CDATA[電玩]]></category>
		<category><![CDATA[電腦圖學]]></category>

		<guid isPermaLink="false">http://mmdays.com/2007/05/24/recursive/</guid>
		<description><![CDATA[想像一下，我剛才說了一句話，那句話是：「想像一下，我剛才說了一句話，那句話是：「想像一下，我剛才說了一句話，那句話是：..........」」，如此下去，就好像站在兩面平行擺設的鏡子中間，鏡子中的影像不斷的重複。再舉個例子，寫完一封信想要匿名保密，就署名「知名不具」。回信的人寫：「知知名不具 具」。之後再回信的時候就變成：知知知名不具具具，加上括號可能比較清楚：(知(知(知名不具)具)具)。]]></description>
			<content:encoded><![CDATA[<p align="left"><strong>Posted By <font color="#008000">Mr. Thursday </font><font color="#000000">&amp;</font> </strong><strong><font color="#964b00">Mr. Saturday<br />
</font></strong><font color="#964b00"></font><font color="#000000">(</font><font color="#ff6600">註：本篇文章有一點長，請耐心服用 XD</font>)<strong><font color="#964b00"><br />
</font></strong></p>
<p><img src="http://mmdays.files.wordpress.com/2007/05/megamonalisa_recursion.jpg" alt="monalisa-recursion" align="left" border="0" />想像一下，我剛才說了一句話，那句話是：「想像一下，我剛才說了一句話，那句話是：「想像一下，我剛才說了一句話，那句話是：&#8230;&#8230;&#8230;.」」，如此下去，就好像站在兩面平行擺設的鏡子中間，鏡子中的影像不斷的重複。再舉個例子，寫完一封信想要匿名保密，就署名「知名不具」。回信的人寫：「知 知名不具 具」。之後再回信的時候就變成：知知知名不具具具，加上括號可能比較清楚：(知(知(知名不具)具)具)。</p>
<p>遞迴就是類似這樣子，不斷的重複同樣的東西，只不過每次重複的是比較小的東西了。大家應該對數學歸納法不陌生，在使用數學歸納法時，我們首先確定 n=1 的時候某件事情是成立，然後在證明 n 到 n+1 的過程是正確的，就可以從 n=1 的例子，一路推論出第 n 項是甚麼東西。就像是推骨牌一樣，把第一張牌推倒了之後，剩下的骨牌自然就被前面的骨牌給推倒。</p>
<p><span id="more-4300"></span></p>
<p>遞迴的概念則是相反的方向：我們想要解決一個大小為 n 的問題，我首先做的事情是把問題化簡成大小為 n-1 的問題，但是解決的方法還是一樣，只不過大小是 n-1。如此繼續化簡，最後變成大小為 n=1 的基本問題，接著只要n=1的基本問題解決了，原來大小為n的問題也跟著解決了。</p>
<p>這又好像層層分工。假設每個人都會加法，然後今天我想求出 1+2+&#8230;+n 等於多少？其中一個辦法就是遞迴，我先假設 1+2+&#8230;+(n-1) 已經有人算好，那麼我只要再加上 n，就可以得到答案了。然而 1+2+&#8230;+(n-1) 要怎麼得到呢？我就請另外一位朋友幫我算。另外一位朋友接到這個問題以後，也用同樣的方法，他把 1+2+&#8230;+(n-2) 的結果交給另外一位朋友算，然後把這個結果加上 (n-1)，就變成我想要的 1+2+&#8230;+(n-1) 了。朋友的朋友也繼續用類似的方法，直到最後一位朋友只需要回答1，接著倒數第二位朋友就把1加上2，傳給倒數第三位朋友，倒數第三位朋友加上3，一直到我收到 1+2+&#8230;+(n-1) 的結果，再加上 n，就大功告成了。
</p>
<p style="text-align: center"><img src="http://mmdays.files.wordpress.com/2007/05/recursion.gif" alt="recursion" border="0" /></p>
<p>不過可能會覺得，如此簡單的問題，為何還需要遞迴呢？其實遞迴也是比較適合一些問題來解，也就是那些「解決方式一樣，但是可以化成大小比較小」的問題，除此之外還可以輕鬆解決基本問題(n=1的時候)。舉例來說，有個古老的問題叫做河內塔 (Hanoi Tower)，問題的定義引述如下 (<a href="http://www.chiuchang.com.tw/toy/hanoi/hanoi.html" target="_blank">引述網站</a>)</p>
<blockquote><p><img src="http://mmdays.files.wordpress.com/2007/05/tower_of_hanoi.jpg" alt="haoi-tower" align="right" border="0" height="187" width="262" />1883年，一位法國的數學家 Edouard Lucas 教授在歐洲的一份雜誌上介紹了一個相當吸引人的難題──迷人的智力遊戲。這個遊戲名為河內塔 (Tower of Hanoi)，它源自古印度神廟中的一段故事 (也有一說是 Lucas 教授為增加此遊戲之神秘色彩而捏造的)。傳說在古老的印度，有一座神廟，據說它是宇宙的中心。在廟宇中放置了一塊上面插有三根長木釘的木板，在其中的一根木釘上，從上至下被放置了64片直徑由小至大的圓環形金屬片。古印度教的天神指示祂的僧侶們將64片的金屬片移至三根木釘中的其中一根上。規定在每次的移動中，只能搬移一片金屬片，並且在過程中必須保持金屬片由上至下是直徑由小至大的次序，也就是說不論在那一根木釘上，圓環形的金屬片都是直徑較小的被放在上層。直到有一天，僧侶們能將64片的金屬片依規則從指定的木釘上全部移動至另一根木釘上，那麼，世界末日即隨之來到，世間的一切終將被毀滅，萬物都將至極樂世界。</p>
<p>倘若這個故事的敘述為真，那麼，我們只需加速移動金屬片，是不是就能愈早到達極樂世界呢？果真要移動這64片金屬片，那麼，至少要花幾次的搬動才能完成呢？有沒有規律可循呢？</p></blockquote>
<p>這個問題，就很符合剛才的特性：我們可以把大問題化成小問題，而且解決的方法相同，只不過問題的大小變小了。另外基本問題(n=1)，就是移動一根金屬片所需要的次數，這個我們也可以輕易解決，所以這個問題就可以用遞迴來解。</p>
<p>首先，我們假設有A、B、C三根柱子，這64片金屬片一開始在柱子A上面，我們想要搬到柱子C。因為問題中規定某個金屬片上面是空的時候才能移動，我們就假設有個人可以幫我們把<font color="BLUE">63片比較小的金屬片先從柱子A搬到柱子B上面</font>，然後我們把<font color="RED">最大的那一片從柱子A搬到柱子C</font>，再請那位朋友把<font color="BLUE">剛才的63片從柱子B搬到柱子C</font>，整個問題就解決了。然後我們只要知道剛才那位朋友搬了幾次，然後加上我們自己般動的1次，就是整個問題要求的搬動次數了。</p>
<p>遞迴不僅僅在數學上有其重要性，在電腦科學之中扮演的角色更是至關重要。程式設計者對於遞迴絕對不會陌生，上面所舉的河內塔問題，實際上也是電腦科學的經典例子之一，是初學程式設計的人一定會學到的東西。遞迴的思維，常常可以讓程式設計者打造出簡潔的程式，讓繁冗的問題透過簡單的程式碼來解決 (例如 parser 的設計)。演算法上所講的 dynamic programming，就是遞迴思維在演算法的具體呈現。</p>
<p><a href="http://mmdays.files.wordpress.com/2007/05/fractal_broccoli.jpg" title="fractal-broccoli"><img src="http://mmdays.wordpress.com/files/2007/05/fractal_broccoli.thumbnail.jpg" alt="fractal-broccoli" align="left" border="0" /></a>遞迴同時也是碎形 (fractal) 這門大學問的基石，碎形是一種相當美妙的幾何圖案，就如同上面那一張蒙娜麗莎的圖一樣，圖中有圖，形中有形，且小的部分都是大的部分的縮影，我們就稱之為碎形。碎形本身的數學定義，實際上就包含了遞迴定義在裡面，我們甚至於可以說，碎形是遞迴在幾何學的一種具體呈現。但是碎形不僅僅是一種數學概念而已，在自然界中，有許許多多的地方都出現自然的碎形，讓人讚嘆遞迴原來就出現在我們的生活周圍。圖中的這棵花椰菜，就蘊含了遞迴的碎形圖案與於其中。碎形同時也在各個研究領域有著廣泛的應用，光是在電腦科學領域，就有人把碎形應用在影像和影片壓縮之上 (這不難想像，由於碎形這種以小見大的特性，我們可以用小的來表現大的，因此可以有壓縮的概念出現)，在電腦圖學上 (computer graphics)，也有人把碎形應用在設計電腦遊戲之中的一些景物，打造出有效率和簡潔的系統。現在電腦遊戲之中的景物，很多都是玩家邊玩、遊戲系統邊產生出即時的景物，這叫做 procedural generation，這種即時產生景物的技術，可以避免遊戲軟體預先儲存一堆要展現的景物，幫整個軟體瘦身。procedural generation 就使用了大量的碎形產生與合成技術於其中，而這些都根植於遞迴這一個深刻卻簡單的思維。</p>
<p>至於把碎形應用在遊戲之中，現在已經做到有多可怕的地步了呢？請大家看看以下的三張圖片，不妨猜猜擁有這種精緻畫面的遊戲軟體，其整個遊戲的size大小是多少呢？</p>
<p align="center"><a href="http://mmdays.files.wordpress.com/2007/05/kkrieger_screenshot_01.jpg" title="kkrieger-screenshot2"><img src="/files/2007/05/kkrieger_screenshot_01.thumbnail.jpg" alt="kkrieger-screenshot2" border="0" /></a> <a href="http://mmdays.files.wordpress.com/2007/05/kkrieger_screenshot_02.jpg" title="kkrieger-screenshot3"><img src="/files/2007/05/kkrieger_screenshot_02.thumbnail.jpg" alt="kkrieger-screenshot3" border="0" /></a> <a href="http://mmdays.files.wordpress.com/2007/05/kkrieger_screenshot_03.jpg" title="kkrieger-screenshot1"><img src="http://mmdays.wordpress.com/files/2007/05/kkrieger_screenshot_03.thumbnail.jpg" alt="kkrieger-screenshot1" border="0" /></a></p>
<p>正確答案是97KB！沒錯，我沒有打錯字，你的眼睛也沒有看錯，這款遊戲的大小只有 97KB！傳統的一片 3.5 吋磁片可以裝下十幾個這款遊戲！這一款第一人稱的射擊遊戲叫做 .kkrieger，是由德國的 <a href="http://en.wikipedia.org/wiki/Demogroup" title="Demogroup">demogroup</a> <a href="http://en.wikipedia.org/wiki/.theprodukkt" title=".theprodukkt">.theprodukkt</a> 所開發，截至目前為止還在beta測試版的階段，這款遊戲之所以可以壓縮到這麼小的境界，就是因為遊戲之中的場景和音樂幾乎全部都是由動態產生，遊戲之中預先存放的資料只有一些簡單的幾何形狀和 MIDI 音樂檔，所以自然檔案大小非常小。如果這款遊戲沒有用 procedural generation 的技巧進來的話，估計檔案大小會爆增成 200~300MB，這樣的技術，真是令人嘆為觀止。而背後最大的功臣，就是這篇文章談到的遞迴和碎形。各位也不妨下載來玩玩看吧 (<a href="http://212.202.219.162/kkrieger#20" target="_blank">下載點</a>)。不過需要注意到一件事情，這款遊戲的載入時間非常長，因為他要靠著一點點的程式碼即時來運算製造出場景，所以要耗去很多計算時間，這可說是一種 time 和 space 的 tradeoff。</p>
<p>看完這篇文章，各位有沒有對看似枯燥的數學有了一點點不同的看法呢？沒想到遞迴可以這樣應用在遊戲開發之中吧。下次學習數學感覺到枯燥時，不妨從應用的角度切入試試看吧！<br/>
<div>
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td><a href="http://plurktop.mmdays.com/replurkdetail/?link=22d99f0db208bdd564d2a2635d9c37b8" title="看看其他人討論內容" target="_blank"><img src="http://plurktop.mmdays.com/images/replurk_1.png" style="border:0"></a></td>
</tr>
<tr>
<td><a href="http://plurk.com/?qulaifier=shares&#038;status=http%3A%2F%2Fmmdays.com%2F2007%2F05%2F24%2Frecursive%2F+%28%E9%81%9E%E8%BF%B4%E4%B9%8B%E7%BE%8E%3A+%E6%95%B8%E5%AD%B8%2C+%E9%9B%BB%E8%85%A6%E7%A7%91%E5%AD%B8%E8%88%87%E7%A2%8E%E5%BD%A2%29+-+%E8%BD%89%E5%99%97%E6%8E%92%E8%A1%8C%E6%A6%9C+http%3A%2F%2Fplurktop.mmdays.com%2Freplurk" title="推到噗浪" target="_blank"><img style="border:0" src="http://plurktop.mmdays.com/images/replurk_2.png" /></a></td>
</tr>
</table>
</div>
<p><br/><a href="http://www.facebook.com/MMDays" target="_blank">加入MMDays在facebook的粉絲團 隨時閱讀最新文章</a><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://mmdays.com/2007/05/24/recursive/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>

