針對查詢「迷宮」依日期排序顯示文章。依關聯性排序 顯示所有文章
針對查詢「迷宮」依日期排序顯示文章。依關聯性排序 顯示所有文章

星期日, 4月 24, 2011

20110424 生活雜記

很是奇怪,自己明明應該有不少自由時間,為什麼每天總是匆匆忙忙,疲累不堪?

想想自己每天的一些例行事。每晚幾乎都要督促大隻的完成作業、帶小隻的讀經(最近由於大隻的闖了很久的關都沒有過,也花了許多力氣帶她讀)、並催促她們早些上床(第二天早上六點多就得起床上學)。或許,也是因為最近工作上的事情多了些,而自己總是得在小朋友入睡後才能趕寫論文、修改程式或投影片,造成睡眠不足、或睡眠品質不佳的緣故吧?(雖然知道該把工作移到早上進行,但還是習慣在晚上寫程式,真是糟糕...)

今天天氣好,早上小朋友也起得夠早,吃過早餐後就帶她們去兒童育樂中心玩。花博展期即將結束,人潮多到有些誇張。還好多數的人都去擠展館,兒童育樂中心的遊客並不算多,小朋友只需要稍稍排點隊,就可以玩到遊樂設施。

雖然不喜歡人擠人的感覺,也認為花博展區的規劃有許多缺點,但自己對花博的整體評價還是相當好的。至少,我覺得花博對於行動不便人員的考量是少見的。

由於使用的是全期間票,住家附近又有接駁車,所以有機會就儘可能去花博逛逛 -- 即使有時僅僅是從新生園區進入,穿過美術園區後再從圓山園區離開。半年來,陸陸續續也遊覽過多數的展館,對於未來館的特有植物展、第一期爭豔館的國際展覽、舞蝶館的百合戀,以及早期的迷宮花園(大概是怕遊客走不出迷宮,後來迷宮花園裡打通了許多原本較為曲折的路線)、真相館的 3D 電影等都留下頗為深刻的印象。

大隻的以前並不喜歡跟妹妹一起玩。幾個月前我開始用利誘(偶而加上一些小小的威脅)的方式,讓大隻的跟妹妹一起玩。雖然她們玩著玩著經常會爭吵或甚至打架(通常都是姊姊被妹妹打,然後大哭或大叫),但大隻的最近已經比較願意跟小隻的一起玩,想來還是頗有成就感的。

星期二, 11月 23, 2010

遊花博雜記

幾個星期沒有更新網誌了。不是因為什麼噗浪之類的部落格殺手,而是自己越來越懶得去維護。

由於工作的時間相當有彈性,花博(2010 臺北國際花卉博覽會)開幕沒幾天,想說先去探探行走的動線,方便日後帶小朋友遊覽,沒想到走了半天下來,卻著實感覺相當舒暢。

當天還沒八點半就出門去找花博的轉運車站。搭 2 號接駁車到圓山站後,看看時間還沒有九點,就興致匆匆地跟著一大群人轉搭 1 號接駁車到新生公園。看到身旁的大人小孩都興匆匆地往前跑(準備排隊拿夢想館的預約券),自己也不禁跟著小跑步起來(一邊跑一邊笑,怎麼大家的興致都這麼高啊)。

拿到 2:10pm 的預約券後,順著人潮往未來館走。大概是因為時間還算早,排隊的人並不算多。接著又去看了天使生活館,走了屋頂的青青步道。看著小朋友在迷宮花園裡面跑來跑去,處處充滿著笑鬧聲,自己也情不自禁地走了一趟。人潮不多時,逛花茶殿(林安泰古厝)的感覺也非常棒。

也去探了一下大佳園區,坐了坐園內線的接駁車。看過夢想館後,一路從新生館區穿過美術館區,走到圓山館區搭車回家。

由於感覺太過美好,過了幾天就和太太一起再去走一遭。想說自己很可能會去許多趟,就買了 NT$2500 的全期間票,方便日後多次進出。

雖然夢想館是人潮最多的展館,但我其實並不怎麼喜歡。感覺起來,未來館裡的各式奇珍異卉,反而更有看頭。天使生活館裡也有一個地方很有意思,明明是一塊地板,投射後卻可逼真地看到許多魚兒在水中游來游去。想到未來科技更為發達,或許四處可見這類真假難辨的影像呢...

