如何通俗地解釋圖靈停機(jī)問題?

昨天小編一如既往地在刷知乎,忽然刷到一個(gè)問題:
有哪些悖論一下子就吸引了你?
悖論嘛,大家都知道的,就是無解的問題嘛,于是小編作為“好奇心少年”果斷點(diǎn)開了那個(gè)問題。
果然不出所料,第一個(gè)悖論就深深地吸引了我——色盲悖論。
這個(gè)悖論主要講述的是:假如一個(gè)人屬于色盲,無法分出藍(lán)色和綠色,別人眼中的“藍(lán)天”他看起來是“綠色”的,別人眼中的“綠色”草原,他看起來是“藍(lán)色”草原,但是他和別人的叫法卻都相同,依舊喊他們各自為“藍(lán)天”和“綠草”,那么你是如何確定你不是這個(gè)人呢??
看完這個(gè)悖論,我對(duì)自己深深地產(chǎn)生了懷疑??!

繼續(xù)往下看,小編發(fā)現(xiàn)里面竟然還有一個(gè)悖論是羅素悖論!?。?/strong>

眾所周知,天才的羅素是個(gè)奇葩,他是數(shù)學(xué)出身居然憑借邏輯特長獲得了諾貝爾文學(xué)獎(jiǎng),而這個(gè)天才提出的“羅素悖論”更是被稱為“數(shù)學(xué)的一場(chǎng)嚴(yán)重危機(jī)”。
羅素悖論
注意:以下內(nèi)容過于干貨,非戰(zhàn)斗人員請(qǐng)?zhí)^直接看“理發(fā)師悖論”
羅素悖論,簡(jiǎn)單來說就是對(duì)一個(gè)集合而言,有兩種不同的類別,一種是集合的全體元素里包含有集合自己。比如集合T定義為“全體非正方形物體組成的集合”,由于T本身是一個(gè)集合,不是正方形,所以T自己也應(yīng)該作為一個(gè)元素包含在T中,這類集合叫做本身集合。另一種集合在其所有元素中不包含集合自身。這樣的集合最為常見,例如全體整數(shù)組成的集合,全體女人組成的集合等等都不允許集合自身成為元素。此類集合叫做非本身集合。

如果假定S是自身的一個(gè)元素,則根據(jù)分類規(guī)定S是一個(gè)本身集合,而剛剛說過S的定義是全體非本身集合的集合,既然S是本身集合,所以S應(yīng)該不是自身元素。這就出現(xiàn)了矛盾。這個(gè)兩難問題便是羅素悖論。
怎么樣?看完之后是不是覺得自己現(xiàn)在一頭霧水,有沒有一種大佬果然是大佬的拜服感?!

其實(shí),羅素悖論還有一個(gè)簡(jiǎn)單通俗的描述方式:理發(fā)師悖論。
理發(fā)師悖論
在一座小島上有位理發(fā)師, 有一天他做出一項(xiàng)規(guī)定: 他給島上所有不自己理發(fā)的人理發(fā),并且只給那些不給自己理發(fā)的人理發(fā)。
最初, 這個(gè)規(guī)定并沒什么問題, 后來, 隨著這個(gè)理發(fā)師自己的頭發(fā)越來越長, 他發(fā)現(xiàn)自己陷入了一個(gè)兩難的境地: 他該不該給自己理發(fā)?
如果他不為自己理發(fā),按照他自定義的規(guī)則,他屬于自己的服務(wù)客戶范圍,因此可以給自己理發(fā);
如果他選擇為自己理發(fā),同樣按照規(guī)則,他便不屬于自己的服務(wù)對(duì)象,因此他又不能給自己理發(fā)。
綜合以上兩種情況, “他為自己理發(fā)”當(dāng)且僅當(dāng)“他不為自己理發(fā)”, 這成為了一個(gè)悖論。面對(duì)這個(gè)困惑的理發(fā)師究竟應(yīng)該何去何從呢?To be or not to be, that is a question!
羅素悖論在很多領(lǐng)域有都普遍存在, 在計(jì)算機(jī)領(lǐng)域就有一個(gè)非常出名的例子——圖靈停機(jī)問題。
圖靈停機(jī)問題
寫過程序的人一定知道一種痛苦,就是程序?qū)懞瞄_始運(yùn)行后等了半天毫無反應(yīng),既沒有報(bào)錯(cuò),又沒有停止,讓人不知所措。出現(xiàn)這種情況,一般有兩種成因。一是程序運(yùn)行的時(shí)間的確比較耗時(shí),而編程人員又忘記編制任何運(yùn)行中的動(dòng)態(tài)提示功能,導(dǎo)致機(jī)器好像毫無反應(yīng)。如果是這種情況,很好解決,只要增加運(yùn)行中的屏幕提示,比如打印某個(gè)變量的狀態(tài)或計(jì)算某種進(jìn)度即可。但另一種情況會(huì)比較麻煩,就是程序執(zhí)行陷入了死循環(huán),永不停止。如果是這樣,那么就必須跟蹤查找死循環(huán)發(fā)生的位置并修改相應(yīng)程序代碼。
因此程序員們都期望能夠有理論大牛發(fā)明一個(gè)判斷程序來提前預(yù)報(bào)死循環(huán)是否會(huì)在程序中出現(xiàn)。把一段即將運(yùn)行的代碼作為字符串序列輸入到該判斷程序中,判斷程序直接通過某種算法分析被輸入程序的結(jié)構(gòu),并給出預(yù)報(bào)結(jié)果:該程序可以或不可以在有限時(shí)間內(nèi)完成計(jì)算停止。這就是有名的停機(jī)判定問題。
這里說的有限時(shí)間是一種純理論概念,一個(gè)算法即使所需執(zhí)行時(shí)間要200億年,超過宇宙的壽命,它在理論上也被認(rèn)為是可停機(jī)的,也就是說“有限時(shí)間”無論是1秒還是100億年,只要有終止的時(shí)候就可以稱之為“在有限時(shí)間內(nèi)結(jié)束運(yùn)行”。
不失一般性, 假設(shè)我們想要測(cè)試的代碼是一個(gè)函數(shù)

