我对算法有很基本的了解。我是数学专业的毕业生。我正在读苏珊娜·艾普的《离散数学与应用》一书中的停顿问题。它有一个定理:
定理:没有一个计算机算法可以接受任何算法x和数据集d作为输入,然后输出“暂停”或“永远循环”来指示当x使用数据集d运行时,x是否在有限步数内终止。
证明:假设有一个算法,称之为CheckHalt,这样如果输入了一个算法X和一个数据集D,那么CheckHalt会打印“halts”,如果X在使用数据集D运行时终止于有限步数,或者如果X在使用数据集D运行时不终止于有限步数,那么CheckHalt会打印“loops forever”。
接下来的几行是我不明白的
注意,构成算法X的字符序列可以看作是一个数据集本身因此,可以考虑使用输入(X,X)运行CheckHalt。
所以我知道checkhalt本质上是作为一个算法x和一个数据集d来输入的,它告诉我们如果用这个数据集d作为输入来运行算法x,那么x将永远停止或循环。因此checkhalt(x,d)看起来不错。
我的问题是,一个算法x如何能有一个输入x本身,即我们如何把一个算法称为一个数据集?
“组成算法x的字符序列”这句话的意思是什么?
我能理解CheckHalt(X,D)但是什么是CheckHalt(X,X)?
谢谢。
最佳答案
考虑以下算法来反转字符串:
function reverse(s) {
var ret = "";
for (var i = s.length - 1; i >= 0; i--) {
ret = ret + s[i];
}
return ret;
}
它接受一个字符串作为输入,并返回一个字符串现在考虑以下输入数据集:
"function reverse(s) {\n"
+ " var ret = \"\";\n"
+ " for (var i = s.length - 1; i >= 0; i--) {\n"
+ " ret = ret + s[i];\n"
+ " }\n"
+ " return ret;\n"
+ "}"
这是一根绳子它碰巧是一个字符串,编码一个算法的源代码因为它是一个字符串,所以它是接受字符串的算法的有效输入;就像它碰巧编码的算法一样实际上,如果将此算法的编码传递给它本身,您将得到以下定义良好的输出:
"}"
+ ";ter nruter "
+ "} "
+ ";]i[s + ter = ter "
+ "{ )--i ;0 => i ;1 - htgnel.s = i rav( rof "
+ ";"" = ter rav "
+ "{ )s(esrever noitcnuf"
同样,如果您有一个字符串编码的程序
X
并且enc(X)
接受一个字符串,则可以将X
传递到enc(X)
。如果您有另一个采用两个字符串的算法,则可以将X
作为两个参数传递。