爭豔館是太太的最愛。我對花卉花藝都沒什麼研究,卻也能隱約感到參展作品的用心與美麗。使用 152 萬個保特瓶(回收重新融合壓製保特瓶磚)所蓋的保特瓶館(流行館)據說創下多項世界第一,想想也真的是很不容易。

帶小朋友逛花博的焦點就不一樣了。只要不是靜態的展覽,小朋友好像都很感興趣。只是週末人潮特多,我們也不喜歡排長龍的等待,所以幾趟下來她們也只參觀了夢想館、迷宮花園、毛毛蟲大遊行、保特瓶館、以及晚間大佳河邊的光雕。小朋友對花博娃娃(就是那五隻花精靈和芽比)、紀念品和坐船遊河似乎最感興趣,回家後都還念念不忘呢。

星期五, 7月 25, 2008

20080725 生活週記

上週的清境之旅因故提前回家,在小寶寶病情穩定後,我們打算盡量帶小朋友在台北遊玩。

星期日,天氣晴。讓小傢伙選擇動物園或兒童樂園,她和妹妹都選前者。雖然氣溫熱得嚇人,但豔陽下去給動物看的遊客還是頗多。這一趟動物園之旅,在禮品店買了一隻長頸鹿的夜光石頭,算是沒有在清境農場看到小羊的補償,小傢伙很是高興。

星期三到中正紀念堂參觀「長毛象特展」。門票有些貴,成人要價兩百,小朋友則需一百八。我和太太對化石與考古都沒什麼了解,事先也沒做功課,進展場沒多久,小傢伙就吵著要去餵魚了。


比起看展覽,餵魚的成本低很多。十元的魚飼料通常可以餵上十幾分鐘。由於剛好有隻夜鷺(我其實並不確定是什麼鳥禽,還是麻煩貓鑑定一下吧)飛到不到一公尺外的石頭上(牠飛到眼前的速度頗快,把我和小傢伙都嚇了一跳),我和小傢伙都感到頗新奇。這次除了餵到魚和烏龜之外,還看到兩回夜鷺捕吃小魚的景象,小傢伙很是滿足。


放暑假前,薇閣幼稚園發給小朋友一本「臺北兒童藝術節」的「童遊世界護照」,裡面介紹了許多暑期台北市政府主辦、贊助的表演活動。想想暑假已經過去三分之一了,而我們卻都沒有帶小朋友去看這些表演,實在有些說不過去。因此,今天帶小傢伙到「台北偶戲館」去看了場野台布袋戲《神魔對決》。

自己大概有二十幾年沒有看過野台布袋戲了,因此自己是看得興味昂然。一開始團主黃文郎還花了許多時間介紹布袋戲在台灣的演進歷程,很能打動我的心。不過,音響的聲音很大,小朋友必須摀著耳朵才敢欣賞;而我的台語程度並不好,對於許多妙詞對話,其實也聽得不是很懂。

看完布袋戲,帶著小朋友到偶戲館走了一圈,看看百年來的布袋戲偶,玩玩皮影戲。問她喜不喜歡布袋戲,她回答說「很喜歡,但更喜歡偶戲館內用紙搭建的一座小小迷宮!」

星期六, 4月 14, 2007

產生迷宮的另一種方法

約一年多以前,曾寫了些關於「如何產生迷宮」的 Blogs。

前些時日,在書店亂逛,無意間看到一本關於資料結構與演算法的書,裡頭提到利用 Set Union 來產生迷宮的方法(Weiss: Data Structures and Algorithm Analysis in C++, 3rd edition, pp.331-334)。

這個方法的概念很簡單:
  1. 首先,將地圖中的每個單位 (cell) 視為個別的小集合,然後將這些集合的 collection 稱為 C。

  2. 隨意從 C 裡抽出兩個集合 x, y。若這兩個集合「打掉一面牆」之後可以連通,那麼就將這兩個集合聯集 (union) 成集合 z,並將 z 放入 C 中。

  3. 反覆執行步驟二,直到最後 C 只含有一個集合為止。

我覺得這個演算法很漂亮。

春假期間騰出一些時間,用 PHP5 把它實作出來。(為了避免無效率地從 C 中挑選元素,我先將所有「可被打破的牆」排序並打亂後,逐一檢視每一面牆「若被打掉後,是否相當於將 C 裡的兩個元素作聯集的動作」。)


