我刚刚开始阅读TAOCP第1卷,我无法理解风格。
Knuth提到一种计算方法是四倍(Q,I,Omega,f) - 但我无法理解每种方法的意图。我理解他的第一个例子,但不明白他的第二个
我正在看第三版的第8页。
在本章的最后,有一个算法来讨论字符串集。
(我已经用一些更容易输入的希腊变量替换了 - 抱歉)
设A是一组有限的字母,让A *为A上所有字符串的集合。 我们的想法是对计算的状态进行编码,使它们由A *
的字符串表示Q = (s,j) where s is in A* and j is an integer, 0 <= j <= N
I = subset of Q with j = 0
Omega = subset with j = N
f = function below
(请注意,p&amp; w是字符串) 如果和S是A *中的字符串,我们说如果s的字符串形式为字符串p和w的pTw,则T出现在s中。
f(s,j) = (s,aj) if Tj does not occur in s; f(s,j) = (pYjw,bj) if p is the shortest possible string for which s = pYjw f(s,N) = (s,N)
我理解制作字符串集的概念,但不理解他试图在这里说的所有。为什么我需要Q,I,Omega?真正向我解释的是什么(为什么我需要在f中使用3个函数?)??
任何人都可以帮忙解决一些问题吗?
答案 0 :(得分:14)
Q
=一组状态(以便(s, j)
代表s
时的状态j
I
=初始状态(因此要求j == 0
)
Omega
=最终状态(因此要求j == N
)
f
=过渡功能
此外,没有三个名为f
的函数,而是f
由三个方程式分段定义。
答案 1 :(得分:11)
为了完整披露,我最近wrote an article了解了Knuth(前例)对算法的正式定义。下面的大部分内容只是文章中相关文字的复制/粘贴,深入回答了您的第一个问题;
让我们正式定义一个四倍的计算方法(Q,I, Ω,f),其中Q是包含子集I和Ω的集合,f是a 从Q到自身的功能。
当Knuth将计算方法称为四元组时,他只是说计算方法由四个明确定义的部分组成。他将这四个部分标记为(Q, I, Ω, f)
。然后他继续简要描述这个四重奏的每个组成部分。 I
和Ω
是集合(事物集合),Q
也是一个集合,其中包含集合I
和Ω
中的内容。在这一点上,很容易错误地认为他意味着Q
仅包含集合I
和Ω
而没有其他内容。但我们后来发现事实并非如此。最后,他将f
描述为Q
自身的函数。这意味着f
是一个进程,它接受来自集合Q
的元素的输入,并从Q
返回或输出另一个元素。
此外f应保持Ω点固定;也就是说,f(q)应该 等于q的所有元素q。
这实质上意味着,如果参数是(thing in)set Ω
的成员或元素,我们的函数f返回的内容将与其参数相同(即值不会改变) 。当Knuth在他的下一个声明中作出澄清时,这更有意义;扰流器警报 - Ω
是我们的计算方法的可能输出集。一旦我们知道这一点,就会更容易理解。将输出传递回我们的函数不会改变它。
四个量Q,I,Ω,f分别用于表示 计算的状态,输入,输出和 计算规则。
因此Q
是一个包含计算的所有可能状态的集合,即输入,输出和其间所有阶段的所有可能变化。集I
包含所有可能的输入。集Ω
包含所有可能的输出(对不起,如果我之前为你破坏了这个启示)。最后,f
代表计算规则;也就是说,进程/ es应用于每个状态以获得下一个状态,最终(希望)直到我们获得输出。
为了澄清,f
表示单个函数,其具有基于其可能输入定义的输出。在此特定示例中,它只有三个可能的输出,并且在其他算法中可能有更多(或更少)。那么,以这种方式定义算法组件的目的是什么呢?通过使用正式表示法定义它们,它们也可以在分析特定算法时进行分析并进行数学检验。
我回答another question on this subject here。但基本上Knuth在这里所做的就是使用Markov's algorithm来实现他已经描述的内容。值得研究(并通过几个例子)Markov算法来帮助您准确理解这里发生的事情。
参考
答案 2 :(得分:1)
我不是100%肯定,但看起来Q是0&lt; = J&lt; = N的所有有序对(s,j)的集合。这将是你的域。它是给定N和字符串s的所有可能状态的集合。
我是Q的子集,其中所有有序对包含J = 0或初始状态。 Omega是Q的子集,其中所有有序对包含J = N或最终状态。
f是域Q的实际功能。
修改强>
将函数定义视为一个函数的行,但不同的情况取决于给定的输入。想想你会用一种语言写的函数。例如:
tuple f(string s, int i)
{
if (Tj not in s)
(s, aj)
else if ( p is shortest possible length such that s = pYjw)
(pYjw,bj)
else if ( i == N )
(s, N)
}
另一个例子是Fibonacci function definition。看看如何定义? 有意义吗?
答案 3 :(得分:1)
如果你已经阅读了他在书中早些时候提到的euclid的gcd算法。我们的想法是将每次迭代的开始标记为初始阶段,然后定义将在一次循环迭代(即N)中出现的状态数。现在你会记得当m的余数除以n等于零时我们接受了答案并停止了计算。即我们正在搜索字符串Yj的特定事件。当计算机在循环中到达itz的最后阶段时,它必然会停止或重复。
答案 4 :(得分:1)
记住我们正在定义一种计算方法&#39;而不是算法。什么是天真的计算方法?
a&#34;程序&#34;除了可能缺乏有限性之外,它具有算法的所有特征,可以称为计算方法。
简单地说Q是一种计算方法。
Q = {all possible states of computations, I, Ω}
I = {all possible inputs}
Ω = {all possible outputs}
f = computational rule
f是Q中的一个函数。
f: Q ---> Q
[I] [Ω]
f应该保留Ωpointwise,这意味着:
f(q)= q,∀q∈Ω 请注意,它不是任何不同的功能,但相同的计算规则只是分开到Ω
现在一个程序将有一个序列。显然,计算方法也必须有一个序列。 因此,
集合I中的每个输入x定义计算序列x 0 ,x 1 ,x 2 ,...,如下: 对于k≥0,x 0 = x且x k + 1 = f(x k )。
x 0 = x? 不要忘记输入x是一个序列,因此初始输入序列将是x 0 。 当我们正在处理一个序列时,当我们关注&#39; k&#39;状态,序列中元素的顺序和位置很重要。因此,计算规则f使得位置或更精确的单词状态为&#39; k th 元素的结果为k + 1 th 状态。 这样,我们可以将函数单独应用于每个新状态以获得后面的状态。
如果x k + 1 不在Ω中,则根据函数的定义没有意义。因此,Knuth的措辞。
如果k是x k 为Ω的最小整数,则称计算序列以k步结束,并且在这种情况下,据说产生输出x k 来自x。
因此,这是计算方法的定义。计算规则就是算法。