星期一, 7月 31, 2006

從「先苦後樂」談起

仔細想想世間事,還真讓人不明白。

本來對「先苦後樂」這句話並沒有想太多。但今天早上在丹堤閱讀「學習,就是一種享受」,看到作者把「先苦後樂」視為錯誤的神話,卻突然有些話想說。


「現在努力工作,不久之後就會有獎賞」、「你只要把家庭作業做完,就可以出去玩」。在我們的求學過程以及之後的生涯裡,諸如此類的命令與信仰一直影響著我們。因此,退休之後的那幾年,才是一個人的「黃金時期」...


記不記得,童話故事裡,在草地裡唧唧吟唱整個夏天的蚱蜢最後被餓死;而在塵封穀倉裡辛勤工作的螞蟻卻得到回報?從前的年代裡,似乎將「先苦後樂」視為理所當然。但是,如果年老體衰後才退休、而退休後才是一個人的黃金時期,那樂趣又在那兒呢?

曾經寫下一篇 Stop improving yourself and start living。算算從這篇網誌到現在,已經接近一整年了(好可怕!)。我當初想表達的,是不是就是反對一廂情願的「先苦後樂」?

大姊曾似頗感擔心地說,她的小孩好像都是把作業留到最後再做 --- 這跟我們從前先把作業趕完,然後再玩的作風完全不同。而令我咀嚼再三的,卻是她接下來的一句話:「這樣也好,免得最後累死了,也沒有輕鬆到。」

每個人都有每個人的命性,每個人也都有自己的風格。或許,認識自己,就能夠在「先苦後樂」與「莫待無花空折枝」之間微妙地拿捏,就能夠在生活中知足常樂。但這裡其實有個困難處,那就是自己實在很難認清自己!

星期四, 7月 27, 2006

PHP 的陣列

就 prototyping 而言,我相當喜歡 PHP 的陣列。

上回提到,PHP 的 array 其實是用 Hash table + Double Linked List 實作的。因此,要存取 $array[100],實際上是用 "100" 作為雜湊表 $array 的鍵值 (key),然後傳回表中所儲存的值。

所以,在實際的應用上,使用 PHP 的陣列,效能會比「一般程式語言的陣列」慢上許多(因為需要計算 hash key,有時也必須處理 hash collision 的問題)。

即使有著這麼大的效能缺陷,我還是相當喜歡 PHP 的陣列。為什麼呢?

因為,除了「一般陣列」的處理方式外,我們還可以很簡單地利用 PHP array 來實作出基本的資料結構(像是 linked list、stack、queue、tree 等等),而 PHP 也內建了許多有用的函式,可以讓我們方便地操作陣列的內容。例如,我們可以
  • 用 array_push() 與 array_pop() 來實作出堆疊 (stack) 的行為。

  • 用 array_shift() 與 array_push() 來實作簡單的佇列 (queue)。

  • 用 array_push()、array_pop()、array_shift()、array_unshift()來實作雙向佇列 (dqueue)。傳統的人工智能 (artificial intelligence) ,有許多問題相當著重於「狀態空間搜尋」(state space search);傳統的課本裡,也經常會以一些「玩具問題」 (toy problems) 來介紹這樣的解題概念。之前解傳教士與食人族的程式、解數獨的程式、解 Pentominoes的程式,都是利用狀態空間搜尋的例子。

    狀態空間的搜尋,大致上類似於樹狀結構的巡走 (tree traversal)。利用雙向佇列,可以很容易地實作出廣度優先 (breadth-first) 或深度優先 (depth-first) 搜尋。

  • 用 array_merge()、array_intersect()、array_diff() 來實作集合之間的聯集、交集、以及差集。

  • 用多重陣列實作樹狀結構 (tree)。也就是說,可以直接利用 PHP 的多重陣列來實作像是 parse tree 般的階層結構。

  • 其他還有許多「有時會顯得很方便」的內建函式,像是 sort() 可以對陣列排序,usort() 可以呼叫自己定義的另一個函式來對陣列內容排序,shuffle() 可以打亂陣列內容的順序(不必自己寫一小段程式來做洗牌的動作),array_fill()、array_pad() 與 range() 可以填滿一個陣列... 等等。
有時,我甚至會覺得,PHP array 所提供的便利性,有些接近傳統人工智能常用的語言(像是 LISP 或者 Prolog)呢。

星期一, 7月 24, 2006

從 Pentominoes 程式談起

對於一些年幼時期所玩過的益智遊戲,似乎總有著一股濃濃的情感。

Pentominoes 是一種拼圖益智遊戲,用十二片面積相等的不同拼塊,填滿一個 6x10 的長方形。下圖是一個拼好的例子:


