遞迴函式(一):開篇
遞迴函式(二):編寫遞迴函式的思路和技巧
遞迴函式(三):歸納原理
遞迴函式(四):全函式與計算的可終止性
遞迴函式(五):遞迴集與遞迴可列舉集
遞迴函式(六):最多有多少個程式
遞迴函式(七):不動點運算元
遞迴函式(八):偏序結構
遞迴函式(九):最小不動點定理
我們聽說過,現代計算機在計算能力上是與圖靈機等價的,
什麼叫做計算能力呢?
它指的是圖靈機可計算的函式集,與現代計算機可計算的函式集是相等的。
為了簡單起見,我們不去討論圖靈機,而是從現代計算機直接說起,
設\(mathscr\)是一段程式,\(n\)是乙個正整數,
我們稱數論函式\(psi (x_1,x_2,cdots ,x_n)\)為程式\(mathscr\)所計算的\(n\)元部分函式,
如果對於相同的輸入,
要麼:(1)程式\(mathscr\)的計算可以終止,此時計算結果等於\(psi (x_1,x_2,cdots ,x_n)\)的相應函式值;
要麼:(2)程式\(mathscr\)的計算不能終止,此時\(psi (x_1,x_2,cdots ,x_n)\)無定義。
設\(f(x_1,x_2,cdots ,x_n)\)是乙個部分函式,如果存在程式\(mathscr\)可計算\(f\),則稱\(f\)是部分可計算的。
如果乙個函式,既是部分可計算的,又是全函式,則稱這個函式是可計算的。
可以證明,所有的原始遞迴函式和遞迴函式都是部分可計算的。
我們使用現代計算機進行程式設計的時候,並不是直接把程式的輸入傳給程式,
而是將程式本身以及它的輸入,傳給計算機,最後由計算機得到計算結果,
像這種接受任何程式和它的輸入作為自己的輸入,返回程式執行結果的程式,稱為通用程式。
為此,通用程式需要把輸入的程式進行編碼。
常用的編碼方法,涉及配對函式和哥德爾編碼。
為了不引入太多的複雜性,我們可以將程式的編碼理解為儲存程式的二進位制資料,
不同的程式會有不同的二進位制表示,每乙個二進位制表示可以對應一段程式(雖然可能不合法)。
哥德爾編碼做的事情就是將程式和自然數集一一對應起來。
因此,所有程式的個數是可數的,而這些程式可計算的函式個數也一定是可數的,
它們可能是全函式,也可能是部分函式。
(其中,「可數」指的是可數集,可數集是與自然數集之間存在一一對映的集合。
然而,自然數集上的函式全體並不可數,(證略
所以肯定存在程式不可計算的函式。
程式\(mathscr\)所計算的函式,我們可以記為\(psi (x_1,x_2,cdots ,x_n)\),
由此,我們可以定義通用程式\(phi \),則有,
\(phi (x_1,x_2,cdots ,x_n,y)=psi (x_1,x_2,cdots ,x_n)\)
其中,\(y\)是程式\(mathscr\)的編碼。
因為,所有的程式與自然數集一一對應,
所以,\(phi (x_1,x_2,cdots ,x_n,0),phi (x_1,x_2,cdots ,x_n,1),cdots\)
列舉了所有的\(n\)元可計算函式。
我們定義\(w_y=lbrace xin n|phi(x,y)downarrow rbrace \),
根據遞迴可列舉集的定義,每乙個\(w_y\)是乙個遞迴可列舉集,
又因為\(phi(x,0),phi(x,1),cdots \)列舉了所有的可計算函式,
所以,\(w_0,w_1,cdots \)列舉了所有的遞迴可列舉集。
因此,集合\(b\)是遞迴可列舉的,當且僅當存在\(yin n\),使得\(b=w_y\),
稱為列舉定理,這就是「列舉」的含義。
因此,我們找到了乙個非遞迴的遞迴可列舉集\(k\),
以及乙個非遞迴可列舉集\(bar\)。
任給乙個程式和乙個自然數,問該程式對這個自然數輸入的計算是否停止,
這個問題稱為停機問題。
我們可以用謂詞\(h(x,y)\)描述這個問題,
\(h(x,y)\),表示以\(y\)為**的程式對輸入\(x\)的計算最終停止。
那麼,\(h(x,y)\)是不可計算的,即,不存在乙個程式來計算\(h(x,y)\)。
我們來證明一下,假設有乙個程式可以計算\(h(x,y)\),
那麼我們就能用它來構造乙個新程式\(mathscr\),它的輸入是\(x\),
這段程式當\(h(x,x)\)為真時,計算不停止,而當\(h(x,x)\)為假時,計算停止。
程式\(mathscr\)也可以進行編碼,假設為\(y_0\),現在我們來判斷\(h(y_0,y_0)\)。
如果\(h(y_0,y_0)\)為真,意味著編碼為\(y_0\)的程式以\(y_0\)作為輸入最終停止,
即程式\(mathscr\),輸入為\(y_0\)時,最終停止,
可是根據\(mathscr\)的定義,此時\(h(x,x)=h(y_0,y_0)\)為假才會停止,矛盾。
如果\(h(y_0,y_0)\)為假,意味著編碼為\(y_0\)的程式以\(y_0\)作為引數最終不會停止,
即程式\(mathscr\),輸入為\(y_0\)時,最終不停止,
可是根據\(mathscr\)的定義,此時\(h(x,x)=h(y_0,y_0)\)為真才不會停止,矛盾。
\(h(y_0,y_0)\)不能為真也不能為假,矛盾,
因此,計算\(h(x,x)\)的程式不存在,我們也無法用它來構造程式\(mathscr\)。
可判定性問題,指的是乙個詢問真或者假的問題是否可以被回答。
如果我們總能回答出這個問題是真或者是假,就稱該問題是可判定的,
如果我們只能當問題為真的時候確定為真,為假的時候所進行的計算可能不會終止,那麼就稱該問題是半可判定的。
某元素是否屬於乙個遞迴集,是可判定的,
某元素是否屬於乙個遞迴可列舉集,是半可判定的。
因為,遞迴集使用乙個遞迴的全函式定義的,
而遞迴可列舉集是使用第乙個部分遞迴函式定義的,
我們無法判斷某個部分遞迴函式,在接受某引數時,是沒有定義,還是計算尚未停止。
即,判斷元素是否屬於某遞迴可列舉集的程式可能永不停機。
本文介紹了函式的可計算性,通用程式,以及最多有多少個程式,
還了解了停機問題和可判定性問題。
這些都是可計算性理論的基礎,我們清晰的看到了人類的計算能力,
以及用遞迴所能計算的函式範圍,後文中我們開始討論不動點理論,
這同樣是乙個有趣的話題。
配對函式和哥德爾數,是對數偶和有窮數列的一種編碼方式。
(1)配對函式
令\(langle x,yrangle=2^x(2y+1)-1\),稱\(langle x,yrangle \)為配對函式,它是乙個原始遞迴函式。
任給乙個數\(z\),存在唯一的一對數\(x\)和\(y\),使得\(langle x,yrangle =z\)。
\(x\)是\(z+1\)含有因子\(2\)的個數,即使得\(2^t|(z+1)\)的\(t\)的最大值。
\((z+1)/2^x\)必為奇數,\(y\)是\(2y+1=(z+1)/2^x\)的唯一解。
一般的,記\(l(z)=x\),\(r(z)=y\),則\(l(z)\)和\(r(z)\)也是原始遞迴函式。
(2)哥德爾數
記\([a_1,a_2,cdots ,a_n]=prod_^p_i^\),
\([a_1,a_2,cdots ,a_n]\)稱為有窮數列\((a_1,a_2,cdots ,a_n)\)的哥德爾數。
其中,\(p_i\)是第\(i\)個素數。
例如,\([2,0,1,3]=2^2cdot 3^0cdot 5^1cdot 7^3=6860\)。
對於每乙個固定的\(n\),\([a_1,a_2,cdots ,a_n]\)是原始遞迴函式,並且這種編碼具有唯一性。
配對函式
哥德爾數
可數集可判定性
康托爾定理
Linux下最多有多少個程序
程序 系統分配資源的載體,是程式執行的例項 執行緒 程式執行的最小單元,是程序中的乙個實體用來執行程式,乙個系統中的程序數量肯定是有上限的,因為系統資源是有限的,同樣的道理,乙個程序中的執行緒資源也是有上限的。ulimit n可以檢視乙個程序最多可以開啟多少檔案描述符數,這個命令就可以檢視系統中的程...
最多有多少個點在一條直線上
題目 給出二維平面上的n個點,求最多有多少點在同一條直線上。例子 給出4個點 1,2 3,6 0,0 1,3 一條直線上的點最多有3個。方法 取定乙個點points i 遍歷其他所有節點,然後統計斜率相同的點數 用map float,int 記錄斜率及其對應點數,取map中點數最多的斜率 並求取最大...
最多有多少個點在一條直線上 LintCode
給出二維平面上的n個點,求最多有多少點在同一條直線上。樣例 給出4個點 1,2 3,6 0,0 1,3 一條直線上的點最多有3個。思想 利用map ifndef c186 h define c186 h include include include include using namespace ...