產生的迷宮「效果」如何?我覺得還算不錯。它似乎比「稍微有些曲折的迷宮」的結果來得有變化,但並沒有「更為曲折的迷宮」所產生的迷宮那麼蜿蜒。

星期一, 2月 05, 2007

提升眼光的高度

在電子報上,看到龍應台的一篇文章:「自首報告:路走得寬闊,人顯得從容」。

很難形容看過以後錯綜複雜的整體感覺。或許,印象比較深的感覺就是「現實是很複雜的」。多複雜?一個例子是龍應台說的「道德不能處理法律問題,法律又不能處理政治問題」,而現實卻又不僅僅是道德、法律與政治問題。

有時想想,對一個人的了解不多,卻讓媒體新聞的炒作評論來帶領自己對政治人物的觀感,實在是件頗為悲哀(悲傷痛苦)的事。雖然看膩了、聽多了,也習慣不把它們當作一回事。但是,這些媒體評論來來去去,除了激發各個陣營「自以為是」的片面觀感,卻似乎很少能提升民眾對於「民主」、「法治」、或者「道德」的認知,這樣是否類似於「在原地空轉」,以致「太浪費社會整體資源」了呢?

很喜歡文章中所說的:「白老鼠走不出他的迷宮隧道,因為他自始至終在迷宮隧道裡打轉,沒有高度,就無法綜觀全局,看見出口」。沒有提升到一定的高度,就不容易找到出口(或者問題的解答)。

因此,就像文章所說,真正的問題應該是:「我們眼光的高度要放在哪裡,才能在複雜混亂中看見出口?」看待紛亂的的社會,應該從這樣的角度著手;而即使範圍縮小,思考公司、實驗室、乃至於個人的的研究與發展,似乎也應如是。

星期二, 11月 08, 2005

摸著牆走迷宮

在迷宮裡,要如何找到出口呢?

很多人應該都聽過「摸著牆壁走」的方法:只要一直摸著右邊(或者左邊)的牆走,最後一定可以走出迷宮(例如,「迷宮、黃金比、索馬立方體」這本書,就有提到這種策略)。

但是,為什麼這種策略可以行得通呢?


原來,在概念上,沿著一邊的牆壁走,就相當於在執行「深度優先搜尋」(DFS, depth-first search)。參考上面的圖形,應該可以給我們一些感覺:給定左側的小迷宮,目標是由 A 點走到 C 點;而迷宮的樹狀圖(在此先假設迷宮任兩點間只有唯一的一條路)如中間圖所示:最右側的圖,則畫出「摸著右側牆壁走」的路線(迷宮中的藍線,就相當於樹狀圖)。

這樣的走迷宮策略,有什麼限制嗎?如果,迷宮是多連通(multiple-connected,兩個迷宮格之間,不必然只有唯一的路)的,那怎麼辦呢?

一般來說,即使迷宮是多連通的,「摸著牆走迷宮」的策略依然行得通。例如,在下面的圖形裡,我們要從入口 A 點,走到出口 D 點。因為 F-E-I-M-N-O-P-L-K-G-F 構成一個圈 (circle, loop),因此從 F 到 G 有兩條路可走:F-E-I-M-N-O-P-L-K-G 或者 F-G。中間的圖形,說明了沿著右側牆壁走,依然可以從 A 點走到 D 點。(事實上,只要「迷宮出入口」不在這個圈子內 --- 例如 J 點 --- 這個方法就行得通。)


像這樣的圖說,當然不能算是證明。不過,有了直觀後,通常證明就呼之欲出了。有趣的是,這樣的走迷宮策略,與現實生活處理問題的方式,還有著可類比之處:有 時,我們會找不到方法來解決現實環境碰到的問題。這種時候,或許只能依靠「摸著牆壁走」的方式,藉由拓展對問題(空間)的認知,一步一步地走出迷宮呢。

星期五, 10月 14, 2005

誤打誤撞

這幾天試圖整理迷宮的 PHP 程式,讓它看起來清爽漂亮些。

「整理」的工作,大致上就是清除一些非必要(或為了除錯而加上去)的函式,在一些地方加上註解,並重寫部分的程式碼。

