從千層酥到 iPod(送書活動來啦)

演算法與數學之美發表於2018-09-20
從千層酥到 iPod

我幾乎可以確定,我是不會去爬珠穆朗瑪峰的,雖然我會樂觀地保留一點兒能瞬間移動到那裡的可能性。我也幾乎可以確定,我不會去南極。我不認識任何一個攀登過珠穆朗瑪峰的人,但我確實認識一位在南極工作的天體物理學家。我知道到達南極是非常困難的,即使是坐飛機也很困難,但南極和我們之間的距離仍然是有限的。我也知道珠穆朗瑪峰的高度是有限的。但是,它們對我來說就像無窮遠或無窮高一樣,因為我永遠也不會去那些地方。

 

無窮是存在的,但是我們能到達那裡嗎?如果要做的工作無窮小的話,我們是否能做無窮多的工作?在我們搞清楚這些問題之前,讓我們先考慮一些看起來非常大,似乎要接近無窮的事物,以及一些看起來我們幾乎是在做著無窮的工作的情況。

 

有一個關於在國際象棋棋盤上放米粒的古老難題。這個難題的背景是這樣的:一個人被要求在國際象棋棋盤的第一個方格里放上一粒米,在第二個方格里放上數量翻一番的米,在第三個方格里,米粒數量再翻一番,以此類推,直到棋盤上的每一個方格都被放滿,一旦他完成這項工作,他將得到整張棋盤上的米。問題是,最終他能得到多少粒米?簡化版的答案是,非常多。但是準確地說,到底一共有多少粒米呢? 

 

原則上講,這不是一個困難的問題。你只要不斷乘以2,然後將所有得到的答案加在一起,直到你計算完所有的64 個方格就可以了。然而,如果你嘗試這麼做,你會發現數字增大的速度快得驚人。在正常情況下,這個數字會比你的計算器甚至普通模式下的計算機所能處理的最大的數字還要大。除非你有一些特殊的計算工具,否則你是無法算出這個數字的。有一些竅門可以幫助你加快計算,但是你最終還是需要處理一個非常非常大的數字——18446744073709551615 粒米。

 

當然,我們通常不會以粒來計量米,除非在聽起來有點兒荒謬的數學問題裡。(我第一次在數學課堂裡聽到這個問題時,曾經試圖通過手工計算來得出答案。事實證明,我算錯了。)那麼上面那個米粒的數量在實際情況中相當於多少米呢?我們僅需要稱量出1克重的 米,然後數出粒數——1 克米大概有50 粒左右——然後我們就可以近似地進行下面的計算:


1克 = 50 粒米

1碗  = 100 克 = 5000 粒米

1人  = 每天 4碗米 = 20000 粒米

全世界  = 70 億人 = 140000000000000 粒米

1年  = 大約 500 天 = 70000000000000000 粒米



我們最後得到的數字有16 個零。我們曾經計算出的米粒數量為 18446744073709551615,近似於在2 後邊有19 個零。這個數字比我們算出來的夠全世界所有人吃一年的米多出來3 個零,換言之,大約是其1000 倍。所以這麼看起來,這些米可以養活全世界人口大約 1000 年。(當然在這裡我們沒有考慮到的真實情況是,世界人口每年都會增長很多。)

 

我的計算是非常粗略的,但是我相信你能明白我的意思:只不過是在一個棋盤上移動,做著一些平淡無奇的數量翻倍,但是很快,你就擁有了無法計量的米粒——比世界上現有的所有的米還多。

 

千層酥


千層酥的製作依賴相同的原理,即重複做乘法使事物以極快的速度增長。千層酥裡具有驚人數量的薄層,它們是通過將麵糰折三折這個步驟重複6 次製成的。第一步,把一層厚厚的黃油夾在麵糰中間。當黃油的用量剛剛好時,黃油可以在你擀麵團時恰好平鋪在夾層裡。第二步,將麵餅折三折,然後冷卻。這樣所有層都會保持一定的硬度,而不會和其他層粘在一起。第三步,再一次擀麵,將麵餅再次折三折,然後冷卻。如此操作6 次。重複“×3”使得層數增長得非常快。接下來,當你烘烤千層麵團時,薄薄的黃油層融化了,黃油的液體部分蒸發併產生蒸汽,這將層與層相互推離。因此除了抽象數字的增長以外,你還能看到千層麵團在烤盤中有形地變大。

 

這是我最喜歡的關於指數增長的實物演示。一般情況下,人們說事物正在呈指數型增長,僅僅是想表達它們增長了很多。這基本上是正確的,但其正式的數學定義是事物一直以相同比例的速率增長。如果我在第一次將麵糰折三折,第二次折四折,第三次折五折,第四次折六折,這樣層數會增長得更快,但它就不是指數型增長了,因為增長的速率發生了變化。

 