其中 t 是一個(gè)字符串, 我們可以用一個(gè)字符串表示任意輸入, 包括 int, double, 及復(fù)合數(shù)據(jù)類型; 當(dāng) f 不需要輸入時(shí), t 是一個(gè)空字符串。停機(jī)問題是指對(duì)給定任意的一個(gè)函數(shù) f 和輸入 t, 判斷f對(duì)t是否會(huì)永遠(yuǎn)運(yùn)行下去; 如果程序的運(yùn)行時(shí)間是有限長的, 我們稱 f 對(duì) t 停機(jī)。
遺憾的是, 不存在這樣的一個(gè)工具使得其能判斷任意 f 的停機(jī)問題, 即停機(jī)問題不可判定。
以下我們用反證法證明這個(gè)斷言。假設(shè)存在這樣的一個(gè)函數(shù)可用于判斷停機(jī)問題:

其中 f_code 是我們要進(jìn)行測(cè)試的函數(shù) f 的 ASCII 源代碼, 我們可以認(rèn)為對(duì) f_code 進(jìn)行編譯得到了函數(shù) f。?當(dāng) f 對(duì) t 停機(jī)時(shí), halts(f_code, t) 返回 true; 當(dāng) f 對(duì) t 不停機(jī), halts(f_code, t) 返回 false。
我們構(gòu)造這樣一個(gè)函數(shù):

即當(dāng) f 對(duì) f_code 停機(jī)時(shí), 我們讓 modified_halts 不停機(jī); 當(dāng) f 對(duì) f_code 不停機(jī)時(shí), modified_code 停機(jī)。
假設(shè) modified_halts 這個(gè)函數(shù)的 ASCII 源代碼是 modified_halts_code, 如果我們把 modified_halts_code 作為 modified_halts 的輸入會(huì)是什么情況?
若modified_halts對(duì)modified_halts_code停機(jī), 說明halts(modified_halts_code, modified_halts_code)返回false, 說明modified_halts對(duì)modified_halts_code不停機(jī);
若modified_halts對(duì)modified_halts_code不停機(jī), 說明halts(modified_halts_code, modified_halts_code)返回true, 說明modified_halts對(duì)modified_halts_code停機(jī)。
綜合以上兩種情況, "modified_halts 對(duì) modified_halts_code 停機(jī)"當(dāng)且僅當(dāng) "modified_halts 對(duì) modified_halts_code 不停機(jī)", 這是一個(gè)矛盾, 說明不存在這樣一個(gè) halts 函數(shù)可用于判斷任意函數(shù)的可停機(jī)性。
以上這個(gè)證明利用的就是理發(fā)師悖論, modified_halts 函數(shù)就像是那位小島上的理發(fā)師,?他對(duì)并且只對(duì)那些不停機(jī)的函數(shù)停機(jī)。當(dāng) modified_halts 函數(shù)面對(duì)他自己的函數(shù)代碼時(shí),?就像理發(fā)師該不該給他自己剪頭發(fā)一樣, 將陷入兩難境地。