奇怪的是,我發現一個「違反直觀」的現象:調整「讓迷宮多轉些彎」的參數後,若「多轉彎」的機率大於「走直線」的機率,迷宮怎麼反而看起來更少曲折?(例如,右邊的兩張迷宮圖,路徑都頗「迂迴」,但下方的迷宮就比上方的迷宮有較多的轉彎。)

咦,那我之前怎麼沒有發現?當初不就是因為覺得迷宮不夠蜿蜒,才加入「轉彎」的考量啊;而且,加入轉彎的參數後,迷宮不是也「真的」更蜿蜒曲折了嗎?(參考一個月前的 posts:稍微有些曲折的迷宮與更為曲折的迷宮。)

這下可有趣了。根據經驗,這要嘛是自己在實作時,把參數的意義弄反了;否則就是程式不知道哪兒寫錯了,誤打誤撞後,讓加入多轉彎參數的結果,比沒有加入參數的輸出要來得曲折。

花了許多時間追蹤,才發現真的有另一個地方出了些差錯;而「負負得正」,兩個錯誤合起來,就產生出「看似正確」的結果。

如果沒有這番整理,雖然程式仍然可以產生曲折的迷宮;但不管怎麼說,這程式其實都是實作錯誤的。有趣的是,對於「產生曲折迷宮」的目的而言,這個錯誤的程式,或許還是「無傷大雅」、甚至「合於規格」的:我們只要把參數往相反的方向調整就好了(例如,希望得到「多轉彎」的效果,本來應該把「多轉彎」的參數調高,但現在只要反向調低即可)!

程式改好後,我突然有種感覺:「誤打誤撞」似乎也是「實驗」的一種有趣特性呢。

星期五, 9月 16, 2005

即使不必上班,日子依舊忙碌

又過了兩個不必上班的星期。

這十幾天來,做了些什麼事情呢?星期一、三、五陪同太太帶寶寶出門,星期二、四在家裡陪寶寶。雖說陪寶寶玩樂、看著寶寶長大,也經常會得到強烈的幸福感,不過一旦想起「還有許多待做的事情未做」、「還有許多想看的書未看」,就會滿心愧疚。

還好,利用早上大家還在睡覺的時間,自己倒也是做了許多事情。除了寫幾篇 Blogs、嘗試著修改程式,讓迷宮更為曲折外,還有些「登不上台面」、但卻也重要的瑣事。例如,檢視前些日子從學弟妹們那裡取得的「古契書」文字檔。

雖然不甚確定,但我覺得「如何檢索這些古契書」,是項老師與學弟妹們這幾年來做「數位圖書館」研究的一個重要項目。自己的博士論文,研究的就是關於資訊檢索 (information retrieval) 的主題,所以或可提供一些自己的經驗或心得,讓學弟妹們少走些冤枉路。

聽過兩次學弟們的報告,我猜測大家對於使用 general-purposed approaches 應該已經有了相當程度的瞭解,但或許對比較特定的應用缺乏感覺。也就是說,大家看讀過、也實驗過「同時處理多篇文件」的方式(例如,利用統計方法來斷詞),但卻可能會有「見林不見樹」的遺憾(在此,每一篇文件是樹,而整個文件集合 (corpus) 就是林)。

因此,我想採取「見樹」(the small) 的方式,從比較特定的一些文件著手,看看是否能激發學弟妹們的一些想像(以公司裡使用的詞彙來說,就是「創意」)。當然啦,要「見樹」,自然得對「樹」有相當程度的瞭解;但不幸的是:我對古契書的背景與文字內容,瞭解非常貧乏(似乎也只有歷史學者才會比較瞭解 -- 但不該以此作為藉口)。因此,很可能自己花了不少氣力描繪出來的「樹」,與實際上的「樹」會有著相當大的落差。

我想,做研究就是這樣,總是得嘗試去做些「雖然辛苦、也不知是否會豐收」的事情;而這也是「做研究」與「產品開發」的一個主要不同處吧。

星期二, 9月 13, 2005

更為曲折的迷宮

在「稍微有些曲折的迷宮」貼出後,MPH 提出「曲折」的建議:盡量讓迷宮多轉些彎。

說的也是。既然手頭有程式,當然應該試著修改參數、做些實驗,看看會有怎樣不同的結果?

回想一下,我們的演算法,是採用 depth-first search (DFS) 的方式來展開迷宮樹狀結構的。原先的程式,在選擇「欲打破的牆」時,並沒有加入「盡量多轉彎」的考量。現在,我們讓迷宮路徑會轉彎的機率,比直線走的機率高。

