星期六, 12月 31, 2005

年底的簡單回顧

今天是 2005 年的最後一天呢。想了想自己在這一年,到底做了些什麼?

嗯,和前幾年相比,我覺得成長了不少。說得確切些,應該是前幾年幾乎都沒有學到什麼。今年前半年,在舊公司進行了一項「品質改善」的專案,從軟體工程的角度思考與執行後,才慢慢讓自己對軟體專案的開發,有了不一樣的角度與看法。

九月離開公司,回頭再做博士後研究。除了「臨時性」與「薪資不高」之外,我覺得若是好好地「享受」一下,博士後研究也實在不壞:

  • 上下班相當自由。偶而心情好,可以不上班,陪寶寶玩一天。

  • 目前的工作內容,可主要是在延續自己讀博士班時,「尚未完成」的一篇 paper 與 prototype 實作。我覺得,或許也是因緣。

當然啦,自己因為一頭栽入論文寫作、程式實作中,就沒有力氣能夠整理些「曾感到興趣的一些主題」了。對此,我其實還是頗感愧疚的。

過幾個月,把 paper 與 prototype 弄得差不多了,就得準備下一份工作了吧。現代人,如果沒有工作,似乎相當容易顯得失落;親朋好友善意的問候與建議,也很容易令人難以招架。對 MPH 的短期計畫,決定再休息個半年,我是帶點羨慕與祝福的(其實不該羨慕的,自己這幾個月也可以說是在休息,應該知足)。

星期五, 12月 30, 2005

SQL Server 的全文檢索

從 MySQL 將資料轉到 SQL Server 後,接下來當然就是嘗試全文檢索的功能。

大致上,效能果然比 MySQL 好上許多(大約有十倍以上的效能提升吧)。這或許可以說明,MySQL 的全文檢索,可能只是「虛晃一招」,沒有好好認真去做。

即使是檢索「劉銘傳」,回傳 2407 篇文件也不會吃掉太多效能。但... 等等,印象中,在 MySQL 下用「海山口」來查詢,會取得 25 篇文件,但 SQL Server 怎麼只檢索出 23 篇?

雖然頗覺事有蹊蹺,但又有些懶:既然只是 prototype,這又頗明顯是 SQL Server 的問題,況且「大多數的查詢結果與 MySQL 的查詢結果是相同的」,不講大概也沒有人會發現。那麼,「假裝沒看到」又何妨?

不過,隔了一陣子還是忍耐不住,想了解究竟是怎麼回事。(哎,這該算是個性上的優點還是缺點多啊?)

最先浮上心頭的想法,是懷疑「海山口」的前後文,是否在 big-5 或者 unicode 中,含有特殊的字元;而這樣的字元,導致 SQL Server 在做全文索引時弄錯了。調出一篇沒有被檢索出來的文件,相關內容是這樣的:

...比臺北海山口最上之米。一石僅低十錢...

嗯,看起來好像沒有什麼問題?

這下子有點傷腦筋了。懷疑是否 SQL Server 的全文檢索有參數可以設定。然而,搜尋網路與相關文件後,卻只找到 stop words 的檔案;但即使將 stop words 通通拿掉,也還是檢索不出這篇文件。

不信邪,用「海山」找找看。喔,可以找到數百筆資料,但怎麼就是不含這一篇?改用「山口」試試看好了 --- 咦,這回可以檢索到耶。這究竟是怎麼回事啊?

嘗試了一些查詢後,我覺得 SQL Server 好像把「北海」「山口」斷詞斷開(當成是兩個片語)了。想到前同事 Tim 曾提到,Microsoft Word 有類似的斷詞判斷能力,就把上面框起來的那些字拷貝到 Word 裡...

結果還真的頗有趣。當我在「北」或者「海」上頭 double click 時,Word 會 highlight 選出「北海」,在「山」或「口」上雙按,則會選出「山口」。看來,Microsoft 在 Windows 的某個地方,確實有個「斷詞」的程式模組,而 SQL Server 的全文檢索,則「笨笨地」誤用斷詞了。

找不到如何取消這類「自作聰明」舉動的地方,只好用類似於在 MySQL 上檢索中文的方式,在每個中文字間,加上空白,然後用「片語檢索」的方式,查詢 "海 山 口" (在字與字之間加上空白)--- 這下終於成功地檢索出 25 篇文件了。

實作中文系統就是這樣,常常會遇到一堆莫名其妙的問題。為了交差,有時就難免得用到 work around 的解決方式;而既然是折衝繞路後的解決方案,深層根本的問題也就比較多。我想,這應該也部分說明了,為什麼中文的系統,(比單純的英語系統)感覺起來經常是「問題一籮筐」吧。

星期二, 12月 27, 2005

轉移焦點

「爸爸你討厭,把帕還給我,嗚嗚嗚..」

昨天幫寶寶「保管」她的手帕,卻忘了還給她。電話裡,小傢伙哭得很可憐。我在電話裡說好說歹,就是無法讓她停止啜泣與不滿。據說,太太後來是藉著「轉移焦點」的方式,讓她注意到衣服上的小動物,寶寶才破涕為笑的。

今早繼續閱讀「選擇的弔詭」。書中提到,「對不快樂的人來說,他們重視的是相互比較...快樂的人與不快樂的人,之所以會做出不同的反應,關鍵在於能否抽離思緒、還是反覆思考」。當不快樂時,如果能夠分心,轉向思考其他事物,那麼就不會沈浸在反覆的思考或懊悔中。

我想起從前失戀時的一些經歷。失戀時,難過的感覺往往會佔住生活中的大半空閒時間;而旁人的安慰,通常都沒有太大的助益。脫離失戀悲傷情緒的最好方法,就是趕快找到下一個戀愛的對象。

而小傢伙似乎天生就有「顧左右而言他」的轉移焦點能力。當我們數落她做錯了什麼事時,她經常會主動轉移話題與焦點,令人又好氣又好笑。我想,如果這種能力,能夠讓她生活得比較滿足與快樂,那也是一種很好的本領罷。

星期一, 12月 26, 2005

MySQL 到 SQL Server 的轉換

上週提到,使用 MySQL 全文檢索遇到的效能困境。

想起從前曾用過 Microsoft SQL Server 的全文檢索功能,而當初的感覺還不錯,所以就打算將雛型的資料庫改用 SQL Server 2000,來比對是否真的是 MySQL 的問題。

不過,字元編碼的問題又再度出現:MySQL 支援 UTF-8,但不支援 UTF-16 的字元編碼。M$ SQL Server 則正好相反,支援 UTF-16,卻不支援 UTF-8。當下嘆了口氣:看來,轉碼的功夫是省不了的...

找了幾個資料庫轉換的工具軟體,都無法在資料庫之間正確轉碼,所以就只好自己動手寫程式。不過,SQL Server 的 drivers 似乎很奇怪,大五碼(big-5)的字元可以正確地轉譯到 nvarchar 或者 ntext,但其他字元怎麼都會變成問號呢?

明明覺得「一定有辦法解決」,但怎麼總是有某個地方不對勁?又是一番冗長的手冊閱讀、網路搜尋、以及嘗試錯誤過程。頗幸運地,最後終於找到正確的轉碼方式了。

轉譯的過程,用到了 PHP COM 模組的 CP_UTF8 codepage,以及 SQL Server 指令的 "N" prefix。我想,這應該就是所謂的「know how」吧:明明知道必然有解,而最終也證明這個解相當簡單,但如果缺乏這個 know how,就怎麼也做不出來。

星期六, 12月 24, 2005

堅持

電視上訪問朱銘,問他如何能致現今的成功,朱銘的回答是:「堅持」。

從電視上,可以感受到朱銘是一個非常謙和,對自己的理念也非常堅持的人。他說,他堅持著自己的本性、規律生活、在生活中修行(他說,就是把雜念去除)。

堅持。短短兩個字,卻有力地道盡人世的滄桑。如果世界不是那麼現實,那又何需堅持?

想想舊公司竟然還有能力增資,也頗感驚訝。技術研發本來成本就高,舊公司開發的東西也理應有應用價值;只是,歷經一番大變化,看這些東西的角度竟也有了微妙的改變。公司能夠繼續生存,不管是因為賺錢、或者因為能夠找到金主,都是它的本領。只是,就像是政治人物常掛在嘴邊的「不逃避、不退縮」,這樣是否真算是「堅持」?

看來,堅持雖然令人嚮往,但箇中微妙之處,卻語言難以描述。而成王敗寇,就是現實的遊戲規則。或許,「馬後放砲,砲砲都響」,我們也真只能在事後,才能品茶論英雄。

星期三, 12月 21, 2005

逃避選擇

卸下「正式工作」後,總想能夠多看點書。

不過,自己看書的速度本來就屬烏龜等級,最近又為了古契書檢索的雛型傷腦筋;因此總難抽出足夠的時間,好好地讀上幾本書。

看看架上的圖書,都已經滿溢了,怎麼好意思再買書呢?在愧疚的心情下,挑選了一本「選擇的弔詭」,趁著早餐的時間,酌量閱讀。

這其實是一本嚴謹的科普著作。看看書後的參考書目,竟然有 138 條之多。想想自己近來想寫些東西,卻腸思枯竭無法動筆,就更欽佩作者的功力了。

在書中,作者提到「逃避選擇」:在許多狀況下,人們並不願意做選擇。如果在抉擇時被迫要面臨取捨,人不只會變得不快樂,還會顯得優柔寡斷 --- 如果實驗容許,人們甚至根本不想做決定。大家大概都曾聽過這樣的問題:

假想你的媽媽、太太、還有小孩掉入水裡,但你只能從中救一個人。你會選擇救誰?


就我來說, 自己從來都不肯正面去回答這個問題,因而通常就是採取「拖延、玩笑似地回答、或逃避選擇」的態度。此外,就工作的選擇方面,自己似乎也總顯得有些意興闌珊。這應該也是一種逃避吧?

有意思的是,從書上引述的研究來看,這種心理反應是「正常」的:大多數人都是如此,因此似乎也不必太在意。雖然,許多提倡積極進取的書籍,總是會鼓勵「仔細評估、勇於決定、貫徹選擇」。

想起當兵時聽過的話:「時間的過去,就是任務的完成」(這句話,其實是我在 Maryland 求學時,因室友 Pony 多次提及,才比較深刻地映入腦海)。也或許,「不選擇」就是最好的選擇?

星期日, 12月 18, 2005

MySQL 的全文搜尋效率

上個月才聲稱 MySQL 也支援全文檢索,但現在心裡卻頗有不滿。

怎麼回事?原來,MySQL 的全文搜尋效率並不好。當初的文件庫只有一萬多篇文件,效能還差強人意;但現在文件庫裡有了十幾萬篇文件,搜尋的時間竟然也是「直線上升」。那麼,做全文索引,還有什麼意義呢?

調了調幾項參數,都沒能改善效能。只好到網路上看看別人是否也有類似的經驗。喔,是了,確實有人做了些實驗,然後發現 MySQL 的全文效率,並不會比直接用 SQL 指令,下「WHERE content LIKE "% tag %"」來得好(其中,content 是資料庫儲存內容的欄位名稱,tag 是要搜尋的字串,% 表示任意字元都符合,而 tag 前後留有空白,是因為英文字是用空白來斷字的)。

這下子也真令人氣餒。雖說自己只是在做實驗性質的 prototype 或 demo,但尋找個「劉銘傳」、「海山口」竟也要花上半分鐘以上的時間,總讓人心裡不舒服。

於是,也強烈感覺到,強調互動的系統,「回應時間」是需要被關注的。 0.1 秒內取得檢索結果當然很好,但花個三秒鐘,也不會讓使用者覺得太難過。然而,如果需要超過五秒才有回應、甚至需要長達半分鐘的等待,那麼系統在「互動」上就顯得很不實際了。

星期三, 12月 14, 2005

談古契書資料處理:之四

古契書檢索系統,一般需要處理時間的問題。

什麼意思呢?一個提供全文檢索 (full-text retrieval) 的系統,難道還不夠嗎?

從某些層面來看,只有全文檢索的確不夠。例如,若我們只想查閱某些年代的資料,全文檢索因為無法辨識文件的年代,就無法提供「只搜尋清朝乾隆年間文件」的選項,因而回傳的結果,將會因為含有大量「非乾隆年間文件」而使檢索效率降低。

好吧,那我們怎麼提供全文以外的檢索呢?

