学径 LearnPath

编程语言基础 / Wiki

分形

局部放大之后仍呈现出与整体相似的结构;同一条规则在更小的尺度上再执行一遍。

它是什么

分形 是一类图形或对象:把它的一部分放大,仍能看见和整体相像的结构。树冠、海岸线、雪花的边缘,都带有这种自相似。编程里,用同一条规则在更小的尺度上再做一遍,就能逼近这种形状。最简单的教学例子是 Y 型树:每一段枝的末端再分出两段更短的枝,形状仍像一个 Y。

数学理想可以无限精细;屏幕和 海龟 只能画到某一层。有限层的近似仍然叫分形图形。看起来复杂,并不要求程序很长:规则简单、重复多次,正是分形让人惊讶的地方。

名字从哪来

fractal 由本华·曼德博(Benoît Mandelbrot)在 1975 年左右使用,词源是拉丁语 fractus,有「碎裂、不规则」的意思。他想描述那些用传统欧几里得长度很难量准的对象:海岸线量得越细,测到的长度越长。自相似不必完美。自然界的树只是近似;程序里的分形树可以把规则执行得很严格,所以看起来干净,也更容易分析。

分形不只是树。科赫曲线、谢尔宾斯基三角形、巴恩斯利蕨,用的都是「小拷贝拼出大图形」这一想法。自相似也不是对称:左右枝长度可以不同,角度可以不对称,整体仍可以由同一规则生成。

它怎么工作

生成分形,通常要规定:最小尺度停下来(退出条件)、每一层如何缩小和旋转(递归步骤)。用海龟画树时,长度乘以一个小于 1 的比例,层数减 1,再在左右两侧调用同一套动作,见 递归。层数太大,计算量会涨得很快:每一层分叉加倍。这不是机器「突然坏了」,而是问题规模在按指数增长。参数要留在画布和耐心都允许的范围里。

没有递归也可以用 循环 一层层画,但层数一变,代码往往要重写;递归把「层数」收成参数。层数为 0 通常表示「不要再分叉」。这是退出条件,不是错误,除非忘记处理它。

生活里在哪里

树、支气管、河流的支流,罗马花椰菜的小朵,某些山脉和云的边缘轮廓,都呈现近似的自相似。测量海岸线时,尺子越短,量到的长度越长——这不是海岸「变长了」,而是测量尺度进入了更细的弯曲。程序里的分形把这种结构写成可执行的规则,使「复杂形态从短规则中生长」成为可以检验的现象,而不只是一句观感。

和相近概念的差别

分形描述的是对象的结构。递归是生成这种结构时常用的编程手段。海龟是把结构画到平面上的一种几何接口。三者常一起出现在同一份程序里,但分别回答「它长什么样」「如何把问题缩小」「笔如何移动」。

对称是一种特殊情形,不是分形的定义。一份左右不等长的规则仍然可以是分形生成器。把「好看」和「自相似」当成同一个词,会看丢真正被编码的那条规则。

常见误会

误会 1:分形必须无限精细。

数学理想可以无限;屏幕只能画到某一层。有限层的近似仍然是分形图形。

误会 2:看起来复杂,程序就一定很长。

短 函数 可以画出很密的枝。复杂来自重复,不一定来自条款繁多。

误会 3:层数设为 0 还会画出一棵完整的树。

0 通常表示「不要再分叉」。把叶子画在退出条件里可以,但不要在那里再调用自己。

想知道更多

  • 书:布鲁克希尔《计算机科学概论》
  • 书:艾伦·唐尼《像计算机科学家一样思考Python(第2版)》
  • 书:埃里克·马瑟斯《Python编程:从入门到实践(第3版)》

未登录时不会保存学习进度