例如,假設轉彎的機率是走直線的兩倍。再假設我們現在處於節點 (2,4),且發現其左側牆已被打通。則可知道,我們是站在節點 (2,4) 上,面向右(因為剛剛是由 (2,3) 走過來的)。於是,我們就讓 (2,4) 節點上方與下方(分別表示「左轉」與「右轉」)的牆,被打破的機率,是右側(表示「走直線」)牆的兩倍。

而這回產生的迷宮,看起來又更曲折了(參考右上方圖例,並與先前的迷宮做比較)。

這給了我們一個經驗:在定義「蜿蜒曲折」時,似乎不僅僅可「拉長兩端點間的距離」,也該考慮「轉彎的次數」!

喔,這下麻煩大了。原本「蜿蜒曲折」就是一個「未經明確定義」的詞彙;但現在它的意義,變得更複雜(拉長、多彎)後,會不會讓討論變得更模糊呢?

而且,也還有一些或許更困難、更有趣的後續討論哩。現在我們已經有了「感覺起來」頗為曲折的迷宮;但是「好」迷宮,光是蜿蜒曲折,應該還是不夠的。我們並不希望:迷宮蜿蜒曲折,但是「很好走」(例如,從入口到出口,幾乎都沒有岔路;或者,就算迷宮有很多岔路,但岔路都很短,一下就走到岔路盡頭)。

所以,接下來該怎麼延續「迷宮」的研究、討論、與實驗呢?

星期三, 9月 07, 2005

「稍微曲折的迷宮」之後

頗訝異於網路的高效率。

昨天貼出「稍微曲折的迷宮」後,不到半天就有人回應,說這裡有張曲折的迷宮圖,而這裡是它的路徑解答。

喔, 那可是張很大 (3002x3002) 的迷宮圖呢。很可惜,我沒有找到產生這張迷宮的演算法(與程式)。不過,有時直接看到答案,雖然會有「啊哈,原來如此」的痛快,但緊接著可能就會有些莫名 的失落。找不著答案,我們可以試著修改自己的演算法,想想如何才能產生蜿蜒曲折的迷宮。而探索,不也是一種樂趣嗎?

昨晚花了些時間,修改程式來做些實驗。終於,我們可以產生像右圖般的迷宮了。它看起來比昨天的迷宮,就蜿蜒曲折了許多(雖然我們也還是沒有定義出什麼叫做「蜿蜒曲折」)。

這個迷宮是如何被產生的呢?

回顧之前提過的一個想法:或許可藉由增加迷宮的直徑(diameter,就是最長的兩端點距離)來產生曲折的迷宮。但是,要用什麼方式來怎樣增加迷宮的直徑,才能夠依然保持演算法的簡潔呢?

一個「也算直觀」的想法,是在產生迷宮的樹狀圖(8 月 25 日 post 的集合 T)時,儘量增加 T 的高度(height,由根節點到任意節點的最長距離)。也就是說,每當我們從集合 C 裡,要選出「可被打破的牆」時,儘量選「能夠繼續增長迷宮樹狀圖高度」的牆來打破。

最簡單的一種方式,是當我們要將節點四周「可被打破的牆」放入集合 C 時(參考 8 月 25 日 post 的步驟 2),實際上只選一面牆放入集合 C (其他的幾面牆,則放入另一個串列 C2)。如此一來,我們可以讓 T 以類似深度優先 (depth-first) 搜尋的方式向外延伸,而能夠相對容易地增加 T 的高度。

那麼,如果 T 已經「碰到絕處」,無法用深度優先搜尋繼續往下增長時,該怎麼辦呢?此時,我們可以由 C2 取出最後面的牆來打破。如此持續進行,直到 C 與 C2 都是空集合為止。(喔,只是稍微修改 8 月 25 日 post 的「基本演算法」,產生出來的結果,竟然就會有如此大的差異...)

我想,或許迷宮真的是一個不錯的主題吧(連 MPH 從前也曾嘗試用「笨方法」產生曲折迷宮呢)。而回顧這些曾感興趣的問題,總讓我對從前懵懂的歲月,有著淡淡的感傷、歡喜與寂寞。

星期二, 9月 06, 2005

稍微有些曲折的迷宮