印象中,國小時期曾經玩過這個益智遊戲,並且好像拼出兩百多個不同解。十多年前,在美國讀碩士班時,為了因應無聊的日子,曾用 Power Basic 寫過一個程式來解這個拼圖遊戲。記得當時的主機,還是 Intel 386。66M Hz 的 CPU,跑出所有 2339 組解,需要整整一天的時間。

曾幾何時,電腦硬體的進展飛速;同樣一支程式,在我現在的 1.73G Hz 的 Notebook 上執行,竟然只要 200 秒的時間。(我是有稍微改進了一些冗餘的程式迴圈,但沒有這些改進,依然可以在幾分鐘內跑完所有的解答。)

前些日子,想整理一些曾經感興趣的程式設計問題。很自然地,也想重新檢視一下這個解 Pentominoes 的程式。

溫故也該知新。回頭整理從前的東西,似乎也應檢視一下先進們的成果。用 Google 查了一下 Pentominoes,可以找到許多相關的網頁與程式。其中有一個 Gerard's Polyomino Solution Engine,竟然可以在 18~19 秒內,就跑出所有的解答!

坦白說,我當時是覺得有些氣餒。執行速度,怎麼會差這麼多呢?

前兩個月想開了些(不必要求完美 --- 即使自己的演算法或程式效能比較差,但應該也還是能藉此介紹一些有趣的東西),還是決定用 PHP 重新改寫自己的 Pentominoes 程式,順便改用 bit operations 來改善一些執行效能。很不幸地,執行後發現,竟然需要將近兩個小時的時間,才能跑出所有的解答!這當然也讓自己頗感訝異:雖然早知道 PHP 屬於 interpretive language,但... 似乎也跑得太慢了吧?

後來做了一些簡單的實驗,閱讀相關文件後,漸漸了解其實這是因為 PHP array 並不是像傳統的陣列,被配置在連續的記憶體區塊內。它是使用 hash table + double linked list 來實作的,因此執行 $array[$i],實際上並不該被解譯為「取出 $array 區塊第 $i 個項目的內容」,而是「用 $i 作為 $array 雜湊表的 hash key,然後取得相對應的值」。如此一來,執行的速度當然就會慢上許多。

幾個星期前,突然想用 Java 來實作看看,了解一下自己的程式究竟比 Gerard 的程式慢上多少。大概是自己寫程式的習慣還不錯,從 PHP 改寫為 Java,含除錯竟然只需要幾個小時的時間。初步執行的結果是,需要 57 秒的時間。

哦,只需要不到一分鐘的時間!這下子精神來了,花上一個星期左右的時間來優化實作的方式,最後終於可以在 17~18 秒內,就把 2339 組解答都找出來。

於是,允許自己得意十七秒鐘,就當作是一個星期辛苦地優化程式的犒賞吧 :p

星期四, 7月 20, 2006

一切都是從夢幻開始

「神奇寶貝樂園在台北開幕了!」

小傢伙從電視上看到廣告後,可以將這句台詞朗朗上口,可見神奇寶貝的威力無窮。我答應她,只要她連續十天的表現都是「O」(沒有亂哭鬧;不會拖延不肯去刷牙、吃飯、洗澡),就帶她去玩。

前天她達到了要求(雖然太太覺得我有放水的嫌疑;但我的目的,其實是要小傢伙學會克制自己不好的行為。她應該是有進步不少,因此我認為該實踐約定)。恰好神奇寶貝樂園推出「夜間雙人星光票」,票價便宜許多;再加上晚上氣溫較低,不必在太陽下曬得渾身冒汗,所以我們決定昨晚就帶她去玩。而小傢伙,當然一路上都非常興奮!

樂園的門口,有一隻大大的皮卡丘。主題歌曲重覆地播放,很有歡樂的氣氛。服務人員態度非常好,讓人覺得,台灣若真的要學習日本的服務精神,其實也是做得到的。

或許是因為非假日的晚上,人潮並不多。比起熱門時段,動不動就要排隊一個小時(網路留言如此說),我們可是玩得相當盡興。在三個半小時內,我們玩了三次「皮卡丘之森」、四次「神奇寶貝的刺激狩獵之旅」、三次「神奇寶貝旋轉木馬」、兩次「皮丘兄弟頑皮列車」,也看了「神奇寶貝3D電影」、被「水躍魚的滑水道冒險之旅」濺得右半身幾乎全溼。不要說小傢伙非常高興,連我都覺得票價相當值得。

下圖左方是樂園門口的巨大皮卡丘,右方是小傢伙坐在皮卡丘之森的皮卡丘上。


再來一些照片:下圖左方是星光票的票根,右方是小傢伙在狩獵之旅所獲得的神奇寶貝證書。


就像是樂園裡的某個標語:一切都是從夢幻開始。且讓我們洗滌蒙塵的童心,坐上頑皮列車、戴上 3D 眼鏡,陪小朋友一起去尋找夢幻吧!