我喜歡指數增長能夠直接對應於美味的千層酥這個事實。千層酥的多層次不僅僅是為了引人注意和美觀。當薄薄的一層層酥皮在口中融化的時候,它能夠帶來精妙的口感。千層酥以難以製作聞名,但是我認為使用指數增長的天才方法重複折三折的步驟,實際上大大降低了製作那些千層酥薄層的難度。畢竟,單獨擀出這樣的薄層是非常困難的。數學的主旨就是將複雜的事物變得簡單一些。不幸的是,不知怎麼,它反而往往會創造出莫名其妙的複雜問題。

 

iPod


我記得當iPod(蘋果公司釋出的行動式數字多媒體播放器)剛剛問世的時候,我在地鐵上看見了它大大的廣告標語——“240 首歌曲,100 萬種不同的方式”。這個廣告的核心理念是希望讓人們記住一件事,那就是就算只有240 首歌曲,如果你不是在播放列表中從頭播到尾而是用隨機的順序來播放它們,那麼你將有100 萬種不同的播放方式。 

 

事實上,100 萬是一個極大的低估。出於好玩的目的,我坐在火車上計算了一下為了獲得 100 萬種不同的播放方式,你最少需要多少首歌。

 

如果你有兩種歌,那麼你只有兩種播放它們的方式:從一首開始然後播放另一首,或者反過來。假設你有三首歌。對於第一首歌,你有三首歌可供選擇;對於第二首歌,你只有剩下的兩首歌可供選擇;對於第三首歌你將不再有選擇。(這裡有一個前提假設是一首歌你只想聽一次,雖然在現實中我經常重複播放同一首歌曲幾個小時。)我們要再畫一張樹狀圖。與之前不同的是,這一次每一層的枝杈會越來越少,因為你不想重複播放,所以我們可供選擇的歌曲數量就會越來越少(見圖 11–1)。

640?wx_fmt=png

 

所以在這裡我們有6 種可能的播放順序,從樹的最上層到最下層的每一條路徑都代表了一種播放順序。根據每一級可供選擇的路徑的 數量,我們可以把可能的播放順序總數計算為 3×2×1。 現在假設我們有 4 首歌,我們會得到圖 11–2 這個樹狀圖:

640?wx_fmt=png


或者通過下面的方式計算:


第一首歌有 4 種可能性,

第二首歌有 3 種可能性,

第三首歌有 2 種可能性,

最後一首歌有 1 種可能性。


我們可以計算出,總的可能性的數量為4×3×2×1。(事實上我們並不需要在最後寫上 1,因為乘以 1 並不會改變任何事。)

 

這在數學中被稱為階乘。“4 的階乘”寫為“4!”。一般來說,n的階乘為:


n×(n – 1)×(n – 2)×…×4×3×2×1


我們也可以用歸納法來定義這個概念。這看起來有點兒像我那個“你好”小程式裡面的迴圈: 


1! = 1

n + 1)! =(n + 1)×n!


所以,如果我們有 n 首歌,可能的播放順序總數就是n!。因為第一首歌我們有 n 個選項,第二首歌有 n – 1 個選項,第三首歌有 n – 2 個選項,以此類推,倒數第二首歌有 2 個選項,最後一首歌只有 1 個選項。 

 

現在,我們可以回到最初的那個問題:為了獲得100 萬種不同的播放方式,你至少需要多少首歌?以數學的方式來說,這意味著我們要尋找一個最小的n 值,並使這個n!大於100 萬。我們可以依次寫出階乘的值,直到我們找到這個數字。記住,從一行到下一行計算下 去的時候,我們只需要用這一行的結果乘以下一個 n 的值:


1! = 1 

2! = 2

3! = 3×2 = 6

4! = 4×6 = 24

5! = 5×24 = 120

6! = 6×120 = 720

7! = 7×720 = 5040

8! = 8×5040 = 40320

9! = 9×40320 = 362880

10!= 10×362880 = 3628880

 

好極了,我們已經突破了100 萬!我們只需要10 首歌曲,就能用超過 300 萬種順序播放它們了。

 

我們現在可以問另一個問題了。如果有240 首歌,我們能有多少種播放它們的方式?我們需要做如下的計算:


240×239×238×…×3×2×1

 

如果不使用特殊工具,這個計算幾乎是不可能實現的。因為這個數字會變得非常非常大。簡單地使用普通計算機電子表格嘗試了一下 之後,我發現在採取近似之前它只能計算到 17!。於是我們得到:


17! = 355687428096000


我高興地發現我的手機計算器能計算得更多:


18! = 6402373705728000


我的手機計算器可以用近似的方法計算接下來的階乘,但是它最多隻能告訴我:


103! ≈ 9.9×10163