說過自己打算用「迷宮」來起頭,寫寫技術性文章。

也曾討論過,用 tree 來表示迷宮是一種頗為簡單、漂亮的作法。但是,從幾個產生的迷宮路徑圖來看(參考 8 月 15 日的 post),這種簡單方法所產生的迷宮「不夠蜿蜒曲折」。於是,就會想:如何才能產生比較蜿蜒曲折的迷宮呢?

一種想法是,產生迷宮時(參考 8 月 25 日的 post),讓「候選集合 C」裡,每道「可被打破的牆」被打破的機率都不一樣。不過,問題是:該用怎樣的機率分配(該如何指定每道牆被選到、被打破的機率),才能得到蜿蜒的迷宮路徑呢?到目前為止,我試了幾種簡單的機率產生方式,但對結果都不甚滿意(有沒有人可以提供建議啊?)。

換一個角度思考:我們可以觀察到,從左上到右下的路徑,必得經過中間每一直行。因此,或許可嘗試另一種方式:在迷宮中,隨意產生幾道「長長的、不可被打破的牆」,強迫從左上到右下的路徑必得「繞路」。例如,右上方的迷宮,第 10 行與第 26 行右側各有一道由上往下的長牆,第 14 行右側有一道由下往上的長牆。如此一來,產生的迷宮似乎就蜿蜒曲折了些。

我覺得,可以有「激發想法、並修改程式來實驗改進」的餘地,也是迷宮問題的有趣地方。

星期四, 8月 25, 2005

迷宮製作的演算法與圖例

且鼓起勇氣,試著談談「電腦平面迷宮」製作的技術細節。

需要勇氣,是因為談技術,通常容易流於枯燥與沈悶。然而,若我想要寫一篇關於「迷宮」主題的文章,卻非得督促自己去嘗試描述技術細節。因此,就讓我試著接續先前對迷宮的製作,做些更深入的描述與討論吧。

先前提過,可以用樹狀結構來產生迷宮。現在,我們可以將演算法(產生迷宮的方法)說得更仔細些。注意到,在這兒一個節點就是一個迷宮的格子;而相鄰的兩個節點間,如果沒有連結,我們說兩個格子間有一道「牆」。
  1. 一開始,任選一個節點。
  2. 將這個節點四周「可被打通的牆」(不含迷宮的外圍),放入一個「連結集合」C 裡。
  3. 將此節點,放入「已處理之節點」集合 T 裡。
  4. 如果 C 為空集合,表示迷宮已經產生完畢,我們停止程式。若 C 不為空集合,從中任意挑選一道牆(假設這道牆連結節點 n1 與 n2,而 n1 在集合 T 裡),並打通它。
  5. 如果 T 的節點與節點 n2 間,有連結在 C 裡,則將這些連結從 C 裡移除。
  6. 將 n2 標示為「已處理」(放入集合 T 裡),並回到步驟 (4)。

直接看以上的演算法,可能會有「霧煞煞」的感覺。配合著一個實例來對照,應該會比較清楚。

首先,假設我們要產生一個 3x3 的小迷宮。為了方便說明,我們將迷宮的格子標上號碼(英文字母 A~I),如右圖 (a) 所示。現在,且讓我們跟著演算法的步驟走一回:
  1. 任選一個節點。假設我們選到 B。
  2. 將節點 B 四周「可打通的牆」放入集合 C。參考下圖 (1) 中的黑色虛線。
  3. 將節點 B 放入「已處理」的節點集合 T(含有圓點的格子)。如下圖 (1) 所示。
  4. 執行演算法步驟 (4)。因為 C 不為空集合(圖 (1) 中有黑色虛線存在),所以我們從中任意挑選一道牆,例如 B-E(n2 為節點 E)間的牆,把它打通。
  5. 接下來,進行演算法的步驟 (5) 與 (6),可以得到下圖 (2).

  6. 接著,我們再次進行演算法的步驟 (4),假設這回從 C 選出 A-B 間的牆來打通。進行步驟 (5) 與 (6) 之後,我們得到下圖 (3)。
  7. 重覆執行步驟 (4),假設這回選出 D-E(n2 為節點 D)間的牆來打通。
  8. 執行步驟 (5)。注意到,節點 D 與 A 之間,原本有「可被打通的牆」,但因為 A 已經被放入「已處理」的節點集合 T 裡,我們在此必須把 D-A 之間的牆從集合 C 裡移除(用紅色虛線表示已由 C 移除的牆)。
  9. 執行步驟 (6),將節點 D 加入集合 T 之中。至此我們得到下圖 (4)。
  10. 仿前步驟 (4)、(5)、(6),破除 E-H 的牆,將 H 加入 T 後,得到下圖 (5)。


  11. 依循步驟 (4)、(5)、(6),破除 H-I 的牆,將 I 加入 T 後,得到上圖 (6)。
  12. 依循步驟 (4)、(5)、(6),破除 I-F 的牆,將 F 加入 T 後,得到上圖 (7)。
  13. 依循步驟 (4)、(5)、(6),破除 F-C 的牆,將 C 加入 T 後,得到上圖 (8)。
  14. 依循步驟 (4)、(5)、(6),破除 D-G 的牆,將 G 加入 T 後,得到上圖 (9)。
  15. 至此,C 已經變成空集合(圖 (9) 裡,已經沒有黑色的虛線,表示已經沒有「可被打破的牆」)了,因此程式停止。我們最後產生的 3x3 迷宮,就如上圖 (b) 所示。