星期二, 7月 18, 2006

永遠不夠的時間

大概是年紀到了某個階段,最近經常覺得時間過得太快。

前一陣子在網誌裡發洩了煩躁的狀況後,白天裡心情似乎逐漸恢復平和;但是,晚上卻仍會覺得某些地方不對勁。

我想了想,一個主要的原因,似乎是在於,自己想寫寫一些文章,卻越來越覺得路途遙遠(光陰短暫)而不可及。光是為了準備素材,就花去相當多的時間;而文章本身,卻怎樣也寫不出來。這是否表示,「整理一些心得、寫寫文章、甚至出本書」的目標,對自己來說是太高、太過不切實際了些?

如果確實是「不切實際」的目標,那麼我不該去追求,應該要放棄它。但是,令人困擾的是,我自己內心似乎仍然想去做,似乎仍覺得應該嘗試、似乎仍鼓勵自己勇敢地向前行。只是,為什麼「看透不切實際而放棄」,與「積極努力、一步一腳印地前行」之間的界線,感覺起來是那麼地模糊、那麼地令人困惑呢?

星期四, 7月 13, 2006

「迴紋針換到房子」的故事

CNET 有篇頗有意思的文章:「Blog 傳奇:一根迴紋針換到一棟房子」。

這是真實、卻令人難以相信的故事:在一年內,經由十四次的交易,可以讓人用一根紅色的迴紋針,換到一棟兩層樓房子。

以事後諸葛的角度,大家或許可以說,這是經由網路與大眾行銷等等的推波助瀾,才能達成這項「不可能的任務」。但令我印象深刻的,卻是在 CNET 的採訪裡,主角 MacDonald 說的一些話語。

MacDonald 說,『一開始我也很擔心,因為一說出來,大家都會覺得你瘋了』。這是現實社會對「違反社會常態」crazy idea 的反應。『於是情況類似於,你慢慢靠近游泳池,周遭的人一直喊著:跳下去,跳下去。然後你就鼓起勇氣跳下去...』,這是讓自己在勇氣不足的情況下,卻仍然能夠「走不一樣的路」的一種方式吧?

然後,MacDonald 說,『幾個月前,我有一度很擔心,覺得大概不太可能達成這個目標』、『在交易的過程中,我的確有一陣子很不確定。我不是沮喪,而是覺得有點厭倦了,我覺得自己一直付出,但卻沒什麼收穫』。這似乎是任何「走不一樣的路」的人,都必須承擔的困頓,必須面對與解決的問題?

MacDonald 還有一些話語也頗有意思:
  • 『一開始當我選擇迴紋針做為起點,這就注定了我必須很有創意才行』
  • 『你必須走出戶外,真實去面對你的交易對象』
  • 『從很小的地方開始,把目標放遠,然後就好好地玩吧』
回顧自己「希望能夠整理些什麼」的想法,顯然比這個「一根迴紋針換到一棟房子」實際許多。然而,自己卻仍深陷於能力、毅力、恆心不足的疑懼中。因此,就更佩服 MacDonald 能夠貫徹「不切實際」的想法、能夠持續以恆地達成他的目標了。

星期二, 7月 11, 2006

陪伴小傢伙的下午

今天下午在家裡帶小孩。

覺得帶三歲多的小孩,最需要的是耐性,陪小朋友玩的耐性。小傢伙一直要求我陪她玩,可是,陪她玩玩茶犬、神奇寶貝、堆堆積木、揉揉黏土後,自己很快地就覺得無聊、甚至疲倦了。

到床上小盹了半小時,醒來時竟已滿目瘡痍 -- 地上、床上堆滿了各式的玩具。(據教育部國語辭典,「滿目瘡痍」的意思是「映入眼中的都是殘破不堪的悲涼景象」,用在這裡作為誇大的比喻,應該還算合適吧?)

於是,相當佩服傳統的家庭主婦。帶小孩之外,她們竟然還能做那麼多家事,還能將家裡整理得乾乾淨淨。

在射雕英雄傳裡,郭靖曾提到他七師父常說:「看人挑擔不吃力,自己挑擔壓斷脊」。帶小孩雖不似挑擔,但道理卻也類似。要帶得好,當真不是件容易事呢。

星期六, 7月 08, 2006

煩躁

棄我去者,昨日之日不可留。亂我心者,今日之日多煩憂。

不知怎麼搞地,最近這一兩個星期,總是會覺得有些心煩。或許是天氣炎熱、或許是睡眠不足、或許是一些生活瑣事、也或許是自己「每隔一些時日就會發作的週期病」。算了算時間,距離上回發作,差不多有兩個半月(間隔好像太短了些,真糟糕)。

煩躁的原因,到底是什麼呢?我依然不確定。只是隱隱覺得好似有許多東西積壓在心裡,但卻又無法明確地指認,究竟是那些事物讓自己煩心。