一般來說,需要有詮釋資料 (metadata) 的配合。詮釋資料,就是用來說明資料特性的一些東西。例如,Windows 檔案系統有所謂的「延伸檔名」,它就算是一種詮釋資料。由於 .jpg、.gif、.wav、.doc、.xls 各表示不同的檔案格式,應用程式就能藉由這項資訊分辨處理的方式。

可是,古契書本身是沒有詮釋資料的。要將它數位化,就已經會遇到一堆問題了,哪有資源來為每份契書額外加上詮釋資料呢?於是,就會有「從文件中,自動擷取時間資訊」的想法。

讓我們先看一份完整、加過標注的古契書:

od-ta_01516_000005
竹北二堡十寮庄土名七寮三五之二、三五之三

立截出山園字人周明盛兄弟等。緣因先年承買李家之山園,係叔侄兄弟人等備本,按作參股,每股備出本銀壹拾參元陸角正,盛備出本銀陸元捌角正。爰是族戚酌議,福叔姆邱氏備出本銀陸元捌角正,計共每壹股本銀壹拾參元陸角正,將此山園截出四至界址。東至貳鬮毗連種竹為界;南至路生屋角水壢透上;西至大龍種竹為界;北至糞箕窩分水為界。四至界址,即日經族面踏分明。愿將此山園壹處與叔姆邱氏前去掌管,收租納課,永為己業,日後子孫人等不敢異言生端等情。此乃二比甘愿,兩無迫勒。口恐無憑,今欲有憑,立截出山園字壹紙,付為執照。
即日批明:福叔姆邱氏備出本銀陸大元捌角正。立批照。

場見叔 元寶(印)
代筆人 廖青雲(花押)

明治丙申年捌月 日立截出山園字人 周明盛(花押)

其中,「明治丙申年捌月 日」就是很明顯的時間資訊。

當我們要從文件中擷取出這類資訊,會發覺正規表示式 (regular expression) 實在是一個方便的工具。例如,寫一個簡單的式子:

(明治|同治|光緒)\S{1,5}年\S{1,2}月.{1,3}日

就可以擷取出「明治丙申年捌月 日」、「同治拾貳年桂月 日」、「光緒丙子年拾貳月 日」等字串。其中,「\S」 代表任意的「非空白 (white-space) 字元」,「.」可以比對任意的字元,而「{m,n}」則表示符合的字元數目要在 m 與 n 之間。

當然啦,現實總不是那麼簡單與美好。和之前幾篇 posts 類似,總有些打錯的字、莫名其妙的斷行、以及更冗長的時間寫法(例如,「光緒八年歲次壬午拾壹月 日」之類)。此外,古時候中國是採用農曆,有時會有「潤八月」之類的字串出現。因此,要找出合用的正規表示式,就會複雜許多。

星期日, 12月 11, 2005

不願長大

「我沒有長大,我長小了。」

前一陣子告訴寶寶,她已經三歲多、長大了,要學會自己穿衣服、自己刷牙、自己吃飯、自己睡覺。小傢伙竟然說她「長小了」,令人不禁莞爾。

當然,三歲的小孩,經常連自己想表達什麼,都說不甚清楚。但這一陣子,我常覺得,自己是不是也「不願長大」呢?

有人說,中年的主要課題是,摒棄自己想像的一切安全庇蔭,練習對自己負起一切責任。只是,我真的準備好了嗎?

看(聯合報附贈的)紐約時報差不多也有半年的時間了,近來越發覺得自己的英文程度實在不好。有時真的很希望時光倒流:若是自己能夠從十幾年前,就開始閱讀,現在的程度是不是能夠好上許多?

也想起自己兩個月前,是想用一年左右的時間,好好地整理、寫出一些曾感興趣的東西。然而,最近卻幾乎都把時間花在「工作」上了。雖然頗為確定:現在的工作,都是在自己意願下去做的;但是,總是希望時光走得慢些,好讓自己有多些時間來喘息。

想起貓在 Blog 引村上春樹的話語:「四十歲是人生一個很大的轉捩點。那時,我將選擇一些什麼,並捨棄一些什麼。」我想,這應該是個困難、卻又無法逃避的選擇吧。

年近四十,對時光的飛逝,有時真會有股莫名的煩亂。雖感覺不出書上常說的恐懼(不願接受、想找方式來逃避),但卻常帶點無奈、有些悲傷(為逝去的青春感嘆)、更常感困惑:這些日子裡,自己究竟做了些什麼;而接下來的日子,我又想做些什麼、該做些什麼?

想擁有多些時間,來更了解自己。但歲月催人老,不願,卻也無法拒絕長大。

星期五, 12月 09, 2005

令人感動的童言童語

「爸爸你討厭,我要把你丟掉!」

雖然是負面的語言,從寶寶的口中講出來,卻格外感覺溫馨。小傢伙早晨起床,發現爸爸不在身邊,哭著訴說她的不滿。她要媽媽打電話,然後竭盡所能,對我說她僅知的負面詞彙:「爸爸上班,我不喜歡爸爸,爸爸討厭、小氣鬼!」

老實說,聽她這樣哭訴,心裡充滿著感動與不捨。我想,我會珍惜和三歲寶寶相處的歲月。這些日子的點點滴滴,終將伴隨著我,走過看似蒼茫的歲月。

星期三, 12月 07, 2005

Seeing through the distance

上週聯合報附贈的紐約時報,有一篇「捷克梅第的女人,訴說她們的故事」。

原文的標題是「Women Who Posed for Giacometti Tell the Tale」,大意是幾位曾讓藝術家 Giacometti 繪描、塑像的女性,回顧她們當模特兒擺姿勢的情景。原文還有附譯稿,可以讓英文程度不怎樣的我,更有機會一窺紐時報導的文采。

我很喜歡中間的許多描述。尤其是,它讓我對這位藝術家的「追求完美、挑戰不可能任務」產生極大的嚮往與敬意。

文中說,Giacometti 對自己雕塑出來的頭像,總是不滿意。而一位模特兒回顧說,她在擺姿勢時,有時會覺得自己好像是靜物,而旁邊的雕像才是活的。她說,Giacometti 的頭像,總是超越物體朝遠方看,總是「看著遠方」(seeing through the distance)。

好一句「seeing through the distance」。雖說被翻譯為「看著遠方」,但我總覺得有「看穿距離」、「洞察時空」的意涵。用它來形容藝術家的執著與追求,真有股力透紙背、畫龍點睛的效果。

星期日, 12月 04, 2005

淡水河岸的民俗藝品

也不知小傢伙是從哪得來的訊息,昨天寶寶吵著要到淡水坐船。

看看氣象預報,接下來一整個星期氣溫都會偏低,昨天算是不錯的天氣。想了想,淡水不好停車,還是開到左岸八里,坐渡船到淡水,走走逛逛好了。

在淡水捷運站旁,看到民俗藝人用吸管做飾品與玩具,維妙維肖。據說,除了毛毛蟲是用衛生紙做的之外,所有的東西都是用吸管做成的。寶寶年紀小,只能玩「蝸牛」,除了比較安全,還可以吹出笛音。

小傢伙當然很高興,拿著它一路吹著玩。看著她純真可愛的模樣,心裡有股形容不出的感動。

星期六, 12月 03, 2005

Obviously ..., so ...

那些東西是「不證自明」、「明顯不過」的呢?

前一陣子某篇post的回應裡,MPH 舉出「刻卜勒的猜想」這本書裡,提到知名數學家也會犯類似的 "Oh, it's obvious!" 錯誤(或可說是「傲慢」吧),看了真的頗有感觸。

也就像 Ankh 對同一篇 post 的回應,什麼樣的東西才算 "obvious"、才算 "trivial"、才算 "clear" 呢?

Papadimitriou 有一本很有名的課本「Computational Complexity」,已經接連著約十年,被台大資工所拿來作為理論課程的教本了。這本書內容廣泛、證明也多半相當漂亮。但是,有多少人會注意到,它有一個證明「應該」是錯誤的呢?

經過了這許多年,似乎沒有太多人注意到這個問題,而更正版也沒有修正。或許,因為這本書的主旨是在「Complexity」,不是在「Logic」,所以很少人在意吧。

說是「應該有錯誤」,是因為我認為它證明有誤。但是,人家可是大師級的理論學者啊,或許是我自己弄錯了呢!(問題出在哪裡呢?出在它前四行半的鋪陳,拉拉雜雜說明了許多沒錯的事實或推論;但這些並不能得到「So, ...」之後的結果。由此觀點來看,這和「芝諾的烏龜」,是不是也有異曲同工的味道?)

我想起時下的一些政治評論與財經報導。許多「看似有理」、「假借客觀方式論證」的文章,通常都會先東扯西扯地說許多沒什麼相關、但也沒怎麼錯的觀察(但通常有意無意地忽略了相反的意見),然後就突然跳到結論。

不甚明白:他們究竟是想說些什麼、是不是真的知道自己想說些什麼。還是,他們其實另有所指、別有所圖?

星期二, 11月 29, 2005

芝諾的烏龜

芝諾 (Zeno) 曾提出一個有名的「烏龜悖論」。

希臘戰士阿基里斯跟烏龜賽跑。烏龜說,如果牠比阿基里斯先跑10公尺,那麼阿基里斯永遠都追不上牠。因為只要阿基里斯跑了10公尺,這時烏龜就又多跑了幾公尺;若阿基里斯再跑到烏龜曾經停留的點,烏龜一定又跑到阿基里斯前面去了... 如此這般,阿基里斯永遠追不上烏龜。

這悖論 (paradox) 之所以引人入勝,一個主要原因是:它看似有理,但我們卻很清楚地知曉以上的論證必有錯。用腳趾頭想也知道,善跑者怎麼可能追不上烏龜?

問題是,我們該如何說明論證的錯誤點。先撇開這個悖論中的「時空」觀念(據說,這部分仍然引發學者的爭辯),許多人同意羅素的看法:「從 Cantor 之後,在邏輯上才解決了這個悖論」。

嗯,Cantor 的確是說明了,無窮級數的和,並不一定是無窮大(可能收斂在某個數)。但... 等等,這和悖論的論證,又有什麼關係呢?

原來,論證的錯誤在於:前面的無窮個推論(每當阿基里斯跑到烏龜曾停留的點,烏龜就又往前跑了一小段路),並不能推導出「如此這般,阿基里斯永遠追不上烏龜」的結論。

換句話說,雖然每一步的推論的確都沒有錯,也「看得出來」每一步的推論,都讓阿基里斯與烏龜又多跑了一小段路,但即使有無窮多個「向前推進」的正確推論,我們仍然無法得出「追不上烏龜」的結論。

於是,邏輯上,要證明某項結論,必須經由有限個推理步驟。利用無限個逼近步驟所推得的結論,在邏輯上是無效的。

星期六, 11月 26, 2005

朝三暮四

朝三暮四,是一則歷久彌新、發人深省的寓言。

狙公賦芧,曰:『朝三而暮四。』眾狙皆怒。曰:『然則朝四而暮三。』眾狙皆悅。
---《莊子‧齊物論》

我想,莊子真是個細心的人。他竟然觀察到,春秋時期,猴子就已經很聰明了。牠們知道:先拿到的先贏。早上先拿到栗子,即使不拿去投資,把栗子儲存起來,得到的樂趣也(比晚上再拿到)更多!

究竟是猴子愚魯,不知道「3 + 4 = 4 + 3」;狙公狡猾(或聰明),懂得搬弄「朝三暮四、朝四暮三」來取悅猴子;還是猴子竟比想像中的還要聰明,知道先取先贏(很像社會現況呢)的道理?

感覺寓言的巧妙,有時竟可從不同角度、不同層次,得到不同的解讀。莊子真的很有智慧。

星期四, 11月 24, 2005

談古契書資料處理:之三

要做好資訊處理,必須對「欲處理的資訊內容」有些最起碼的認識。

很不幸(或很幸運 --- 因為問題難纏,所以很少人願意花力氣去做)地,一般的古籍,是沒有標點符號的。一篇沒有標注逗點、句點符號的文章,看起來可是有夠令人氣餒的。

不信?請看這一小段摘錄下來的「古地契」:

立杜賣斷根山埔田薗字人黃鼎愛斯先年承買有山埔地壹所坐落土名南港鹿廚溪尾四至界址載在總契詳明金因乏銀別立母特此地東片拆開壹角東至陳家小溪田崁直上龍崗倒水為界西至波塘下帶田壹大坵左君子田唇毗連直透橫崗倒水為界南至左君子会埔直透大凸為界北至伯公艮直透洽溪為界四至界址同中面踏分明...

