星期四, 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 則留言:

被掛掉的阿尼 提到...

我php比java熟得多,它可以很簡單的做一些事
但php還是有一些缺點,一是開發工具不如java(像oracle的jdevelope)外(改別人的系統, 有trace能力的工具很重要)
還有他不容易做出介面跟功能分離的版本(不容易叫美工人員去修一個php網頁還不會把程式搞亂)

tu 提到...

工欲善其事,必先利其器;不同的開發應用,需要不同的設計與輔助工具。要做比較龐大的工作,使用專門的開發工具,應該還是比較合適吧。

只是,「割雞不需用牛刀」,對許多應用而言,腳本語言 (scripting languages) 或許就足夠了。

或者,可以換個角度說,大半的網頁應用,PHP 也許就可勝任,並不需要太過複雜龐大的開發工具組。

當然,有時也頗懷疑,為什麼 PHP 的整合開發工具(Zend 有出 IDE)似乎乏人問津。

至於介面與功能分離的版本,還是要看使用者怎麼設計實作吧。常看見有好(設計上介面功能盡量被分離)工具,卻被濫用的。

被掛掉的阿尼 提到...

被濫用的問題, 常常是後續的跟隨者只知道規格, 卻不了解原來的用意. 有些時候, 大架構做得太偉大了, 根本沒幾個人懂, 但一堆人又必須出書教課的....
例如上次去恆逸, 老師講的xml跟hl7, 都想忍不住吐他. 還有, serverlet(剛好是介面與功能分離的目的), 大多我總是邊看邊罵. 但我還是得看, 因為java我也不是很熟....

mph 提到...

小聲地說:從C之後就沒學好過什麼語言了,所以這兩種都不會。

tu 提到...

這個年頭,「不會」其實是「很正常」的。誰知道現在會的東西,幾十年後,又會有什麼留存下來呢?

我總覺得,程式語言算是工具,所以不該弄得太複雜。在目的上,程式語言或可看作是為了「實作系統」-- 說得好聽些,是為了服務社會(或者說得實際些,是為了賺錢啦)。而若是為了「追求理想」,則似乎該多問問自己「那些理想是否真的符合人類天性」。

當然啦,那些設計大架構的人可能會說,沒有大架構無法成事。但大架構沒有好的跟隨者(像是阿尼說的例子),結果可能怨聲載道,反而壞事呢。在實際生活裡,在適當的時機、有適當的成熟度,應該是困難、但值得去追尋的吧?

因此,不是說 Java 不好,而只是覺得它真的越弄越龐大複雜了(或許 Java 狂熱份子是想把它弄成一統江湖的 PL/2,加上無所不在的 patterns 吧 :p)。PHP 目前在許多地方的確也是捉襟見肘、不甚方便,但對於一般的網際網路應用程式來說,或許也大致足夠了吧。

mph 提到...

http://www.joelonsoftware.com/items/2005/10/21.html
因為這種人好像不用呼吸空氣就能活著,所以叫架構太空人,呵呵呵。

mph 提到...

其實很想趁這陣子學個新語言說,不過看到東西一堆就怕了。

要說腳本語言,Basic不是也很好嗎?PHP究竟比Basic多了什麼?

tu 提到...

PHP 與 Basic(或者說,M$ 的 VBScript 好了)相比,好處至少有:
(1). OpenSource、且「跨平台」(在 Linux、Windows、MacOS 等等作業系統上,都有支援)、且「有很多人用」:p
(2). 很容易裝在 Apache Web server 上;支援 Web technologies 的程度也比較高。
(3). 預設就含有很多有用的延伸套件。例如,幾種常用資料庫的支援套件、gd2 套件(支援影像與繪圖)、tidy 套件(可將 HTML 轉為 XML)、zip 套件等。
(4). PHP 陣列很好用。使用上,它可被視為「一般陣列」、「連結陣列」(linked list) 或「雜湊陣列」(hash array)。此外,PHP 提供相當多「好用」的內建函式(例如,陣列排序、兩個陣列合併、從陣列中用亂數取出一個元素等等)。
(5). 支援 Regular Expression (VBSceript 也有支援),很好用。
(6). PHP 4.x 之後,有支援一些物件導向 (object-oriented) 的概念。
(7). PHP 5 有支援 try...catch 的錯誤處理機制。
(8). 語法跟 C 很像(如果這也算是「好處」的話...)

mph 提到...

語法跟 C 很像?這對我來說就是莫大的好處囉。C++不是就這樣子把C推下去的嗎?

tu 提到...

印象中,有人是說,PHP 是 C 與 Perl 的混種語言(如果不看物件導向支援的話)。

語法和 C 很像,也就算了。看看它的許多 IO 函式:fopen(), fgets(), printf(), sprintf(), strlen(), strpos()... 連名字都和 C 的函式名稱一個樣呢。