因此,從這個角度來看,自己這一年來在心性與成熟度上的些許進步,其實是相當微不足道的。連自己的煩惱究竟是什麼,都不知道,怎能算有多少進步呢?

不過,自己倒是學會時時提醒自己,就算煩躁「發作」,也不該讓它擴大、不該讓它蔓延到家中的其他成員。畢竟,要克服自己內心的無明與煩憂,光靠嘴巴說是不夠的。

星期三, 7月 05, 2006

冬山河親水之旅

酷熱的盛暑。早上走過林蔭道,卻時時可以聽見悅耳的蟬聲。

經歷上回墾丁之遊後,小傢伙說她很喜歡在淺水池玩耍。我答應她,會再帶她去玩水。

而國道五號開通後,台北到宜蘭只需要不到一個小時的車程。因此,到羅東冬山河的親水公園玩玩水,來個半日或一日遊,應該是可行的。

所以,我和太太商量,應該趁著非假日的時段,帶著寶寶來趟戲水之旅。順道也走走國內最長的雪山隧道,感受一下隧道工程的艱辛與偉大。

小傢伙玩得很愉快。而自己在一旁看著、陪著她玩,心裡也是無比舒暢。好棒的感覺啊。

後記:報載雪山隧道在安全顧慮上,其實還有諸多問題。雖然自己算是提前享用到隧道工程縮短車程的便利,但我還是認為,行車人員的安全性應該比「趁早通車」來得重要。換句話說,大官們不應該為了「表面上的政績」,在尚未取得足夠安全性保證前,就倉促宣布通車。現在的政治人物,思考作為實在都令人看不下去。

星期二, 7月 04, 2006

「東山再起」

「東山再起」與「捲土重來」是同義詞嗎?

感覺起來,好像是吧。至少,我分不出它們在成語的使用上有著什麼樣的不同。然而,今早經由「公孫策說唐詩故事」的一篇解說,我才知道、才注意到它們在使用上,是有不同含意的。

「捲土重來」典故出自杜牧《題烏江亭》中,「江東子弟多才俊,捲土重來未可知」。詩人認為項羽自刎烏江,雖然悲壯(英雄氣短),但是若項羽 EQ 高些,當年能忍一時之氣,回到江東重整旗鼓,楚漢相爭鹿死誰手,還未可知。

「東山再起」指的是東晉時期,謝安接到朝廷徵召出來做官,卻始終不忘歸隱東山,因而當了一個多月的官之後,就掛印辭職了;之後,應當權的大將軍桓溫力邀,再度出來做官。這樣的故事歷程,被時人稱之為「東山再起」。

因此,公孫策特別說明,一個人失敗以後積極求勝,叫做「捲土重來」。不忮不求而由在位者力邀復出,才叫做「東山再起」。

喔,成語典故的使用,就是有著如許微妙的不同!

星期一, 7月 03, 2006

「注意力經濟」讀後感

又是一本「金玉其外,無趣其中」的企管論述書籍?

三年前在書店看到這本「注意力經濟」,就被這本書的一些外在特質所吸引。書本紙張的質感、印刷排版的舒適度、封面背頁的名人推薦、以及看起來頗有趣的書名(看到書名,很容易聯想到「注意力失焦」等因應資訊過載所產生的困擾),讓我當時毫不猶豫地將這本書買了下來。

「注意力經濟」這本書的基本觀察,其實是相當有趣的。由於資料、資訊不斷增加,且增加的速度遠超過人類基因(經由自然演化)所能適應,因此注意力就逐漸成為稀有財,而「資訊時代」也將逐漸過渡到「注意力時代」。

我同意作者們的這些觀察與推論。可是,類同於前些時日閱讀後,覺得表面上有趣,實質上深度不足的幾本書:資訊超載新消費者心理學A+的秘訣,這本「注意力經濟」的有趣內容,幾乎也只出現在第一章。閱讀到後來,越來越感覺作者們的論述似乎與「注意力經濟」沒有太大的關連。

簡單地說,有了「資訊超過人類所能負擔、人的注意力有其限制」這樣的觀察後,作者們將重點轉入「注意力管理」的問題。但既然人類天生無法處理資訊超載的問題,要「管理注意力」真是談何容易?於是,前兩個章節後,剩下來的長篇大論,建議就越來越顯得力不從心,論述也就越來越顯得牽強了。

其實,換一個角度來看,或許我不應該對這些書籍有如許多的批評。它們或許只是彰顯出,要寫一本立論有趣,內容又充實的書,是多麼困難的一件事。也或許,作者們本來就不期待它是一本怎樣的好書,而只是想藉著出版這樣的一本書,獲取社會上的注意力(名氣)與實質的回饋(金錢)呢。