其實(shí)無論是停機(jī)問題,還是羅素悖論,亦或是理發(fā)師悖論,其本質(zhì)上都是不可解問題,都屬于數(shù)學(xué)中的內(nèi)容。而數(shù)學(xué)在程序員編程的過程里一直都扮演著極為重要的作用。
程序員的數(shù)學(xué)
網(wǎng)上有一句話說的是“稍微扯上一點(diǎn)數(shù)學(xué),現(xiàn)在的碼農(nóng)隊(duì)伍起碼縮水90%,大部分互聯(lián)網(wǎng)碼農(nóng)都是欠缺數(shù)學(xué)知識(shí)的,與其稱呼他們?yōu)榇a農(nóng),倒不如稱呼他們?yōu)椤?strong>HTML文本構(gòu)造文員’”。一個(gè)程序員想要獲得更深的行業(yè)發(fā)展,數(shù)學(xué)知識(shí)是必不可少的!畢竟編程的基礎(chǔ)是計(jì)算機(jī)科學(xué),計(jì)算機(jī)科學(xué)的基礎(chǔ)是數(shù)學(xué)。
最近比較火的AI/深度學(xué)習(xí)的編程,如果沒有比較好的數(shù)學(xué)基礎(chǔ),你連理解什么是神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)都會(huì)有困難,更不要提如何去理解神經(jīng)網(wǎng)絡(luò)的優(yōu)化等等問題了。因?yàn)槟銢]有搞懂編程背后的數(shù)學(xué)底層邏輯,也就看不透問題背后的本質(zhì)結(jié)構(gòu)。
智力從來不是最重要的因素,思維才是。在一般的編程中,程序員通常不需要掌握很深?yuàn)W的數(shù)學(xué)知識(shí)。但每一個(gè)程序員都要有此覺悟:我們是溝通人類世界和機(jī)器世界的翻譯者,每一個(gè)問題,每一個(gè)需求的到來,最初的解決思路就是化繁為簡(jiǎn),化不規(guī)則為規(guī)律,這樣我們才能將人類世界的問題轉(zhuǎn)換為機(jī)器世界能夠理解和解決的問題,認(rèn)清并簡(jiǎn)化問題結(jié)構(gòu),總結(jié)出具有一致性的規(guī)則等,透過現(xiàn)象看本質(zhì)才是程序員真正的立身之本。
當(dāng)然小編給你們介紹這些也不是讓大家每個(gè)人都去再學(xué)習(xí)線性代數(shù)和微積分,數(shù)學(xué)的學(xué)習(xí)畢竟是一個(gè)循序漸進(jìn)的過程,誰都不可能一口氣吃個(gè)大胖子,但如果你想要補(bǔ)齊數(shù)學(xué)思維,那么建議大家可以先從《程序員的數(shù)學(xué)(第2版)》這本書開始學(xué)習(xí)。

本書適應(yīng)人群:
適合想要好好惡補(bǔ)數(shù)學(xué)思維的伙伴們
適合想要在程序員行業(yè)長久發(fā)展的程序汪們
如果你對(duì)數(shù)學(xué)和邏輯感興趣,那么你會(huì)更喜歡這本書
如果你有一些編程經(jīng)驗(yàn),那么書本中的內(nèi)容將會(huì)更加易于理解
另外,這本書的作者是結(jié)城浩,作為日本知名技術(shù)作家和程序員,他在編程語言、設(shè)計(jì)模式、數(shù)學(xué)和加密技術(shù)等領(lǐng)域編寫了很多受歡迎的入門書,除了《程序員的數(shù)學(xué)》以外,他還有《數(shù)學(xué)女孩》系列、《圖解密碼技術(shù)》等圖書。
讀過結(jié)城浩大佬作品的人都知道,結(jié)城浩大佬尤其擅長利用以小見大的手法,用風(fēng)趣的數(shù)學(xué)小題,闡述著自己的觀點(diǎn),同時(shí)將程序背后的數(shù)學(xué)思維一一剖析,圖文直觀,通俗易懂!
最后借用書中的一段話,作為本文的結(jié)尾:
不要覺得“不擅長數(shù)學(xué)”就漠然處之,而要想到“數(shù)學(xué)妙趣橫生,要多加運(yùn)用”,給每天的編程都注入數(shù)學(xué)的思維方式,這樣才能高效地達(dá)到能力提升。
(掃碼,預(yù)約課程哦)

你還聽說過哪些有趣的悖論呢?
評(píng)論區(qū)說一下,大家一起了解討論下吧