之後就完全沒指望了。如果再進行更大資料的計算,它只會提示我出現錯誤。如果採用近似計算的話,我的計算機電子表格能一直算到 170!:


170! ≈ 7.3×10306


接下來它也沒指望了。這是因為我的舊而脆弱的計算機是使用記憶體來儲存大的資料的,而171! 是它碰到的第一個因為太大而無法處理的階乘。 

 

計算統計學家裡克·維克林(Rick Wicklin)編寫了一個計算大數 階乘的程式。他最近恰好在他的部落格裡公佈了200! 的數值。他解決大數字儲存問題的方式是讓計算機把大的數字當作一個長長的字串來處理。然後他讓計算機像人類手算一樣進行乘法計算,一位一位地做並且在需要的時候進位。他計算200! 得到的答案就是下面這串超乎尋常的數字:


7886578673647905035523632139321850622951359776871732 6329474253324435944996340334292030428401198462390417 7212138919638830257642790242637105061926624952829931 1134628572707633172373969889439224456214516642402540 3329186413122742829485327752424240757390324032125740 5579568660226031904170324062351700858796178922222789

6237038973747200000000000000000000000000000000000000 00000000000

 

我相信這是我見過的最大的數字。它有375 位數字,比廣告中描述的“100 萬種方式”要大非常、非常、非常多個數量級。而事實上,這還不是 240!。

 

在擺弄這些大到荒謬的數字時,我還想看看,你的iPod 裡需要有多少首歌才能讓它們的播放方式多於那個棋盤上的米粒。答案是,21。這就告訴我們,翻倍數字能使它們變大得非常快,而階乘能讓它們變大得更快。

 

你也許想知道在那個數字的末尾有那麼多0 是否是一個奇怪的巧合。事實上,上面那個數一共有49 個 0。大數的階乘 結果註定會在末尾有大量的0,即使不知道階乘的答案,我們 也能算出它的末尾會有多少個0。最終答案中的每一個0 都來自一個因子10,而每一個10 都來自階乘數字中的一個因子2 和一個因子5。由於存在的因子2 要比因子5 多,因此我們只 需要數出從1到我們所計算階乘的數字之間有多少個5的倍數。 記住,有些數字具有多個因子 5,因此會貢獻多個 0。

 

你長得有多快?


小時候,孩子們會長得非常快。因為他們實在是太小了,所以看起來會比實際長得更快一些。假設一個孩子在最初的幾年裡一年大約長高10 釐米,對於一個嬰兒來說,這個增長量顯得非常大,因為10釐米佔嬰兒總長的比例很大。當然,孩子們的生長速度是不同的。有些孩子在小時候比較矮,但是未來某段時期會出現一個急劇的增長,並開始超越周圍的所有人。

 

在數學中,我們也會考慮事物增長得多快,是否有些事物會比其他事物增長得更快這些問題。例如,在米粒的例子裡,我們用2n 來表示數量,這裡n 是穩定增大的。在歌曲播放的事例中,我們用n! 來表示數量,這裡 n 是穩定增大的。在這兩種情況下,數字都會非常快地增長到難以置信的大小,雖然它們仍然是有限的。在數學上,我們說“當n 趨於無窮時,2n 趨於無窮”。在這裡,我們非常謹慎地避 免了直接宣稱某些事物“是”無窮的。同樣,當n 趨於無窮時,階 乘n!也趨於無窮。但是我們會感覺到n!比2n 增長得“更快”一些。這又是什麼意思呢?

 

搞清楚這件事的一個方式就是把二者構建成一個分數:

640?wx_fmt=png 

從這個分數中,我們可以觀察隨著n 的增加誰會“贏”得比賽。 如果分數數值持續變大,就意味著n!勝利了。如果分數數值持續變小,那麼2n 就勝利了。如果分數保持不變,就表示這是個平局。現在我們可以再次耍一個小聰明,將這個分數寫成:


640?wx_fmt=png


接下來,我們可以像這樣將它分解成一個個單獨的分數相乘:


640?wx_fmt=png


現在,我們可以看出這是一大堆分數的乘積,它們幾乎都是頭重腳輕的。除了最末尾的。此外,隨著n 越來越大,分數的乘積逐漸包含越來越多的項,同時新項將會比之前的項更為頭重腳輕,因為其頂部的分子將越來越大,而底部的分母則始終是 2。最終的結果就是頂部明顯勝過底部。

 