要處理古契書,多多少少就得花些時間看看這些契書的內容、並看看它們有沒有一些可資利用的樣式(patterns)。不過,一般資訊人(嗯,或許是阿尼說的「資遜人」?)看到像這樣未經標注的古文,沒有昏倒、也很難著性子看完幾篇吧。

適當的標注,也會影響到文章的解讀。就像是著名的「下雨天留客天天留我不留」,加上不同的標注後,可以產生迥然不同的解釋:「下雨天、留客天,天留、我不留」、「下雨天留客,天天留我不?留」。

碰到這類棘手的問題,一種方式是花錢請「專家」來標注。好吧,就算我們請一些「歷史系的專家或學生們」來對一些古文加上標注,也假設他們的標注是可接受的;接下來也還是會遇到中文處理的許多困難,其中之一就是「斷詞」。

一般來說,中英文都沒有斷字的問題。英文嘛,一個「字」(word) 是由 a, b, c 等英文字母組成,字與字之間可由空白、逗點等來區隔。例如,"This is a book." 這個句子,其中 "this"、 "is"、"a"、"book" 都是個別的「字」。而中文由於是方塊字,每一個字有獨立的字碼,也沒有斷字的問題。

但是,在中文裡,個別看每一個字,通常對內文的了解沒有什麼幫助;數個字連接起來成為一個「詞」之後,這個詞才會具備特定的意義。例如,「新」、「竹」如果分開來看,與「新竹」的意義,經常是完全不同的。

所以,中文有斷詞的問題。在前頭舉的古地契例子裡,「山埔」、「田薗」、「南港」、「鹿廚溪」都可以算作獨立的「詞」;但看起來像是個人名的「黃鼎愛斯」呢?是該斷作「黃鼎愛」、還是「黃鼎愛斯」?

可以想見,適當的標注,有助於斷詞的正確性。至少,我們知道一個詞不應橫跨由標點符號隔開的兩個子句。但是,即使有加上標點,想要適當地斷詞 --- 甚至斷出「地理名詞」、「人名」等特殊意義的詞彙 --- 都還是一項艱難的挑戰。

星期一, 11月 21, 2005

戴帽子問題

有沒有聽說過「戴帽子問題」?

問題的描述是這樣的:有三頂黑帽與兩頂白帽,自其中挑選三頂,讓 A、B、C 分別戴上一頂後,讓 A 排在 B 之前,B 排在 C 之前,形成一直線。每個人可以看到排在自己前面的人所戴的帽子顏色,但是卻看不到自己或排在自己後面的人所戴的帽子。現在,問 C 是否知道自己的帽子顏色,C 回答「不知」;接著問 B 是否知道自己戴的帽子顏色,B 也回答「不知」。最後,問 A 是否知道自己戴何色的帽子,A 卻回答「知道」。那麼,A 戴的帽子顏色是什麼呢?他又如何推斷出自己的帽色?

就像一般的邏輯問題,我們可以從證明論(Proof Theory;例如從「若 P 則 Q」以及「P」,可推斷出「Q」)或模型論(Model Theory;例如,窮舉所有可能性,然後說明,在所有的狀況下都成立)來著手解決。

一般的解答,都是利用證明論來解釋:
A 自問:我的帽子是白色的嗎?如果是,B 可以推論他自己的帽子是黑色的;因為若 B 的帽子也是白色的,C 就會看見兩頂白帽,從而推斷出自己戴黑色的帽子。然而,B 並沒有推斷出他自己戴什麼顏色的帽子,因此一開始的假設「A 帶白帽」不成立,因此可推斷出「A 帶黑帽」。

這個解答,因為用到數次「反證法」(Proof By Contradiction;用「非 P」為偽來證明「P」為真),因此很容易讓人有「喔,好聰明的解答啊」之感。不過,若換個角度,從模型論的觀點來看,或許可以得到更深刻的直觀:

參考上圖,帶黑帽標示為小寫 b,戴白帽則標示為小寫 w。

首先,我們知道,每個人頭上都帶有一頂帽子,因此 A, B, C 戴的帽子可能性,共有 8 種(參考圖 (1),每一列是一種可能性)。

但問題又敘述說,黑帽有三頂(或三頂以上),而白帽只有兩頂,因此不可能三人都戴著白帽(參考圖 (2),我們把三人都戴白帽的狀況用紅線刪除掉)。

接下來,問題又說:「問 C,回答不知自己所戴帽色」。因為 C 可以看見 A, B 所戴的帽子顏色,所以從圖 (2) 可知,A 與 B 不能夠同時戴有白帽(換句話說,A, B 若同時戴有白帽,則從圖 (2) 的第七列,C 可知自己戴著白帽)。所以,我們可以把 A, B 同時戴有白帽的狀況刪除(如圖 (3))。

然後,問題說,「接著,詢問 B,也不知自己戴那種顏色的帽子」。因為圖 (3) 說明了,若 A 戴白帽,則 B 必然戴著黑色帽子(圖 (3) 的前四列說明了,若 A 戴黑帽,B 可能戴黑帽、也可能戴白帽;而接下來的兩列則說明,若 A 戴著白帽,則 B 必然戴著黑帽)。不過,由於 B 回答他不知道自己的帽色,因此,我們可以把 A 戴白帽,B 戴黑帽的狀況刪除(參考圖 (4))。

最後,問 A 知不知道自己戴哪種顏色的帽子。因為在圖 (4) 的所有可能狀況中,A 都必然戴有黑帽,所以 A 可以很有自信地回答:「我戴黑色的帽子」。

星期六, 11月 19, 2005

MySQL 也支援全文檢索

要提供一套查詢、檢索文件的系統,「全文檢索」(full-text retrieval;使用者輸入 query 字串,系統會把這個字串與文件的全文字串做比對,來找出符合 query 的文件們) 已經是不可或缺的要角了。

沒有人會質疑 Google 搜尋引擎的威力吧。事實上,Google 搜尋引擎做得最好的,就是能針對使用者下的 full-text query,在極短時間內,從非常大量的網路文件庫中,找出(並排序)「最有可能滿足使用者 query」的文件(URL、摘要、以及庫存檔)。

而實驗室既然想做一套「古契書的檢索系統」,當然也得提供全文檢索的功能。不過,現實面上,很容易就會處於抉擇的難點。難以抉擇的地方在哪兒呢?原來,我們的系統,並不只是想提供全文檢索,還希望利用其他的 metadata(好像是翻譯為「詮釋資料」吧)來增進檢索的效能。

於是,系統可能就得整合一套關連式資料庫 (RDDB)、與一套全文檢索系統(例如,Apache 的 Lucene project)。「整合」總是件吃力卻不怎麼討好的工作。

雖然 Microsoft SQL Server 很早就有同時提供 RDDB 與 full-text retrieval 的功能,但是實驗室老闆是很討厭 M$ 的;Oracle 有很好的 RDDB,但全文索引不是內建;因此,腦筋通常都會動到開放原始碼的 MySQL 上。

很高興地看見,MySQL 文件上,說它是支援全文檢索的。不過,實際跑了跑,就會有些沮喪:對中文資料而言,似乎行不通。手冊、甚至是網路文件上,對於如何處理中文的全文檢索,雖有片段的說明,卻缺乏完整的實例。

好吧,這又是一個需要做實驗(測試、並嘗試找到解答)的地方。「實驗室」嘛,就是得做做實驗,不是嗎?

透過以下這些步驟,應該可以讓 MySQL 處理中文的全文檢索:
  1. 資料庫採用 UTF-8 編碼格式,以支援中文。此外,欲提供全文檢索,資料表必須採用 MyISAM 的型態。例如,CREATE TABLE table_name (...) ENGINE=MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
  2. 在資料表內建立欄位的全文索引。由於 MySQL 並不支援中文的斷字,因此我們目前還得新增一個欄位來儲存輔助全文檢索。例如,假設我們想對 DOC 欄位做全文索引,那麼除了 DOC 之外,我們還得新增一個(名稱自取的)DOC_FOR_FULLTEXT 欄位。然後,在 CREATE TABLE 時,加入 FULLTEXT (DOC_FOR_FULLTEXT) 來對這個輔助欄位的資料,建立全文索引。
  3. 將全文資料填入 DOC 欄位時,也將「自行斷字處理後的文件字串」填到 DOC_FOR_FULLTEXT 欄位裡。例如,假設要填入 DOC 欄位的全文是"新竹縣東興庄",那我們也同時將斷字後的 "新 竹 縣 東 興 庄 "(註:若字串內容為 UTF-16 Little Endian 編碼,利用 PHP 的 chunk_split() 可以在字串內,每隔兩個 bytes 插入一個空白字元 "\x20\0")填入 DOC_FOR_FULLTEXT 欄位。
讓 MySQL 提供全文索引後,接下來是處理使用者輸入字串的部分:
  1. 執行 full-text SQL query 前,先執行 SET NAMES 'utf8'
  2. full-text SQL query 長得像這副模樣: SELECT * FROM WHERE MATCH (DOC_FOR_FULLTEXT) AGAINST ($fulltext_query IN BOOLEAN MODE)。其中,$fulltext_query 是一個對 user query 做過處理的字串。例如,若使用者輸入「新竹」,則 $fulltext_query 需要被處理為「'"新 竹"'」(注意:「新」與「竹」之間要有空白斷開,「新 竹」要用單引號框住雙引號;還有,不要忘記,SQL query 必須以 UTF-8 編碼的)。

星期三, 11月 16, 2005

Oh, it's obvious

在 Maryland 求學時,曾發生一件事情,讓我至今印象深刻。

當時,我是計算理論 (Theory of Computation) 的助教(但因為英文程度不夠好,並不是擔任需要上台授課的 TA;而只是改改作業與考卷、回答學生問題的 Grader)。有一天,一位頗有年紀的女學生,到助教室來問我一個問題(有些可惜,我已經忘記當時的題目是什麼了)。

那時討論到某段證明的一個癥結點。她問說:"Why?" 我回答 "Oh, it's obvious." 結果她滿臉苦惱,說了一段令我至今難忘的話:"It's obvious... I hate obvious!"(答案很顯然... 我厭恨這種「顯然」!)

至今我仍難忘她當時那副沮喪苦惱的表情。為什麼我忘不了這一幕?因為,事後我稍微仔細地想了想,發覺自己其實也不是那麼了解;換句話說,當時我的回答,算是自欺欺人的作為!

但為什麼當時沒有立即承認、只隱隱地告訴自己「嗯,有些不對勁...」呢?或許,一個很可能的原因是,雖然自己當時只是似懂非懂、一知半解;但有學生來問問題,實在無法大大方方、毫無羞愧地說:「我不懂、我不知道」。

也或許,這是難以避免的成長歷程。

在許多課本或者課堂上,都經常看見或聽到 "It's obvious" 或甚至 "It's trivial!" 的回答。雖然我們不太好懷疑,作者或者講課的老師,對問題的答案,是否真的感到「明顯、微不足道」,但我仍強烈地贊同「知之為知之,不知為不知」、甚至「打破沙鍋問到底」的求知態度。

下次,回答 "Oh, it's obvious" 前,讓我們先謹慎地問問自己,是不是「真的那麼顯而易見」罷。

星期日, 11月 13, 2005

談古契書資料處理:之二

上回談到古契書資料處理的一些棘手處。

在數位化的過程中,必須有人介入(掃瞄、打字等等)來產生「第一手的數位化資料」。這裡的重點是:有人介入,就會有錯誤產生。有時是看錯原籍,有時是打錯字詞,有時則是心不在焉、錯誤連連。此時,如果沒有安排「校對」的人力(據說,實驗室的古籍資料,是有安排校稿的人力;但從結果看來,似乎在品質上沒有改進太多),寫程式來做後續處理的人,就注定陷入一番苦戰了。

此外,如果沒有事先加以規範(但老實說,要「事先」就知道困難所在、並加以防範處理,是相當不容易的),即使看到同樣的字,不同的輸入人員可能會將其數位化成「形狀類似、但實際上不同」的字碼。例如,古契書裡並沒有使用阿拉伯數字,因此 40 會寫成「四〇」。從實際數位化的資料來看,至少有「四〇」、「四O」、「四0」、「四○」(這些「零」--- 〇O0○---看起來很相似吧?)等幾種不同的結果。

如果數位化資料只是供人閱讀,那倒還好;但若想對這些資料做進一步的處理,寫成不同的字碼,會導致寫程式做進一步處理時的困擾(例如,要搜尋文件中出現「四〇」字串),甚至會導致資料轉換的錯誤。