有時,會很訝異於自己是如此地沒有效率:即使是這麼短短的一小段內容,也需要自己好幾天的時間來構思、繪圖、撰寫、修改呢。

星期一, 8月 15, 2005

再談迷宮


利用樹狀結構,可以產生迷宮。

另一方面,因為樹狀結構保證了任兩個節點之間必然有唯一的一條路徑,我們也可以用程式將這條路徑「畫」出來。例如,右圖就顯示了從迷宮最左上節點,到最右下節點的路徑。

然而,產生了幾個迷宮與路徑後,會發現這種演算法所產生的迷宮,路徑似乎不夠「蜿蜒曲折」。一般的紙上迷宮,通常從起點到終點,路徑都會彎彎折折,迂迴纏繞,不像這裡產生的迷宮路徑,感覺起來頗為平順。

但是,要怎樣才能產生「蜿蜒曲折」的迷宮路徑呢?

我不知道。

雖然我猜想,應該有「直觀、漂亮、簡單」的演算法可以產生蜿蜒的迷宮。例如,或許可以嘗試讓迷宮的樹狀結構長得深一些,這樣就可以拉長迷宮的「直徑」(迷宮 中,最長的兩個節點距離),而或許路徑就會顯得比較迂迴曲折。但是,在沒有合適的模型來定義「蜿蜒曲折」、或者在還沒有實際的實驗觀察前,我現在就是不知道答案。

我覺得,許多問題就是這樣:當你不知道答案的時候,你會認為要回答問題頗有困難;但當你知道答案以後,你卻又覺得它一點也不令人感到驚奇。

而就如知道答案後,會覺得實在也沒有什麼:有時,我們會很容易覺得別人的想法比較優秀;覺得外國的月亮,就是比較圓。我想,不論是「棄之如敝屣、外國月亮圓」或者「閉門造車、敝帚自珍」,應該都與人性脫離不了關係吧。只是,既然覺得過度輕視自己、過度自以為是都不健康,我們就應該努力讓自己掙脫這樣的思想與心態,不是嗎?

星期六, 8月 13, 2005

迷宮


從小時候,我就對許多益智遊戲感到興趣。

一種簡單的遊戲是「走迷宮」:玩的人要從一個迷宮的某一點,走到另一點。一個典型的平面方陣迷宮,就如同右圖所示。

那麼,如何用程式來產生這樣的迷宮呢?

乍看之下,似乎不是那麼容易。然而,如果有一些圖論 (graph theory) 的背景,會發現其實是有相當漂亮的方法,來產生這類迷宮的。

將迷宮的每一方格視為一個節點 (node)。相鄰兩格若有路相通,則說此兩節點間有個連結 (link)。如此一來,迷宮中每個小方格最多會有四個(上、下、左、右)相連結的節點。要產生一個迷宮,只要任選一個小方格,再由此方格向外伸展連結, 產生一個樹狀結構 (tree structure) 來涵蓋所有的格子,就可以了。

由於在抽象模型上,我們是用 tree 來表示 (represent) 此迷宮,因此這個迷宮也會有一些有趣的性質。例如,迷宮中的任兩個方格,之間必然、且僅有一條路徑相通。