事物趨於無窮的速度是有一個等級的。這與我們之前所說的無窮的層級有一些不同,但都是基於相似的想法建立的。 我們剛剛看到,n!增長得比640?wx_fmt=png快,而640?wx_fmt=png又比n^2 增長得快。事實上,640?wx_fmt=png比n^3、 n^4 或n的任何次冪,甚至640?wx_fmt=png增長得都要快。 最後一個數看起來很大,而且除了n = 1 以外,在開始階段它確實比640?wx_fmt=png要大。但是640?wx_fmt=png最終會超越它。我們來試一個稍微不那麼誇張的數, 比如640?wx_fmt=png。我的計算機告訴我,640?wx_fmt=png會一直領先640?wx_fmt=png直到 n = 125。之後,640?wx_fmt=png就領先了。

 

在這裡,我們只考慮n 的正數次冪。因為負數次冪通常根本不會帶來增長。隨著 n 的增大,n 的負數次冪通常越來越小。

 

有個東西比所有可能的n 的冪都要增長得慢,那就是log n。你 也許還記得,對數是與指數相反的。如果我們以10 為底來做對數, 那麼log n就是“將10增大到n所需要的指數”。所以log 100就是2, 因為你計算10 的 2 次冪就能得到100。而log 1000 就是3。然後100 到 1000 之間任意數的對數都位於 2 和 3 之間。以 10 為底數取對數基 本上就是在計算一個數在以10 為基數的情況下包含多少位數字。所以當n 增大時,log n 也會持續增大,但其增大的速度很慢。當n 已 經增大到 100 萬時,log n 才僅僅增大到 6。

 

這就是對數有用的一個原因。它可以將大數字轉換成小數字,這樣我們就能較方便地處理這些數字了。有這樣一個理論,當數字增大到超過某個特定點的時候,我們的大腦就無法真正處理這個數字了。所以我們轉而使用對數的方式思考,觀察這個數有多少位而不是看它有多大。你可能也會這麼做,即使你沒有意識到你是在“取對數”。 這就是為什麼在之前的例子裡我會告訴你200!所得到的數字有375 位,因為 375 是一個我們能處理的數字。換言之,我剛剛從對數的角度對這個數字進行了轉換。當一個數字大到這個程度時,與數字的數量級相比,你基本上已經不會在乎在這個數的某一位上加上或者減去 一個 1 了。這就是為什麼在米粒的例子中我如此隨意地假設一年中有 500 天。我知道相對於這個事件的巨集偉性,500 與 365 之間並沒有什麼重要的區別,我真正需要做的就是選擇一個與365 具有相同位數的數字。這裡,我就使用對數的方式進行了思考。 

 

總而言之,對數比 n 的任意確定的冪都要增長得慢。

 

慢速增長


有可能你增長得非常緩慢,以至於雖然你還在增長但是已經看不出來了。想象一下你正在節食,你決定只吃一塊蛋糕的640?wx_fmt=png。但是蛋糕太美味了,你決定再吃這塊蛋糕的640?wx_fmt=png。接下來,由於你像我一樣控制 不住地想要更多但是又真的不想變胖,所以你決定再多吃一點點,但是這次只吃這塊蛋糕的640?wx_fmt=png。接下來640?wx_fmt=png,再接下來640?wx_fmt=png,一直繼續下去。最終你將吃下多少蛋糕呢?經過一段時間之後,你每次吃的蛋糕將基本上不存在了。因為在100 萬輪之後,你只能再吃這塊蛋糕的百萬分之一,這基本上就等於什麼都沒吃,對吧?

 

錯了。如果你持續這樣吃下去直到永遠,你最終將會吃下無窮量的蛋糕。事實上,你吃的蛋糕量是呈對數增長的。它的增長速度確實很慢,而且會越來越慢,但仍會不可阻擋地趨於無窮(見圖 11–3)。


640?wx_fmt=png

圖 11–3

 

從圖11–3 中你可能無法判斷這個曲線最終是否會完全變平,但我來告訴你,它真的不會。這個曲線是無邊界的,這表示無論你想到哪個數字,最終它都會超過那個數字。無論你想要它變成多大,最終它都會變得比你預想得更大。我們將在第 16 章解釋這個問題。

 

這個例子說明,我們在思考無窮的增長的時候,真的要非常小心。因為我們的直覺極有可能導致我們誤入歧途。一塊蛋糕是微不足道的,但如果我們想要吃到的是無窮量的蛋糕呢?這就是我們需要依賴數學的精密性來搞清楚這些明顯令人困惑的矛盾,並且確定我們能否吃到無窮量蛋糕的原因。

640?wx_fmt=gif


粉絲福利

送書!


640?wx_fmt=png 

《超越無窮大:一次跨越數學邊界的冒險之旅》

 

本書入圍英國皇家學會科學圖書獎短名單,獲得包括《魔鬼數學》作者喬丹•艾倫伯格在內的多位數學界大佬聯袂推介。


想獲得此書,

文章底部留言,

留言點贊前五名的粉絲(24小時計),

免費獲得此書!

640?wx_fmt=gif

相關文章