最後,還想再為「編碼」所導致的煩惱多說幾句。事實上,光是編碼、轉碼的問題,就夠資料處理的人員忙翻了。多種編碼共存也就算了,開發工具與國際組織們,往往也各支援不同的標準。例如,目前的 PHP 版本,就只支援 ISO-8859-1 編碼格式的程式;Windows 與 Java 內部則是採用 Unicode (不過,前者是 Little Endian 編碼;後者是 Big Endian 編碼);而現在流行的 XML 則建議使用 UTF-8。

怎麼這麼多種「標準」啊?從技術的觀點來看,每種編碼是各有其優缺點。但我有時不免會想:那些英語系國家的開發人員,大概不曉得處理這種編碼轉換是多麼令人厭煩吧。

星期四, 11月 10, 2005

技能、態度、注意力

教育(或者說專業教育)的主要目的是什麼呢?

"The main purpose of professional education is development of skills; the main purpose of education in subjects like mathematics, physics or philosophy is development of attitudes." Discrete Thoughts 的作者如是說。他們認為,專業教育是要發展技能,而數學、物理、哲學等科目的教育目的,則是在發展態度。(喔,或許,理學院與工學院的差異也在於此?)

在一本小書裡,則看到這樣的話:法國的思想家 Simone Weil 認為,注意力的培養,是學校教學的真正目的;它是唯一的意義所在,其他的意義都是第二位的。(且不說獲取知識就需要專心一致;如果不能夠聚精會神、專注地做某件事情,再多的知識又有什麼用呢?)

接受了十幾年的教育,我們在技能、態度、與注意力上,是否學到了什麼?

星期二, 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 點 --- 這個方法就行得通。)


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

星期四, 11月 03, 2005

談古契書資料處理:之一

這一陣子在「想寫的文章」上進展頗為遲緩 --- 那我在忙些什麼啊?

嗯,一言難盡。簡單地說,是在做實驗室古契書電子檔的一些資料處理實驗。

實驗室裡,多年來持續在進行一個 THDL (Taiwan History Digital Library,台灣歷史數位化圖書館)的計畫。希望能藉由電腦科技與數位化古籍資料,來改善歷史學者(與一般民眾)對台灣歷史的研究與了解。

因此,實驗室有著許多「花不少錢」請人數位化的台灣古契書資料。然而,光是「資料數位化」這個過程,其實就隱含著許多困難。例如,古契書常常會有一些奇特的字,沒有被收錄到 Big5 或者 Unicode 裡,而這就產生了「缺字問題」。

除了這個相對明顯的「缺字問題」外,還有一些努力(或者說是苦工)就經常被忽視。例如,將這些不同 corpus(文獻集)的資料數位化時,通常都是請人「把文件內容掃描、打字」來取得數位資訊的,因而就產生了「資料彙整」的問題。例如,若打字人員是用 Microsoft Word 來鍵入資料,那麼我們最後還是得寫程式來將文字資料從 Word 文件中轉出。

對文件做資料格式轉換,聽起來也沒有什麼。不過,它背後還隱含著文件編碼(Big5、UTF-16 Big Endian、UTF-16 Little Endian、UTF-8)的假設。於是,用 Java 寫的轉換程式,輸出就是 UTF-16 Big Endian 的格式 -- 這讓我稍嫌老舊的 UltraEdit「無法正常編輯檢視」,於是我就得花點力氣再將它們再轉成 UTF-16 Little Endian 編碼。

另一方面,寫程式從 Word 文件將文字資料轉出,有可能對某些文件處理失敗。通常,這部分的努力很少得到「長官」合適的重視,也因此讓「資料處理」成為一件吃力不討好的差事。

經過一些資料檢視與實驗,我對於實驗室學弟妹們的辛苦(做了很多雜事,卻沒有被 appreciate 到的感覺),其實是有一份理解的。

星期二, 11月 01, 2005

一無所有

日子過得很快,回鍋做博士後研究,也滿一個月了。

這個月來,對實驗室的環境漸漸進入狀況。主要的工作,就是在實驗室幫助學弟妹們討論、釐清研究主題與方向。此外,旁聽了一場座談會,並且代替項老師主持了兩次實驗室 meetings。

就像是貓所描述的「四十歲中年危機」,自己這一陣子,在自我認同、自我觀念上,確實有些變化。幾天前帶寶寶到中正紀念堂參觀「廣場藝術節」展覽,意外碰到大學同學老鮑,他的孩子已經十歲了。閒聊許久,他說,在這個年紀會這樣應屬正常,他同樣地也對生命價值感到困惑。

「是否我真的一無所有?黑暗之中沈默地探索你的手。是否我真的一無所有,明天的我又要到哪裡停泊...」大學口的重順餐廳,傳來一陣陣王傑的歌聲。這可是我大學時代的歌曲呢,想不到連續幾次在重順用餐,都聽到這首老歌。

哦,是否我真的一無所有?如果不是,那我又擁有了些什麼?

星期一, 10月 31, 2005

Where Theory Meets Practice

當「理論」碰上「實際」,場景會是如何呢?

有人說,實際是理論的延伸;也有人認為,理論是實際的抽象表達。那些聰明又有名氣的思想家,不管是支持哪一種論點,都能產生許多「有用」或「影響深遠」的思想或學說。

而自己工作了這些年,卻只有一些不成熟的經驗:理論與實際雖然在許多「概念層次」的地方很相似,但是在許多「現實層次」上的建議卻常有衝突。

這完全是現實社會的成本考量嗎?似乎也不是如此。有時,對於實際很重要的許多性質(例如「軟體品質」、或者資訊檢索中的「相關概念」),似乎連理論都難以界定清楚。

在一本關於 "Distributed Systems" 的書上看到右上方的這張圖。很喜歡它對「當理論遇上實際」的描繪。藝術作品就是這樣,對現實常有詼諧幽默的表達,富有詩意,又餘味盎然。

星期五, 10月 28, 2005

爭取

昨天終於催收到應得的資遣費,很是開心。

本是應得的東西,為什麼會覺得開心呢?因為,如果沒有如此主動、積極地爭取這些該得到的權益,我很可能會在一次又一次的延後中,逐漸麻痺自己,終至最後不了了之。(以個性、或者個人習性來說,我通常會先試圖爭取;倘若不成功,則最後很可能會自行吸收損失。)

然而,現今的社會,似乎偏好懂得爭取權益的人。「好人」不見得會得到獎賞,但「臉皮厚些、懂得爭取」的人卻經常能夠獲得實質的報酬。說得刺耳些,如果懂得爭取(或者像是「被掛掉的阿尼」所說,會吵會抗議),好像常常可以拿到「不是那麼應得」的好處。

「自行吸收損失」還有一個壞處:吃了幾次虧後,如果內心沒有好的化解方式,就容易感到不平、憤怒、或者憂鬱。這些情緒累積久了,是會得到內傷的。

很高興自己終於用行動來獲取應得的權益;也很高興自己在這些現實處理面上終於「有所長進」。

星期四, 10月 27, 2005

太過嚴肅

