我对算法有非常基本的了解。我是数学专业的毕业生。我正在阅读Susanna Epp的离散数学与应用一书中的停止问题。它有以下定理:
定理:没有计算机算法会接受任何算法X和数据集D作为输入,然后输出"停止"或"永远循环",以指示当X与数据集D一起运行时,X是否在有限步数内终止。
证明:假设有一个算法,称之为CheckHalt,这样如果输入算法X和数据集D,那么如果X在使用数据集D运行时以有限数量的步骤终止,则CheckHalt打印"halts",如果使用数据集D运行时X在有限步数内终止,则"永远循环"。
现在下一行是我在这个证明中不明白的那些
请注意,构成算法 X 的字符序列可以被视为数据集本身。因此,可以考虑使用输入 (X,X( 运行 CheckHalt。
所以我明白 CheckHalt 本质上是作为算法 X 和数据集 D 获取输入的。它告诉我们是否使用数据集 D 作为 (X( 的输入运行算法 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"
同样,如果您有一个具有字符串编码enc(X)
的程序X
并且X
接受字符串,则可以enc(X)
传递给X
。如果您有另一种采用两个字符串的算法,则可以enc(X)
作为两个参数传递。
数据集是一个非常开放的定义,所以绝对可以想象数据集将由一串字符组成。但我认为一个例子会有所帮助。
假设X是一种计算字符串中周期 (.
( 的算法。X可以有多种方式编写,但是如果你想想象这种特殊的方式:
- 从
0
处开始计数,在0
处开始位置指针。 - 读取字符串中指针位置的字符。
- 如果字符是
.
,则增加我们的计数。 - 如果字符是字符串中的最后一个字符,则返回我们的计数。
- 递增位置指针
- 返回到步骤 2。
我刚刚写的六步列表本身就是一个字符串......因此可以作为数据应用于自身(我认为我们得到 12(。在这种情况下,算法可以作为数据应用于自身。
在这种情况下,CheckHalt(X,X)
将返回halt
因为算法不会永远循环。
当然,并非每个算法都能将自己视为数据。例如,GCD 算法需要整数输入,因此无法应用于自身。但是,我认为正在构建的反例涉及一种算法,该算法可以作为字符串应用于自身。