希尔伯特曲线分析

时间:2011-08-28 00:29:31

标签: python

我刚刚开始学习Python,我不理解在自己内部调用相同函数的能力?

以下是一个例子:

import turtle
from turtle import left, right, forward

size = 10

def hilbert(level, angle):
    if level == 0:
        return

    turtle.color("Blue")
    turtle.speed("Fastest")

    right(angle)
    hilbert(level - 1, -angle)
    forward(size)
    left(angle)
    hilbert(level - 1, angle)
    forward(size)
    hilbert(level - 1, angle)
    left(angle)
    forward(size)
    hilbert(level - 1, -angle)
    right(angle)

这究竟是如何运作的?

感谢。

6 个答案:

答案 0 :(得分:3)

答案 1 :(得分:2)

level等于0时,hilbert(level,angle)才会返回,即不执行任何操作。

现在考虑当level等于1时会发生什么:调用hilbert(1,angle)执行这些语句:

turtle.color("Blue")
turtle.speed("Fastest")
right(angle)
forward(size)
left(angle)
forward(size)
left(angle)
forward(size)
right(angle)

在我看来,这可能是一个正方形的三面。

hilbert(level-1,...)等于0后,level-1语句已被删除,我们已确定hilbert(0,...)不执行任何操作。

现在,请考虑致电hilbert(1,-angle)时会发生什么。 接下来,考虑当level等于2时会发生什么。我希望这可以让您了解如何继续。

PS。关于Python的可爱之处 - 您可以以交互方式运行程序,以可视化调用hilbert(1,angle)的功能,然后hilbert(2,angle)执行,等等...

答案 2 :(得分:1)

这是一种强大的编程技术recursion,通过将问题分解为类似但更小的问题来解决问题,直到问题足够小以便轻松解决为止。

答案 3 :(得分:1)

正如@Tom Zych和其他人所提到的,这是一个称为递归的问题,起初可能难以解决问题(有时需要以与通常完全不同的方式思考问题)。

最经典且易于理解(但不一定有用或强大)的递归示例是阶乘生成器。给定正整数nn的阶乘等于小于或等于n的所有正整数的乘积。我们将n的阶乘写为n!

  

N! = n *(n-1)*(n-2)* ... * 3 * 2 * 1

现在通过递归,我们希望看到,“当我尝试解决更大的问题时,这里重复的模式是什么,变得更简单?”我们试试5!例如:

  

5! = 5 * 4 * 3 * 2 * 1

解决这个等式时我们做的第一件事是什么?我们采用5并将其乘以某种东西。这很完美,因为如果我们有一个因子函数fact(n),我们可能会将n作为参数:

def fact(n):
    return n * #something

剩下的就是找出#something是什么。但我们只是在上面写了:

  

5! = 5 *(4 * 3 * 2 * 1)

但是新的#something如何只是一个与我们原始问题基本相同的小问题?观察,这是递归的魔力:

5! = 5 * 4 * 3 * 2 * 1
   = 5 * 4!
4! = 4 * 3 * 2 * 1
   = 4 * 3!
3! = 3 * 2 * 1
   = 3 * 2!
2! = 2 * 1
   = 2 * 1!
1! = ???

正如您所看到的,对于大多数给定的n

  

N! = n *(n-1)!

我们差不多了,现在我们已经发现了我们的模式,我们需要担心异常情况,最简单的情况,(当n = 1时,没有别的东西可以乘以)。在递归中,我们称之为基本情况,幸运的是,我们确切地知道在这个基本情况下要做什么:1! = 1。因此,在总结我们的逻辑时,我们可以编写递归因子函数:

def fact(n):
    # Take care of the base case first
    if n == 1:
        return 1
    # Then break down the larger case into its recursive sub-problems
    else:
        return n * fact(n-1)

你的Hilburtle程序有点复杂,但是如果你知道Hilbert曲线分析的一些内容,并且你开始理解递归程序逻辑,那么你应该能够弄清楚它是如何工作的。祝你好运!

答案 4 :(得分:0)

这被称为recursion。递归函数通常可以解决一个小问题,但也能够将较大的问题分解为更容易解决的较小问题。

在你的例子中,看起来程序可能是一些耗费精力的程序。

答案 5 :(得分:0)

实际上这很简单。一般来说,除了一些(重要的,但不是讨论)例外:

  • 函数是对数据进行操作的指令列表。
  • 部分数据是“堆栈” - 内存块
  • 函数使用“堆栈指针”跟踪堆栈的哪个部分正在使用
  • 调用函数时,移动堆栈指针,指令作用于当前堆栈指针(可能会进一步移动)
  • 当一个函数完成(返回)时,指针会移回。
  • 当一个函数调用另一个函数时,它会像以前一样移动堆栈指针。
  • 因此,当一个函数调用自身时,它没有什么不同:函数指针移动,然后执行该函数。

换句话说,如果调用不同的函数或递归调用相同的函数,计算机并不在意。实际上,它可以稍微优化递归函数,因为它知道每次都会发生相同的事情,比如for循环。