【问题标题】:SICP Exercise 1.16 ... what does "invariant quantity" hint mean?SICP练习1.16 ...“不变量”提示是什么意思?
【发布时间】:2022-08-23 19:17:15
【问题描述】:

我看到围绕这个练习还有其他一些问题,但没有一个具体是在询问提示中的含义......\"以这样的方式定义状态转换,即产品抗体n各州不变\".

他们还提到,这种使用“不变量”的想法对于“迭代算法”来说是一个强大的想法。顺便说一句,这个问题需要设计一个“对数”指数算法,其空间复杂度为O(1).

主要是我不知道这个提示是什么意思,我很困惑。谁能帮我解释一下这是什么意思?我唯一能真正找到的关于“不变量”的东西是用物理学中的例子来描述的,这只会使这个概念更加不透明。

完整的练习描述:

练习 1.16:设计一个过程迭代的使用连续平方并使用对数步数的求幂过程,fast-expt 也是如此。 (提示:使用观察(乙n/2)2=(乙2)n/2, 与指数一起保持n和基地b,一个额外的状态变量一个,并定义状态转换,使得产品抗体n从一个州到另一个州是不变的。

开始过程的一个被认为是1, 答案由一个结尾的过程。一般来说,定义一个不变量剩下的不变从状态到状态是思考迭代算法设计的有效方式。)

提前致谢。

  • 你需要描述练习,我们不知道练习 1.16 要求什么。
  • 对此感到抱歉 - 在上面添加
  • 假设 X = b^n(使用 n 的初始值)。最初,当 a=1 时,X=a(b^n)。如果你反复从 n 中减去 1 并将 a 乘以 b,你最终会得到 n=0,这样 X=a(b^n)=a。现在假设您将 n 分成两半;你需要对 a 做些什么来保持 X=a(b^n) 为真?
  • 因此,对于每次迭代,如果我们减去 1,a 最终将 = a(b^n),而我们在每次迭代中对 a 所做的只是将 a * b 相乘。如果 n 是偶数并且我们在每次迭代中将 n 除以 2,我们将...平方 a?
  • 我想我只是不知道他们所说的“产品与状态没有变化”是什么意思——这对我来说现在感觉非常神秘。

标签: recursion iteration scheme sicp


【解决方案1】:

这与任何“对数取幂”无关,这是一个非常模糊和令人困惑的术语。

正如您提供的报价所说,它是关于取对数步骤以获得最终结果的幂函数。

所以我们想开发一个函数exp(b,n),它需要O(log n)是时候完成了。

涉及的数字都是整数。

那么我们如何计算b<sup>n</sup>呢?我们注意到

b^n = b * b * b * b *... * b 
      `------n times------/        O(n) time process

并且,当n 是偶数时,

b^n = b * b * b * b * ... * b *  
      `------n/2 times-----/   
      b * b * b * b * ... * b   
      `------n/2 times-----/   
    = (b^(n/2))^2                ; viewed from the side
    = (b^2)^(n/2)                ; viewed from above

n 是奇数时,

b^n = b * b * b * b * ... * b *  
      `------n/2 times-----/   
      b * b * b * b * ... * b *
      `------n/2 times-----/   
      b
      `--1 time--/
    = (b^(n/2))^2  *  b
    = (b^2)^(n/2)  *  b

请注意,如果我们将第一个表达式写为(b^2)^(n/2) * 1,则这两个表达式属于同一类别。

另请注意,方程

  b^n = (b   )^(n  )  *  { a where a = 1   }
      = (b ^2)^(n/2)  *  { a where a = ... }
      = (b'  )^(n' )  *  { a' }

意味着计算b^n * a一样{ b' = b^2 ; n' = n/2 ; a' = {if {n is even} then {a} else {a * b}} } 的更改值计算 b'^n' * a'

所以我们实际上并没有计算这个等式的任何一边。相反,我们在每一步都保留三元组{ b, n, a },并根据该规则对其进行转换

 { b, n, a } --> { b', n', a' } --> ...

bn的初始值是给我们的,第一个a等于1;并且知道如果我们以某种方式实际计算它,从任何三元组计算的最终结果都是相同的。我们仍然不知道我们将如何做到这一点。只是它会相同.那是“不变”部分。

那么这一切有什么好处呢?好吧,既然链{ n --&gt; n/2 --&gt; ... }肯定会达到n == 1的地步,我们知道在那时候我们可以打破链条,因为

 c^1 * d  ==  c * d

这两个数字的简单乘法将产生相同的结果作为初始公式。

这是函数的最终结果。

这就是提示的含义:保持状态将计算作为(此处)数字的三元组(或仅命名为bna 的三个变量),并将您的计算实现为状态转换脚步。当链根据一些测试(这里,n == 1)被打破时,我们已经到达了我们的目的地,可以根据一些简单的规则(这里,c * d)计算最终结果。

这为我们提供了一种很好且强大的解决问题的方法。

哦,我们还知道,状态变化链的长度是O(log n), 因为我们减半n 在每一步。

【讨论】:

  • 任何挥之不去的问题?怀疑?不要犹豫,问。 :)
【解决方案2】:

当 fast-exp 执行时,跟踪看起来像这样

b^14 = (b^2)^7 ; where: b' = b^2; a = 1, n = 7
b^14 = (b^2)^6 * b^2 ; where: b' = b^2; a = b^2, n = 6
b^14 = ((b^2)^2)^3 *b^2 ; where: b' = b^2^2 ; a = b^2, n = 3
b^14 = ((b^2)^2)^2 *b^2 *(b^2)^2 ; where: b' = b^2^2; a = b^2*(b^2)^2, n = 2

请注意,所有这些语句都有 b^n = b'^n' * a' 的一般形式,这不会改变

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 2016-02-24
    • 2012-07-05
    • 2011-11-05
    • 2017-02-03
    • 2010-12-26
    相关资源
    最近更新 更多