最近寫的 Posts 沒有得到什麼回應,有些傷心 :(

我想,就如同 Sophia 所說,寫得太嚴肅啦。不過,要怎樣才能寫出詼諧、幽默、有趣的小品文、或者生活記事呢?這可真是個大難題啊。

星期三, 10月 26, 2005

理論與現實

很久以前曾匆匆看過,但現在重新回味,又別有一番風味。

"Suppose a contradiction were to be found in the axioms of set theory. Do you seriously believe that that bridge would fall down?" (假設我們發現集合論的公設有矛盾。你真的會相信,那座橋會因此而掉下來?)

集合論是形式化 (formal) 數學理論的根基。沒有集合作為基礎,就發展不出關係 (relation)、函數 (function) 等進階的定義;而從邏輯上來說,也就推導不出各式各樣的定理。但是,「萬一」集合論真的有問題,物理世界「真的」就會因此而產生巨大的變化嗎?

據說,鼎鼎大名的 Turing 是相信:橋會因此而崩解;但同樣受人推崇的維根斯坦 (Wittgenstein) 則不同意。兩位大師級的人物,對理論與現實,竟然有如此不同的看法!(可參考這網頁。它的一些註解也很有趣:誰『贏』了?看起來 Turing 是有些太過天真,但他留給我們電腦這東西。至於維根斯坦留給我們什麼?呃...就是維根斯坦。)

也有人試圖在這兩個極端間取得緩頰。"Discrete Thoughts" 的作者 (Mark Kac, Gian-Carlo Rota, Jacob T. Schwartz) 認為,或許聽起來很基本的「公設系統的確定性」,在現實上卻顯得天真而不切實際。他們說,或許我們是該「認真地與不確定性共處」(而橋也不必因此而崩塌)。

星期一, 10月 24, 2005

使用者介面與資料呈現

這一陣子,對優良的「使用者介面」(User Interface, UI) 設計,都隱隱懷有一份欣賞與讚嘆。

為什麼會這樣呢?我猜想,是因為自己這些年來,漸漸感受到 UI 的重要性。此外,自己也曾花過一些心力去思考,卻苦於找不到「漂亮的抽象模型」來說明:怎樣的 UI 設計才算是好的設計、惱於「主觀的使用者意識與客觀的資料」之間複雜難解的互動。

之前在 Maryland 求學,就曾聽說過 Shneiderman 在 UI 設計上的大名。然而,那時的我只顧著尋找計算機科學的深層內容(或許也可說是「抽象美」),對於「使用者介面」則視為是二流的學問,因此錯過了去上課求知的機會(不過,那個時候就算是修了課,因為缺少了一份「強烈的動機與感動」,應該也只能膚淺地記得課堂上的知識內容,而學不到課程的精髓罷)。

這幾天,強烈感受到需要拓寬一下自己(與實驗室成員)對資料呈現(Data Visualization,它構成一部份 UI 設計的主題)方面的知識。於是,我從書堆裡,將 Shneiderman 的一本舊書又翻找了出來。

覺得書中的一份資料應該頗有啟發性。它列出資料呈現的分類方式(Data Types)、與一些相關的工作(Tasks;從使用者角度,或可說是「使用者可執行的動作」):

Data Types
  • 1-D Linear
  • 2-D Map
  • 3-D World
  • Temporal
  • Multi-Dimensional
  • Tree
  • Network
Tasks
  • Overview:
    - Gain an overview of the entire collection.
  • Zoom:
    - Zoom in on items of interest.
  • Filter:
    - Filter out uninteresting items.
  • Details-on-demand:
    - Select an item or group and get details when needed
  • Relate:
    - View relationships among items
  • History:
    - Keep a history of actions to support undo, replay, and progressive refinement.
  • Extract:
    - Allow extraction of subcollections and of the query parameters.
看到這樣的整理歸類,至少讓我從新思考 Temporal 與 Multi-Dimensional 之間的差異。我從前一直將 Temporal 視為 Multi-Dimensional 中的一種特例(多維度中的一個維度),卻沒有關注到:Temporal 的「時間」特質,其實與其他維度有著本質上的不同。這就好像把時空合起來,視為四度空間一樣:看起來具有一般性,但卻因為忽略了「時間之箭」的特質,實際上最後卻反而把自己侷限住了。

或許,這也是過度執著(於抽象化),所衍生的的盲點?

星期四, 10月 20, 2005

再談傳教士與食人族

幾天前,曾提到「傳教士與食人族」的問題。

它的解答並不困難,右圖就是一種解答(在此,我用 B 代表「黑人」或食人族、用 W 代表「白人」或傳教士)。一開始,左岸有三個黑人、三個白人、與一艘船(用黑色的方格代表);第一步,一黑一白將船開到對岸;第二步,一個白人將船開回左岸;接下來,兩位黑人將船開到右岸,然後一個黑人把船開回來... 如此一共進行 11 步,就可以將所有人都渡到右岸。

據說,一般解不出來的人,大多是在第五步後,沒有注意到第六步 -- 這一步將辛辛苦苦度到對岸的一個黑人與一個白人度回左岸。

傳統的人工智能 (Artificial Intelligence) 相當強調問題解決 (Problem Solving),因此也經常用「簡單且經典」的益智問題當作教材,告訴學生何謂搜尋空間、以及如何有效搜尋。

從概念上來看,如何「解傳教士與食人族問題」其實相當直觀:我們只要把問題的「狀態空間」 (state space) 產生出來(作為程式的搜尋空間),然後找到一條路徑,從問題起始的狀態,通到目的狀態即可。

例如,在這個問題裡,一個狀態就是像 (1B1W, R, 2B2W) 這樣的一個 tuple(有序元,或者說是向量),它表示「有 1B1W 在左岸,2B2W 在右岸,而船停在右岸」(右上解答圖在第五步後,就是停留在此狀態)。而「傳教士與食人族」的問題,也就轉化為:尋找一條路徑,由 (3B3W, L, 0B0W) 狀態,通往 (0B0W, R, 3B3W)

至於如何實作,講穿了後其實也頗容易(這點可以日後再找機會討論)。值得一提的是,今天在 CNET 上看到一篇報導(它提到:在全球資訊網上,或許 PHP 比 Java 更有可為。但我在意的,是「簡單相當重要」這種觀念與原則)。這也讓我覺得,自己選擇用 PHP 而非 Java 來實作展示「曾感興趣的問題」,或許是恰當的呢。

星期二, 10月 18, 2005

歷史是什麼

前些日子看到一本小書:「歷史是什麼」(書林出版,老共學者李公明著)。

由於目前實驗室做的研究,有相當大的部分是在於「用電腦與數位化內容,來幫助學者研究台灣的歷史」,因此稍微了解歷史學家(可類比於資訊界常聽到的「領域專家」:domain experts)怎麼看待事情,應該會對研究的結果有些幫助。

以下摘錄一些書中的句子(我有對部分修辭作些小更動):
  • 歷史是一則約定俗成的寓言,也是現在與過去永無止境的問答交流。「歷史」告訴人們什麼是過去,並幫助預測未來。

  • 只有那些被歷史學家賦予了意義、並進入人類記憶之中的事情,才成為真正有價值的「歷史」。(衍生的問題是:歷史學家根據什麼來判斷哪些已發生的事情是有意義的呢?)

  • 與一般人相較,歷史學家是一群對歷史意識更有自覺、更主動研究過去的人;他們感到有責任把自己所了解到的過往事情,講述給更多的人。

  • 歷史學研究的對象,與自然科學所研究的對象,有著根本上的差異。歷史學家無法超越時空限制而面對過去;他們只能面對一些歷史的遺物,而這些遺物本身無所謂證明什麼,要依賴歷史學家決定用它們來說明什麼。

  • 史實並不是歷史學家研究的出發點,也不是經過挑選、並賦予意義之後就可以密封保存的。(因為現在和以後可能發生的事情,都有機會改變我們對某一史實的看法。)

  • 歷史學家的主要工作過程:收集史料、提出問題、作出解釋並予以證實。

星期一, 10月 17, 2005

傳教士與食人族

它是個不困難、但也算經典(經常被書本提起、參考)的益智問題。

這個問題的正式名稱,應該是叫做:Missionary and Cannibal(傳教士與食人族)。但小時候那裡知道什麼「傳教士」,聽到的是「通俗版語言」的「黑人與白人過河」問題。

通俗版的描述是這樣的:有三個白人與三個黑人要過河。但河邊只有一艘船,且船上最多只能容納兩個人(當然,至少需要有一個人在船上,才能將船駛到河的彼岸)。此外,還有一個條件:不管是在河的哪一邊(或是在船上),當黑人的人數超過白人時,黑人就會把白人吃掉。問題:要如何安排渡河的順序,才能夠讓此三個白人與三個黑人順利渡河?

不記得是國小、還是國中時,第一次聽到這個問題了。說也奇怪,似乎也只有在那個懵懵懂懂的年代,才會對任何需要動點腦筋的益智問題,都感到有股熱忱與衝動。不知道是不是因為年紀漸增,變得現實老成;現在對許多事情都顯得力不從心、甚至提不起勁。當然,我對許多曾感興趣的益智問題,也就失去年少時的興致,而只剩下淡淡的回味了。

星期五, 10月 14, 2005

誤打誤撞

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

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

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

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

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

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

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

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

星期三, 10月 12, 2005

寶刀未老?

今天與學弟妹討論檢索與分類後,突然有「喔,我竟然懂得還不少」的感覺。

或許是因為自己當初(做博士研究)的確曾對資訊檢索與分類深思過、或許是因為「資訊檢索」在這幾年來也進展緩慢、又或許只是因為大家並不善於表達內心深邃過人的創意;我對學弟妹們做的許多「古契書檢索」研究,在概念與系統整合上,總覺得有些「似曾相似」的味道。

而這兩個星期與學弟妹個別討論時,我竟然也幾乎都能夠在不算長(30 ~ 60 分鐘)的時間內,大致上抓到每個人研究的重點,甚至還能提供一些參考或建議。

這是否是只是種幻覺?或許,是自己一廂情願、自欺欺人地認為自己「寶刀未老」哩。

星期二, 10月 11, 2005

三談 AB-game

網路檢索到 Mastermind 相關的文章後,發現 Knuth 的方法確實可以減少猜測的次數。

我們或可將它視為一種「如何縮小可能性空間之優化處理」的方法。在先前「再談 AB-game」這篇 post 裡,提到甲每猜測一次,就可以藉由乙的回答,從「可能性空間」裡,刪除一些「不可能是答案」的數字。問題是,該猜測那個數字,才能夠排除最多不可能的答案呢?

Knuth 建議,選一個數字,讓「剩下的狀況裡,有最多可能性」的值是最小的 (choosing at every stage a test pattern that minimizes the maximum number of remaining possibilities)。

令人困擾的是,雖然 min(max(...)) 這樣的抽象式子簡潔漂亮,但是對於我這樣非數學系背景的人,通常並無法從這樣的式子中、看出它的直觀意義。因此,對這個式子多加些解釋,應該是有助於理解的。

對於目前的「可能性空間」(也就是「不會與乙對甲先前的猜測所給的回答」衝突的所有可能答案)而言,任何甲的新猜測都可能有 14 種回答(4A0B、2A2B、1A3B、0A4B、3A0B、2A1B、1A2B、0A3B、2A0B、1A1B、0A2B、1A0B、0A1B、0A0B -- 不可能有 3A1B 的情況發生)。這 14 種回答,可以將「目前的可能性空間」切割 (partition) 成 14 個集合。

例如,假設目前的可能性空間為 S = {3749, 4379, 8095, 8590}(參考右圖),若下一步甲猜 3749,則乙只可能有三種回答:4A0B(若乙的謎底也是 3749)、1A3B(若謎底為 4379)、或者 0A1B(謎底為 8095 或 8590);其他像是 1A3B、0A4B 等等回答,都是不可能的。因此,3749 這個猜測,可以將 S 分割為 {3749}、{4379}、{8095, 8590}。

換個角度看,這樣的切割表示,經過甲的 3749 猜測後,可能性空間只能是 {3749}、{4379}、{8095, 8590} 這幾個分割中的一個。於是,我們知道:經過猜測 3749 這個數字後,「最大的可能性空間」是 {8095, 8590},而其集合的個數 (cardinality) 則為 2。

值得提醒的是,我們不見得一定要猜測可能性空間裡的數字。例如,我們可以猜 8793,它可以將 S 切分為四個 cardinality 為 1 的 partitions:回答 1A1B 的 partition 為 {8095}、回答 2A0B 的 partition 為 {8590}、0A3B 的 {4379}、以及 1A2B 的 {3749}。

Kunth 的方法,就是從所有可能的新猜測裡,選擇會讓「最大可能性空間」個數 (cardinality) 為最小的那個數字。在上面的例子中,猜測 8793 會比猜測 3749 來得好;因為前者切分出的 partitions 中,最大的 cardinality 為 1;而後者切分後,最大的 cardinality 為 2。

我也依照這個演算法實作了程式。實際跑過後,它驗證了這個演算法,對於 Mastermind 的確可以在五步內猜得答案。然而,對於 AB-game,這個演算法卻仍然可能需要猜測七次。

所以,Knuth 的演算法,並不能證明「AB-game 在最壞的狀況下,也僅需要猜 6 次」的傳說(除非我程式寫錯啦,但這也並非不可能)。那麼,這個傳言的內容,究竟是真還是假呢?

星期五, 10月 07, 2005

溝通是種藝術

好的溝通很困難。奇妙的是,當事人經常不覺得溝通是件不容易的事。

回鍋作 post doctor 的「工作」,實際上卻沒有特別想做的研究。雖然對於資訊檢索、甚至是 THDL (Taiwan History Digital Library),我仍然有著頗為濃厚的興致,但我還是想「在這一年內盡量整理從前感興趣的主題、並寫出些東西」。

就先扮演項老師與實驗室學弟妹間的橋樑吧。這個星期的主要工作,就是與實驗室的幾位學弟妹,討論他們目前的研究狀況,並適時提供一些適當的建議。

令自己覺得有些高興的是,對於溝通討論,我終於有了一些說來頗微不足道的自覺(這應該也是今年前半年在公司進行「產品改良專案」所學到的吧)。

自覺到什麼呢?雖然我在討論、詢問學弟妹們的工作內容時,仍然時常尖銳地 (sharply) 試圖從概念與模型來明確定義使用的詞彙(我多少覺得,明確的詞彙非常重要;而大家通常都在「模糊的描述中,討論模糊的未來方向」);但我有時會突然驚覺,過度尖銳的對話,對於溝通是沒有太大幫助的。

因此,溝通的技巧非常重要。我甚至覺得,溝通就像是藝術呢。如果能夠懂得欣賞溝通(就像是懂得欣賞藝術般),就應該更能欣賞對方的長處與成果、更能了解其他人的想法吧。

星期四, 10月 06, 2005

Mastermind

Mastermind 是一種很像 AB-game 的兩人遊戲。

事實上,我接觸到 Mastermind 這遊戲的時間,比 AB-game 還要早。印象中,大約在二十年前,大姊就曾買過這個益智遊戲來給家人玩了。

Mastermind 的棋盤如右圖所示。玩法是這樣的:甲先由六種非黑白顏色的釘子中,選四個排在盤面上作為謎底,然後讓乙來猜。對於每一次乙的回答,甲作如下的提示:若乙猜的顏色與位置都相同,則放上一個黑色的釘子;若乙猜的顏色對,但位置不同,則放上一個白色的釘子。與 AB-game 不同的是,Mastermind 允許出謎著選相同的顏色。因此,甲可以有 6 x 6 x 6 x 6 = 1296 種不同的謎底選擇。

例如,若甲的謎底是 BBRY(藍色、藍色、紅色、黃色),而乙的猜測是 RBGB(紅色、藍色、綠色、藍色),則甲所回應的提示就是:1B2W(一黑:第二個位置顏色相同;二白:一個藍色的位置不同、一個紅色的位置不同)。

Web 上有許多網站討論 Mastermind。例如,Invitation to Mastermind (參考 Ankh 在「再談 AB-game」的 comments),就有提到,Knuth 在 1976-77 年間,即已提出一個 algorithm,它能夠在五次猜測內取得答案。

有趣的是,雖然從一開始,我就很想檢索「跟這個遊戲相關」的文件,但由於當時並不知道 Mastermind 這個名稱,因此根本就不知道如何下合適的 query keywords。換句話說,雖然我有 user needs,也有威力強大的 Google 搜尋引擎,但是我卻仍然無法用「描述這個遊戲」的方式,來取得檢索結果。

那我是怎樣得知 Mastermind 這個關鍵字的呢?說來也奇妙,我其實是用「不知道是否為正式名稱」的 "AB-game" 去檢索,然後在檢索到的文件中,發現 Mastermind 這個關鍵字的呢!

星期一, 10月 03, 2005

回鍋第一天記事

今天是「回鍋」作 post-doctor 的第一天。

大致上來說,「工作」得還算充實;但因今天沒有睡午覺,身體有些疲累。

做了些什麼呢?與四位碩二的學弟談了談,了解他們目前在做的研究、已做出什麼成果;可能的話,也順便問問他們「接下來是否還想做些什麼」。

老師還說,電機的博理館有 FORTE (Formal Techniques for Networked and Distributed Systems) 與 ATVA(不知是什麼縮寫)的 conference,應該頗值得去聽聽看。於是,我下午也去聽了 Protocol Verification 的 session,感覺還算不錯。

星期五, 9月 30, 2005

再談 AB-game

年輕時,很容易手癢、想寫程式來解一些益智問題。

AB-game 也算是頗有趣的遊戲。因而,我在很久以前,就曾寫一支程式來(和使用者、或電腦自己)玩 AB-game。雖然那時自己其實對程式設計懂得很少,但最後還是能用 BASIC 語言,笨笨地、很暴力地 (ad hoc) 寫出「還算能夠玩」的程式。

回想起來,雖然頗覺得當時「不知天高地厚」,但心裏仍不免懷念那段年少輕狂的過去。也是因為最近試圖整理「從前感興趣的問題」,讓我回想起 AB-game。

從遊戲規則來看,要寫一支程式來檢查使用者的猜測,是相當容易的。程式可先依亂數選定一個數字,然後檢查使用者輸入的數字,回答幾 A 幾 B;直到使用者猜到程式所選的數字(回答 4A0B)為止。另一方面,要寫一支程式(扮演甲的角色來猜乙所選的數字),自動猜測使用者心裡所想的數字,似乎就不是那麼容易。

稍微分析一下,我們知道,在還沒有猜測前,乙選的數字有 10 x 9 x 8 x 7 = 5040 種可能。所以,即使乙並不需要回答幾 A 幾 B (僅需回答「是否猜中」),最糟的狀況下,我們也可以將這些可能的數字一個一個地拿來詢問「是這個數字嗎」,而在 5040 步內,猜中乙的答案。

而我們現在有乙所回答的「幾 A 幾 B」資訊,該如何利用它呢?最直接的方式,就是利用這項回答,從 5040 種可能(或者稱作「可能性空間」,possibilities space)裡,將不符合的數字刪掉。例如,如果猜測 1234 而得到回答 0A1B,那我們知道,答案不可能是 1234 (否則,回答應該是 4A0B)、不可能是 1567(若答案是 1567,猜 1234 的回答應為 1A0B)、也不可能是 8912 (回答會是 0A2B 而不是 0A1B)...。

因此,甲每猜測一次,就可以藉由乙的回答,從「可能性空間」裡,刪除一些「不可能是答案」的數字(也就是說,每一步都可以縮減可能性空間的大小)。於是,還保留在可能性空間裡的數字,就是「經過一連串猜測與回答後,仍有可能是答案」的那些數字。而我從前的程式,就是任意地從可能性空間中挑選出一個數字,來當作下個回合的猜測。

接下來的問題是:若演算法是任意由可能性空間裡,挑選一個數字,那麼最壞的情況下,需要猜測多少次呢?或者,更進一步:平均起來,需要猜幾次才能得到答案?還有:雖然可能性空間裡的數字,都有可能是答案;是否會有一些數字,它比其他的數字「更有可能」是答案?

雖然經過了這些年、似乎累積了更多電腦相關的知識;但我除了對從前的程式實作,有些改良的意見外,竟然也沒能想出更好的演算法與結果呢!

星期三, 9月 28, 2005

AB-game

雖然不知道 AB-game 的正式名稱,但我猜想,很多人都曾玩過類似的遊戲。

它是一種兩個人玩的遊戲:甲乙兩人各自在心裡想一個四位數字 (4 digits),然後輪流讓方猜測這個數字(而自己則對此猜測的數字,依下一段的說明做回應);能夠先猜出對方數字的人就算是贏家。

對於對方的猜測,回答的規則是這樣的:假設自己設想的數字是 a3a2a1a0(四位數字,在此千位數為 a3,百位數為 a2,十位數為 a1,個位數為 a0)而對方猜測的數字是 b3b2b1b0。若 x 為集合 {i | ai=ai} 的個數 (cardinality),而令 y 代表集合 {i | ai=bj, i ≠ j} 的個數,則我們的回答就是 xAyB。

換句話說,x 是「數字相同、位置也相同」的個數,y 是「數字相同、但位置不同」的個數。例如,若設想的數字是 1234,而對方猜測 3614,則我們回答 1A2B(數字 4 出現的位置相同;而數字 1、3 出現的位置不同);若設想的是 1357,對方猜 7890,則回答是 0A1B (沒有數字出現在相同的位置上;而有一個數字 7 出現在不同的位置)。

在 AB-game 裡,我們通常會要求猜想的四位數字不可重覆;也就是說,要求 ai≠aj (i ≠ j)。至於第一位(千位數)a3,一般則可以為零。因此,可猜想的數字,共有 10 x 9 x 8 x 7 = 5040 種可能。

右圖是一個可能的猜測序列。乙所選定的數字為 8590,而甲的運氣不太好:他先猜 0123,得到回答 0A1B;接著猜 1456,又得到一樣的回答 0A1B;如此這般,甲總共花了八個步驟,才猜對 8590 這個數字。

花了這麼多篇幅介紹這個遊戲,我到底想說些什麼?

我想說的,是一段聽聞與經驗有些衝突,但沒有經過驗證 (prove or disprove) 的情事:印象中,似乎曾聽人說過,「最糟的狀況,也僅需猜六次」。然而,在我的記憶裡,雖然在大多數情況下,的確只需要猜六次,但我似乎也曾有要猜七次(或七次以上)的經驗。

所以,為什麼只需要猜六次,就可以得到答案呢?

星期六, 9月 24, 2005

簡報後的檢討

昨天簡報後,自己總覺得不太對勁。

問題出在哪兒呢?我想了想,大致上或可說是:「準備不足、時間不夠、缺乏互動」。

首先,是遇到螢幕大小的問題。由於先前沒有使用「寬螢幕筆記型電腦」的經驗,不知道接上投影機後,會產生字體扭曲的現象。事後,我猜測是(筆電螢幕與投影機螢幕)解析度不同的緣故;但自己也頗好奇,為什麼產品手冊上,沒有教使用者如何處理這類狀況?

說來也真奇怪,我這回買的 HP Presario B1800 筆電,竟然沒有附產品的說明或使用手冊。大概是 HP 以為使用者都知道鍵盤上各式按鍵的使用方式、也都瞭解各類燈號的意義。可是,我就曾經因為不知道有個「打開無線網路」的按鈕而虛耗數個小時呢(參看 8 月 31 日的 post)。現在,自己碰到「螢幕解析度」的問題後,不免會想:「難道,只有我才會碰到這種狀況;只有我才會認為:它是個需被解決的問題?」

我猜測這個問題,與多重螢幕的設定有關;不過自己並不瞭解多重螢幕間,設定、切換、與運作的方式。有沒有人(喂,萬事通的貓啊,快幫我想想辦法吧)能夠提供合適的建議或解答呢?(還是,乾脆該打電話向廠商求教?)

除了「簡報顯示扭曲、自己與觀眾看了都不順眼」之外,我覺得「投影片準備不足、簡報時間不夠」也是項缺點。說投影片準備得不足,其實該說是自己並沒有想清楚:這次的簡報,究竟想達成些什麼。而簡報的時間不足,除了頭頭(項老師)有事必須提前離開;簡報期間太太數次行動電話 call-in ,也讓自己顯得手忙腳亂。

最後,關於缺乏互動的部分,自己似乎早該知道、也該事先有所準備(如此就不會對「缺乏互動」感到不安)。在做簡報前,已經有三位學弟報告過了。輪番上陣、疲勞轟炸的結果,聽眾早已心力交瘁、頭昏眼花,怎能有氣力與意願,來做良好的溝通與互動呢?

星期五, 9月 23, 2005

回實驗室給了一場簡短報告

準備了一個多星期,今天下午在實驗室給了場簡短的報告。

報告的內容,就像是上星期五所提到的,是嘗試以「見樹」的方式、換個角度看待古契書文件群。因此,雖然自己對古契書其實一點都不懂,還是努力假想了一個使用情境,然後從中看看是否能夠學習到什麼。

或許是時間不夠、或許是很久沒有在學校做過簡報,又或許是自己準備得還不夠,我總覺得許多地方講得不是很好(也就是說,詞不達意、講得不清楚啦)。不過,除了自己可以學習簡報技巧外,我還是傾向於將簡報看作「報告者與聽眾的溝通與交流」;聽眾(學弟妹們)的感受、收穫、想法與回饋,才是最實際、也最重要的。

星期四, 9月 22, 2005

科教館的玩具

如果有用心,在台北常能發現有趣的事物。

例如,士林有一座國立科學教育館,假日人潮洶湧,但上班日通常門可羅雀,非常適合帶小朋友去走走。更棒的是,即使不買門票,也常能得到許多樂趣。

我們因為常有事到士林,偶而也會帶寶寶到那兒,看看門外的「球球坐電梯」。它是一座很有趣的機器,利用傳輸帶將球帶到高處,然後讓它由高處滾動滑下、撞擊、彈跳(右圖是這座機器的部分展示 -- Blogger 似乎會把上載的動態圖弄壞)。不僅很多小朋友喜歡駐足觀賞,我也常常在那兒感到歡欣讚嘆。

該館一、二樓有賣許多玩具,也提供一些樣本讓小朋友試玩。非假日期間,寶寶通常都能玩得頗愉快。有時,也可以找到一些有趣的益智遊戲,讓大人們也都能玩上好一陣子。

昨天帶三歲的寶寶去科教館,又發現一個可愛的玩具。它其實是一隻氣球,但日本人發揮巧思,在氣球下裝上合適重量的膠紙(作為動物的腳),讓氣球漂浮在離地約 10 公分處。小傢伙用線牽著氣球走,就像是牽著真實的動物一樣可愛。

雖然價格有些偏高,但寶寶玩得高興、又覺得需要鼓勵這類的創意,我決定讓她自己挑一隻。連問數次,小傢伙都選了「小公雞」。我讓她牽著小公雞在館內四處逛、教她到二樓書局講故事給小公雞聽 -- 而或許是因為看到寶寶高興的樣子,我在那些時刻裡,確實感覺頗為幸福。

下圖就是這隻「小公雞氣球」的長相。遠遠看來,還頗像真的公雞呢。

星期一, 9月 19, 2005

AI 是什麼?

上星期五實驗室聚餐,項老師也出席了。

席間,老師半開玩笑似地說,AI(Artificial Intelligence,人工智能,從前翻譯為人工智慧)是一個很奇怪的領域。他說,AI 有許多定義,其中的一個定義是:「AI 是研究那些人腦可以做,而電腦卻不能做的事情」。

依照這個定義,老師說,AI 裡研究的主題,一旦成熟後,就會獨立出個別的學門,不再算是 AI 了。例如,幾個從前被認為算是 AI 領域的學科,像是 Image Processing(影像處理)、Theorem Proving (定理證明)、Robotics(機器人學)等,在漸漸成熟、知道如何運算出夠好的結果後,都獨立出自己的學門;而研究這些主題的學者,也都不再認為自己 是在做 AI 的研究了。

老師接著說,「所以,AI 存在的目的,就是為了消滅它自己,那真是怪異 (weird) 啊。」

其實,項老師在十年前,就講過一樣的話了。但從現實面看,就算我們真的是如此定義 AI,而 AI 的存在,也真的只是為了消滅它自己,那又如何呢?

即使最終電腦可以取代人腦,但 AI 身為衍生出這些有價值的獨立學門之母,應也足夠了,不是嗎?更何況,我是屬於「認為電腦無法取代人腦」的人;而只要存在某些事情,是人腦做得比電腦好的,那 AI 也就有存在的價值啊。

後記:由此也可看出,學數學的人(項老師)對「定義」的敏銳程度。學工程的人或許會覺得,定義沒有弄得很清楚也不打緊,系統做得出來、運作無誤就好了。但做科學研究、尤其是有志於理論研究者,似乎還是該先瞭解定義比較好。

星期五, 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月 11, 2005

能夠「輸出自己」的程式

前些日子提到 Ackermann's function 後,也讓我回想起一些有趣的小問題。

其中一個,是寫個程式,它不管輸入什麼,都會輸出自己(這份程式)。這個問題之所以有趣,一部份的原因,是因為乍看之下,要求得一組解(寫出一個能夠「輸出自己」的程式),似乎並不困難。但真的如此容易嗎?有興趣的人可以試試看。

第一次碰到這個問題,也是在 Maryland 時,計算理論老師 (Dr. Smith) 的講義裡,某個習題提到的。當時是沒有出這項作業,但我有花幾個小時嘗試寫過,並沒有成功。(嗯,還是一樣,沒有成功解出的問題,比較會印象深刻...)

在課堂上,老師也提到過,我們可以證明:不管是哪種程式語言 (只要它們的計算能力相同,都是 Turing-complete -- 現在幾乎所有的程式語言,像是 C、BASIC、JAVA、LISP、PASCAL、PROLOG,甚至 PHP,都是 Turing-complete),總是存在著(無限多個)這樣的程式,它們可以輸出「它們自己」(此證明可參考這本書末,對習題 2.13 的解答)。

自己則是在數年後,從 BBS 上看到有人貼出用 C 語言實作的漂亮答案。我將它稍微修改,展現成 PHP 的程式碼:

<?php $s='<?php $s=%c%s%c;printf($s,39,$s,39); ?>';printf($s,39,$s,39); ?>

你能夠自己寫出這樣的程式嗎?

星期三, 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 行右側有一道由下往上的長牆。如此一來,產生的迷宮似乎就蜿蜒曲折了些。

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

星期五, 9月 02, 2005

不用上班的一個星期

一般說來,「不用上班」似乎是「不用工作」的意思,是「悠閒」的代名詞。

不過,就如同 MPH 幾天前在 Blog 所言,不用上班的日子,感覺似乎更為忙碌(有時,我連早上看紐約時報的時間都不夠呢)。難道真的應驗了:「休息是為了更忙?」

我不清楚。我只知道,這幾天在家,倒是處理了許多上班時「忙碌而沒有做」的事情。通常,這類的事情必須麻煩家人來處理(所以啊,從前能夠空出一些時間,多少需要感謝家人的幫忙);而現在不用上班,就「理所當然」地該由自己來做了。

在家裡,似乎比較無法專心整理、回想、思考曾經感到興趣的電腦相關問題。因此,我會擔心:做這些「雜務事」,讓自己沒有什麼時間可以進行原先想進行的「心得、感想整理」。做這些事情,需要相當的專注、耐心、與毅力才能達成。

我希望,這幾天的忙碌,能夠算是「特例」。逐漸處理完「從前累積下來的事務」後,期待可以慢慢地「進入狀況」。

星期三, 8月 31, 2005

終於買筆記型電腦了

離職後的這幾天頗為忙碌。尤其是,終於買了一台筆記型電腦。

早在幾個星期前,我就打算買一台筆電了。想要重量輕、規格好(CPU 夠快、記憶體 1GB、硬碟也不能太小、最好還是寬螢幕)、價格也合理的機型。在網路上看了幾天、到 Nova 看了一回、嫌 Sony 的太貴,只能在 Asus 的 W5 與 acer 的小狗機之間作選擇。但 Asus W5 只支援到 768 MB RAM,acer 的品質一般來說又頗差,怎麼辦呢?

最後是找到 HP Compaq 的 B1800。除了光碟機是 Combo 外,大致上都相當滿意(不過,事後從 CNET 的報導中,知道含電池的重量其實是 1.86 公斤,比型錄上聲稱的 1.6 公斤重了不少,令我有些被騙的感覺)。

接 下來的事情,就是安裝軟體了。由於無線基地台與 Hub 的位置弄錯了,花了許多時間在安裝與測試(最後還是在貓的指導說明下,才知道弄錯了)。更扯的是,我不知道這台筆記型電腦必須在按了某個按鍵後,才會打開無線上網的功能,竟花了數個小時的時間在檢測基地台與筆電間的安全設定。

不過,安裝設定好了後,敲打著筆電的鍵盤、上網查資料寫 Blog,也覺得頗為滿足。

而花錢買東西就是這樣,經常可以得到許多「擁有新東西」的興奮。難怪許多現代人,會喜歡藉著添購新事物來抒發鬱悶、讓自己「似乎」可以活得快樂些。

星期二, 8月 30, 2005

我看紐約時報的感想

數個月前,回實驗室參加 meeting,項老師鼓勵大家看每週聯合報所附的紐約時報 (New York Times) 精選。

自己的英文程度不佳,是早就知道的事。看英文報紙,不懂的單字頗多,即使是一篇短文,都要看上半個小時。但許多知名的教授(像是李家同)都極力推薦大家看紐約時報,我想,我是該每天儘量抽出些時間來嘗試閱讀。

說真的,看了幾個星期後,我覺得台灣的報紙,真的不知道在報導些什麼。報導的主題狹窄、內容貧乏就算了,連寫篇「好文章」的基本訓練都沒有。

紐約時報的每一篇報導 --- 即使是短短的幾段文字 --- 都是自給自足 (self-contained) 的。每一篇都像個完整的故事,重要的個體(人、事、時、地、物)都有被清楚交代;而故事人物的心情起伏,描述也是生動極了(我目前其實是透過聯合報的中文 翻譯 與解說來感受的。說來也頗自卑:我對英文字詞的微妙用法了解非常有限;看到不同的形容詞此起彼落地出現,通常只能瞠目結舌,更不用說是了解吸收)。

項老師說,學習英文,除了多看多學習外,沒有其他的訣竅;而紐約時報的文章,多半都是「好的英文」。我看了這幾週後,有一個很強烈的感覺:「好東西該與好朋友分享」,真的該向大家極力推薦。

星期六, 8月 27, 2005

浮濫的商業口號

有一陣子,我對陳腔濫調的口號頗感厭煩。

部分原因是,這些口號看起來、聽起來都冠冕堂皇,合理正當,但經過一段時日後,總會覺得它們與實際的執行落差太大。由於我的邏輯感似乎常常會告訴自己:「必須強調前後的一致性」,因而時常會對於對這類的矛盾衝突感到不舒服。

恰好那時正在看「隨機的致富陷阱 -- 解開生活中的機率之謎」這本書(時報出版)。作者提到 (p.90),我們或可用隨機的方式,模擬公司執行長的言談,用以確定他說的話是真具有價值,或者只是經過修飾後的胡言亂語。

也想起傳統的人工智能 (Artificial Intelligence) 中,有著一個「電腦作文」的主題:希望電腦可以藉由一些規則與亂數,隨機地自動產生文章。要產生商業口號,應該比作文容易得多吧?心血來潮,就寫了一段小程式來玩。這個程式在剛剛的執行中,產生了這樣的幾個句子:

我們日新又新,致力於股東的持股價值
我們堅持誠信為企業之本
我們致力於追求卓越
我們發揮己長,並且改善缺點
我們相信如何對客戶提供更好的服務

雖然最後一句顯得相當古怪(「相信」如何對客戶提供更好的服務?),但大致上,讀起來也真像會議中所常聽見的執行長用詞呢。

星期五, 8月 26, 2005

珍重再見

辦完離職手續,正式與公司揮手告別。

回首過往,已如雲煙。在這家公司,工作了三年又四個半月。從早期對未來的憧憬想像、中期對產品的積極找尋、以及晚期對軟體的品質管控,自己多多少少是有著一些感觸。

就如同波普 (Karl Popper) 認為科學的真理必須靠臆測與否證 (conjecture and refutation) 來向前推進;對於公司在某個時刻的發展選擇,事後也多半隻能以成敗論英雄,卻很難累積一致的經驗與規則。以事後諸葛的角度,我們是可以舉出許多例子,來說明為何會導致現在的失敗;但是處在多種相互衝突的選擇間,其實也沒有絕對的定律來告訴管理者該如何做。

於是,我們可以看到許多彼此矛盾的商業策略、前後不一致的銷售模式,讓公司裡的員工經常無所適從。而或許也因為如此,保持「簡單、清楚、一致」的商業策略與貫徹執行,才更讓人感覺其重要性。

有趣的一個經驗是,「當你已不在乎你的職位,反而能夠做好這個職位所該做的事」、「當你不在意能夠得到什麼而盡力付出,反而能夠得到最多」。我想,這或許就是一般人的盲點:只看見自己想要的,卻忘記團隊是需要關注到他人需求後,才能夠團結併發揮力量。

星期四, 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月 23, 2005

Stop improving yourself and start living

昨天和 MPH 在 msn 閒聊。他說,想寫關於「Stop improving yourself and start living」的系列文章。

我說,這句話說得真好。我人屆四十,才驀然發覺,自己從前汲汲於改進自己(尤其是學識上的技術相關領域),努力想在工作上有所表現;卻忘卻了:眼前的生活,才是最值得珍惜與重視的。

自上週三起,努力進行的專案就被迫停止,而公司也進行裁減人力的動作。突然間,好像「沒有事情可以做」了。而前幾天早晨,我到台大醫院抽血檢查,在二二八公園走走逛逛,聽聽鳥叫蟲鳴,很強烈地感受到很久都沒有的舒暢。

我說,我想空出一年來整理自己這些年的感想;但一年後,似乎總還得去找份「正式的工作」。只是,為什麼「工作」在現代人的生活裡,竟然扮演了如許重要的角色呢?

星期一, 8月 22, 2005

我想整理些什麼?

想花一年的時間,整理自己這些年對電腦(科學、軟體、程式)的心得與感想。

起因是這樣的:自己快要四十歲了。不知道是年歲的關係、還是工作的緣故,在電腦科學(或電腦工程?)領域浮沈了十幾年,了解的知識越多,卻越來越覺得喪失了年輕時的好奇與樂趣。

我在高中時,並沒有上過任何關於電腦的課程,也缺乏現今的網際網路來取得資訊。在大學時代,雖然仍對許多電腦相關問題感到興趣,卻總覺得缺乏一本整理過的書籍,能夠帶著我入門、領著我欣賞。如今,雖然電腦書籍已經稍嫌氾濫、Internet 與 Google 又威力龐大;但我仍然覺得,或許有些年輕朋友,會像我當初那樣,需要有人整理些有趣的主題,寫成可以動動頭腦、又可以學習到電腦技術的書籍。

因此,我想整理一些感想與心得,獻給約具備高中或大學一、二年級的數學程度、對電腦(程式)感到有興趣的朋友。此外,我也希望能藉著回顧年少輕狂,重新品嚐青春的淺淺歡樂與悲傷,讓自己的人生,有著更甘醇的韻味。

能不能做到呢?我自己也不是很有把握。在這幾個月裡,我雖然已經慢慢地從日記、筆記堆、與古早的軟碟片裡,找回一些曾經感到興趣的主題,卻總覺得不知道該如何著手來完成一篇文章。貓(LCAT)建議我從寫 Blog 開始、逐步練習寫作。我頗為贊同,所以就開始了「也是回顧」的漫筆。至於成效如何?就只能讓時間來說話了。

星期日, 8月 21, 2005

也談「說謊村」

我對益智性的小題目也頗感興趣。

「說謊村」是一類有趣的問題。在這類問題中,通常都會有
  1. 兩個地點:「老實村」與「說謊村」;與
  2. 兩種人物角色:一個是「老實村」的人,他永遠說真話;另一個是「說謊村」的人,他永遠說假話。
〈問題一
你來到一個村莊,卻不清楚它到底是「老實村」或「說謊村」。現在你只能詢問(當地)村民一個問題,來確認是否是在哪一種村莊裡。你該如何問這個問題呢?

對於忙碌的現代人來說,通常想個一兩分鐘,就可能懶得再去思考,直接看答案了。而看到答案是,問村民:「請問你住在這個村子裡嗎?」時,又會覺得:喔,答案好像不太容易想到?(出題、解題的人,怎麼這麼聰明啊?)

其實,我們可以反過來,從回答端來思考這個問題。也就是說,我們希望讓提問有「是」與「否」兩種回答;當聽到的回答為「是」,我們希望確定是在老實村裡;而聽到「否」 時,則了解是處在說謊村(也可以反過來提問另一種問題,聽到回答「是」表示是在說謊村,聽到「否」則表示在老實村)。

因此,關鍵是在於問一句話,讓老實村的人回答「是」,而說謊村的人回答「否」。因此,答案就浮現了:我們可以問一個「恆真」的問題,例如「請問 1+1=2 嗎?」、「請問你是(老實村或說謊村的)人嗎?」;或者,問「你住在這個村子裡嗎?」(因為我們已經假設問的是當地村民,所以這個提問必然是恆真的。)

問題二
另一個常見的問題是這樣的:「你在一條岔路上,遇到一位路人。這條岔路的一邊通往老實村,另一邊則通往說謊村;而這個路人,可能是老實村的村民,也可能是說謊村的村民。現在你只能問這位路人一句話,就必須決定岔路的哪一邊通往老實村。你該如何提問呢?」

這個問題的關鍵,其實是在問一句話,指涉到特定的一條路,讓老實村的人與說謊村的人,都會回答「是」。也就是說,對老實村的人而言,這句話是真的;而對說謊村的人來說,它卻是假的。例如,問「你從這條路回家嗎?」、「這條路通往你住的村子嗎?」。於是,我們(對於路人的回答)有如下的真值表:


而當我們聽到回答為「是」時,即表示所指的路通往老實村;聽到回答為「否」時,則表示此路通往說謊村。

星期四, 8月 18, 2005

Ackermann's function

我對 Ackermann's function (艾克曼函數)一直有著強烈的崇敬感。

讓我們先從兩個簡單的函數看起。如果 f(n) = nn,那麼 f(0) = 1, f(1) = 1, f(2) = 22, f(3) = 33, ..., 它增長的速率是相當快的(也就是說,f(n+1) 會比 f(n) 的值要大上大頗多)。而如果 g(n) = nn...n(共有 n 項),我們應該會對 g(n) 的增長速率感到些許敬畏、感到有些「遙不可及」。

可以想像,應該會有增長速率更快的函數。例如,Knuth 就曾提出一種 big-number(很大的數目)的表示法(注意到,這套表示法會用到無限多個(^, ^^, ^^^, ... )運算子;而且這些運算子都是右結合(right associative)的,例如 234 = 2(34) = 281):
m ^ n = m m ... m (n 項) = m n
m^^n = m^m^...^m (n 項) = mm...m
m^^^n = m^^m^^...^^m (n 項)

Ackermann's function 的定義很簡單:

它簡單到用程式實作,幾乎只要照著定義抄就可以了。例如,以下就是一個用 PHP 實作的程式,它可以算出 A(3, 6) = 509:
<?php
function A($m, $n) {
  if ($m == 0) return ($n + 1);
  else {
    if ($n == 0) return A($m-1, 1);
    else return A($m-1, A($m, $n-1));
  }
}
print "A(3, 6) = " . A(3, 6);
?>

令人驚訝的是,Ackermann's function 增長的速度非常快。現在的電腦威力已經很強了,但是要計算 A(4, 2) --- 更不用說是計算 A(5, 1) 了 --- 都還是會出現 Stack Overflow 或者 Out Of Memory 的錯誤訊息。事實上,Ackermann's function 增長的速度,比 m^nm^^n、甚至 m^^^n 都還要快。在數學上,它是一個 total recursive(全然迴歸:對於每個自然數 m, n,A(m, n) 都有定義)的函數,但是卻不是一個 primitive recursive(基本迴歸)函數。它增長的速度,遠超過一般人所能想像。

這也沒什麼嘛,數學的世界裡,本來就有許多令人驚詫的函數或定理,不是嗎?

是這樣的。十餘年前修習數理邏輯時,老師把「證明 Ackermann's function 非 primitive recursive」當成作業給學生做。那位老師 (Dr. Kueker) 很有趣,習題做錯後,他會點出錯誤所在(有時還會給一點提示),然後學生可以在學期內任何時刻再補交(如果還是做錯,可以下回再繼續補交)。重點是,這題我「證明」了三次,但每次都是錯的。一直到學期末,我想破了頭,都沒有證明出來。

也因為曾經努力數個月卻還是失敗,我對 Ackermann's function 一直有著頗為複雜的情感。有時,我會覺得:人就是這樣,對於盡力後依然失敗的情事,日後反而會留下最深刻的印象。

星期三, 8月 17, 2005

執著是苦

放得下的人,身無長物。

今天到公司整理自己的位子,才發現自己的東西實在太多。數十本技術書籍,疊起來厚厚高高的各式文件,再加上逾百片的各類光碟,越整理越覺得沈重。

很明顯,雖然似乎讀得懂許多教人放開心胸、安身立命的書籍,但我還是個不怎麼放得開的人。幾天前,還有同事說,我對許多事情太過於執著。要明瞭:「執著是苦」啊。

星期二, 8月 16, 2005

團隊解散

公司無預警告知,決定結束目前正在進行的專案。

這表示,我接下來的一陣子沒有什麼重要的事情要做了(說真的,是有些措手不及)。也表示,讓自己和開發團隊互道珍重的時刻就要到了。

五年間,先後加入兩間新創公司。前一間公司在三年前關閉,而這一間公司目前也是經營得辛苦。我想,創業維艱啊。而或許也是因為年輕時包袱少,所以才不願進入政府官僚體系、才想到廣闊的業界闖天下吧?

而這幾年的工作,回顧起來,用到所學的多,但是額外的收穫卻少。只有這半年多,讓我感受到團隊的樣貌與價值。

也不是說過去就沒有分工合作,而只是總覺得彼此間,缺乏強烈的信任感與明確的方向。因此,雖然多少彼此還是有互相幫忙,但就是缺乏整體的步調與和諧的溝通,很容易在開發的前後期,產生認知上的不一致。

這半年來,嘗試用軟體工程的方式,構建一個軟體開發的團隊。從建立成員間的互信、專案的規劃、到產品的需求與規格、軟體架構的設計、程式的實作、以及系統的測試與除錯,我們都嘗試讓成員儘量發揮他們的所長、嘗試讓時程的溝通與掌握能夠貫徹。從一些成員的回饋,與幾位專案外的產品經理的談話中,我了解到,這樣「有系統的開發方式」,對專案來說,是很有幫助的。

很可惜,專案還是在未完成前,就要劃下句點了。現實生活中,不如意之事總佔了多數,令人嘆息。

星期一, 8月 15, 2005

再談迷宮


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

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

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

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

我不知道。

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

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

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

星期六, 8月 13, 2005

迷宮


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

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

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

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

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

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

星期五, 8月 12, 2005

跟著感覺走

這兩天,因為接下來做些什麼好而煩惱。

一方面,明年就要 40 歲了,有股衝動:想嘗試做些自己很久以來就想做的事情(如果沒有在現在就嘗試,以後就會更難)。另一方面,這個年頭一般人似乎總得有個「工作」,最好 還是個「永久、持續性」的工作,大家才不會對你說東道西,指指點點。別人的想法,本來是不需要太在意的;但被親朋好友問多了 ,仍維持好耐性來委婉辯駁解釋,卻不是「一塊蛋糕」(piece of cake) 般地容易。

在這半年的軟體品質改善專案裡,我倒是真的體會到,溝通是一件多麼不容易的事。溝通看起來好像很簡單,就是把訊息傳遞出去;但實際上,人一多了,訊息的傳遞與解讀,就都會產生變化。

大多數人也同意:要讓一群人都真的能夠凝聚出一股共識(對許多事情有接近一致的卻的看法),是「團隊」價值的起步。而一個團隊,不是幾個人湊合在一起,講講彼此的 R&R (Role and Responsibility),然後各自「分工」做自己的事情,就算是團隊了。它需要「合作」:團隊的成員,彼此間要有互信的基礎,然後在充分溝通瞭解 下,對於未來的遠景(隱隱看到未來工作完成的樣貌)、使命(要用何種方式來達到遠景的目標)、計畫(較為詳細、合理的規劃)、執行方式,與稽核驗證,都能 有「共同體」(成員彼此依賴頗深)的感覺,才能夠算是達到一個團隊的雛形。

然而,由於團隊成員的背景與專長不同,因此強烈的互信與共識,就會需要有效的溝通,才有機會達成。

扯遠了。不管怎樣,在現實生活裡,「成王敗寇」才是遊戲的主要規則。而我這五年在業界闖天下,只能承認是以失敗收場。因此,當然有些悲傷、有些惋惜。

而對於我目前的困惑,貓的說法是「典型的中年危機」(他還建議我去看侯文詠「我的天才夢」這本書)。他的建議是就是:跟著感覺走。

喔~記得好像是蘇芮有首歌:「跟著感覺走,讓它帶著我,希望就在不遠處等著我 ...」。在現實的生活中,要真的能夠跟著感覺走,卻似乎是件頗為奢侈的事呢。

星期四, 8月 11, 2005

我的情緒,有戲劇化的傾向

回學校找老師。

一個目的,是問問是否有 part-time job 的機會,可以讓我在明年,一邊整理出想寫的文章,一邊有個「工作」。

老師手頭,正在進行一項攸關台灣學術研究競爭力的計畫。他認為這項計畫極有其價值與意義,且剛好有一個 post-doctor 的缺額,因此建議我 take full-time job。我還是很擔心自己整理不出想要的東西呢。因此,不斷地詢問是否工作的負擔會太過沈重。

我說,我擔心因工作過重,而無法在明年達到自己所預設的目標。老師說,我有將情緒 dramatize(戲劇化)的傾向。是嗎?我因不知而感到好奇。

老師說,一個例子是,當初他建議我從研究 Theorem-Proving 轉到 Intelligent Agent 領域時,我的回答是:「已經花了這麼多時間在定理證明上,所以不該如此輕易轉移研究主題 ...」。他說,轉換 Topic 並不是什麼 big-deal,不需要如此悲壯的。

嗯,說自己 40 歲想要做些什麼,應該是有些 dramatizing 吧?然而,過了四十歲,要再找個理由來讓自己整理年輕歲月的痕跡,恐怕會更困難吧。為了不讓自己在往後的歲月後悔,似乎是應該找回自我,做些真正想做的事情的。

另一方面,家人們都希望我去找教職或研究的工作。我說,我覺得自己並不是那麼合適做研究,而或許教職是可以考慮。但現在競爭激烈,要進好學校教書也不是那麼容易啊。(事實上,我也一直沒有嘗試申請過,所以算是在逃避。)

太太說,我也不是那麼容易聽人勸的。她說,我最容易聽進去的話,多半是從貓那邊「敲邊鼓」來的建議。我想,這或許是因為貓的想法,最接近我的個性吧?

星期三, 8月 10, 2005

放下,也是另一個開始

說開了九月底就要卸下現在的工作。

除去工作上的壓力,最主要的原因,是因為自己明年就要四十歲了。40?是個年輕時很難想像的年齡呢。回顧自己這些年走過的痕跡,竟也感到茫然。

從 國中、高中時代,就開始對電腦程式感到興趣。最初,是由二舅花了幾萬元,買給大姊使用的 Commodore PET。8 位元的機器,記憶體很少,應該不到 64KB。但即使如此,我仍舊著迷於大姊用 BASIC 開發出來的一些小程式。對我而言,電腦程式蘊含了開發者解決問題的精密構思。不論是資料結構的巧妙安排、抑或是演算法的高明深刻,都深深地吸引著年輕的 我。

之後,APPLE II 開始流行。但讓自己印象最深刻的,卻是大一時玩的 Ultima IV。它讓我廢寢忘食,足足玩了一整個暑假。

大學時代,修習的是電機。然而,除卻它是第一志願外,我對電機其實並沒有什麼興趣。反而是在社團(應該是叫做計算機研究社吧)裡,找到一些志同道合、對電腦感興趣的朋友。

雖然在大一、大二時,也有計算機相關的課程,但不知是因為老師教得不夠好,還是自己不夠認真,總覺得不得其門而入。直到大三,修習 Compiler 與 Artificial Intelligence 的課程,才算是重新燃起自己對 Computer Science 興趣。

出國留學, 讀的就是 Computer Science。雖然 University of Maryland 並不算是很有名的學校,但是自己也真的學到了不少。其中,因自己對於計算理論還算頗有興趣,甚至還跑到數學系修習了數理邏輯與集合論的課程。對於 Goedel 的不完備定理,尤其感到讚嘆與折服。

出了一些狀況,讓自己在 Maryland 只取得碩士學位,就回到了台灣。第一個叩門詢問的老師,就是對定理證明相當有研究的指導教授。很遺憾地,雖然自己對數學頗有興趣,但是數學基礎卻著實不 夠,因而自己最終還是轉換了主題,研究 Intelligent Agent (智慧型代理程式)與 Information Retrieval (資訊檢索)。

畢業時,剛逢 Internet Bubble 的末期。加入了一間新成立的軟體公司,兩年後卻不幸關閉。接著,我就加入現在的公司,從事 mobile Internet 上的軟體架構與產品開發。

三年又過去了。算算自己在業界,也有五年以上的經驗。這些經驗是什麼呢?一時之間,竟然也想不起有那些。比較有收穫的,似乎只有這半年來,在公司所進行的 一個軟體品質改善專案。我覺得,自己學到了許多學校裡很難教的東西:包含軟體專案開發的團隊建構、角色職責、時程規劃與執行、以及「你給他人越多,自己學 到的就越多」。

雖然覺得公司的軟體產品還是有價值,但現在還是選擇了離開。原因,就是自己快要 40 歲了。我希望自己在明年,能夠整理出一些這些年的感想與心得,一些自己曾感興趣的演算法或電腦程式,寫些短文,算是對逝去青春的一些省思與留念。

但久沒寫作,雖然已經有了幾個主題,竟然連第一段文章也寫不出來呢。看來,自己還是得多練習、多督促自己,才有可能完成吧。