我们日常接触的维度都是整数:线段是 1 维的,正方形是 2 维的,立方体是 3 维的。这个东西很直观——你从小到大在黑板上画的坐标系,横轴是一条线,横轴加纵轴是一个面,再加一根竖轴就是空间。
但这个世界有些东西,它的维度不是整数。

英国的海岸线有多长?你拿一把很长的尺子去量,得到一个数字。换一把更短的尺子,能量到更多弯弯绕绕,量出来的长度变长了。再换更短的尺子,它变得更长。如果尺子无限短,海岸线的长度似乎会变成无限大——但它又不是 2 维的面,它是一根线,只不过缠绕得过于厉害。
Mandlebrot 在 1967 年那篇著名的 Science 论文里问了这个问题。他的答案是:海岸线的维度在 1 和 2 之间,大概 1.2 到 1.3 左右。这不是一个整数。
维度到底怎么算
先回想一下整数维度是怎么来的。拿一条线段,把它均分成 2 段——你得到的是 2 段,每段长度是原来的 1/2。如果你把它均分成 3 段,你得到 3 段,每段长度 1/3。
关键在哪呢?放大的倍数和段数的关系:
- 线段:放大 2 倍 → 长度变成 2 倍。2 = 2¹。维度是 1。
- 正方形:放大 2 倍 → 面积变成 4 倍。4 = 2²。维度是 2。
- 立方体:放大 2 倍 → 体积变成 8 倍。8 = 2³。维度是 3。
设放大倍数为 r 的倒数(就是缩小的比例),设 N 为缩小后小图形的个数,则维度 D 满足:
两边取对数:

这个公式妙在什么地方呢?它不要求 N 是整数。只要你能数清楚"一个图形缩小到原来的几分之一后,包含了几个和自己相似的更小图形",你就能算出它的维度——哪怕算出来的不是整数。
科赫雪花:周长无限但面积有限
科赫雪花(Koch Snowflake)可能是最著名的分形了。构造方法非常简单:
- 从一个等边三角形开始
- 每条边三等分,把中间那段换成一个小的等边三角形的两条边
- 重复
用 Python 写出来就是:
import numpy as np
import matplotlib.pyplot as plt
def koch_snowflake(depth=4):
"""生成科赫雪花的顶点坐标"""
# 初始等边三角形
pts = np.array([[0, 0], [1, 0],
[0.5, np.sin(np.pi/3)], [0, 0]])
for _ in range(depth):
new_pts = []
for i in range(len(pts) - 1):
x1, y1 = pts[i]
x2, y2 = pts[i+1]
dx, dy = (x2 - x1) / 3, (y2 - y1) / 3
# 第一段起点
new_pts.append((x1, y1))
# 第二段起点 (三等分点)
new_pts.append((x1 + dx, y1 + dy))
# 中间凸起的顶点 (旋转60度)
angle = np.pi / 3
mx, my = x1 + 1.5*dx, y1 + 1.5*dy
new_pts.append((mx - dx*np.cos(angle) + dy*np.sin(angle),
my - dx*np.sin(angle) - dy*np.cos(angle)))
# 第三段起点 (二等分点)
new_pts.append((x1 + 2*dx, y1 + 2*dy))
new_pts.append(pts[-1])
pts = np.array(new_pts)
return pts
pts = koch_snowflake(4)
plt.figure(figsize=(8, 8))
plt.fill(pts[:, 0], pts[:, 1], facecolor='#f39c12',
alpha=0.4, edgecolor='#f39c12', linewidth=0.5)
plt.axis('equal'); plt.axis('off')
plt.show()

每一次迭代都发生了什么?一条线段被替换成了 4 条更短的线段,每条的长度是原来的 1/3。
所以 N = 4,r = 1/3(或者说,放大倍数是 3)。
科赫雪花的维度大约是 1.26。它是一个在 1 和 2 之间的几何对象——比一条线更"拥挤",但还远不到一个面。它的一个非常反直觉的性质是:面积是有限的,但周长是无限的。每一次迭代,周长都变成原来的 4/3,无限迭代下去周长就趋于无穷。
谢尔宾斯基三角形:像是被虫蛀过的三角形
另一个经典分形是谢尔宾斯基三角形(Sierpinski Triangle)。构造方法也很简单:
- 一个黑色实心三角形
- 挖掉中间那个倒着的、边长是原来一半的小三角形
- 对剩下的三个小三角形重复同样的操作
def sierpinski(depth=4):
"""生成谢尔宾斯基三角形"""
pts = np.array([[0., 0.], [1., 0.],
[0.5, np.sin(np.pi/3)]])
triangles = [pts]
for _ in range(depth):
new_tris = []
for t in triangles:
a, b, c = t[0], t[1], t[2]
# 三条边的中点
mab = (a + b) / 2
mbc = (b + c) / 2
mca = (c + a) / 2
# 三个小三角形(中间那个被挖掉了)
new_tris.append(np.array([a, mab, mca]))
new_tris.append(np.array([mab, b, mbc]))
new_tris.append(np.array([mca, mbc, c]))
triangles = new_tris
return triangles

每次迭代,三角形被分成 4 个等大的小三角形(中间那个被挖掉所以只剩下 3 个)。每个小三角形的边长是原来的一半。所以 N = 3,r = 1/2。
谢尔宾斯基三角形的维度大概是 1.58。比科赫曲线更接近 2,但仍然不是一个完整的平面——因为它被无限多个窟窿蛀空了,总面积趋近于 0。
计算任何自相似分形的维度的通用函数:
import math
def fractal_dimension(N, r):
"""
计算自相似分形的维度
N: 缩小后的小图形个数
r: 缩小的比例 (新边长 / 原边长)
"""
return math.log(N) / math.log(1/r)
print(f"科赫雪花: {fractal_dimension(4, 1/3):.2f}")
print(f"谢尔宾斯基三角形: {fractal_dimension(3, 1/2):.2f}")
print(f"门格海绵: {fractal_dimension(20, 1/3):.2f}")
print(f"线段: {fractal_dimension(2, 1/2):.2f}")
print(f"正方形: {fractal_dimension(4, 1/2):.2f}")
输出:
科赫雪花: 1.26
谢尔宾斯基三角形: 1.58
门格海绵: 2.73
线段: 1.00
正方形: 2.00
注意最后一行的线段和正方形——N 和 r 取适当的值,公式算出整数维度。这个公式是兼容的,整数维度只是它的特例。
Mandelbrot 集:无穷的精致
如果说科赫雪花和谢尔宾斯基三角形是数学家人工构造的,那 Mandelbrot 集就是大自然塞到数学里的。它的定义简单到只有一行:
取一个复数 c,从 z₀ = 0 开始不断迭代这个公式。如果 z 最终发散到无穷大,c 就不属于 Mandelbrot 集;如果永远局限在有限范围内,c 就属于它。你只是把每一个 c 在复平面上对应的点按照迭代发散的快慢染上不同的颜色,就得到了下面这个东西。

用 Python 画出来:
import numpy as np
import matplotlib.pyplot as plt
def mandelbrot(width, height, max_iter, xmin, xmax, ymin, ymax):
x = np.linspace(xmin, xmax, width)
y = np.linspace(ymin, ymax, height)
C = x[:, None] + 1j * y[None, :]
Z = np.zeros_like(C)
img = np.zeros((height, width))
for i in range(max_iter):
mask = np.abs(Z) < 4
Z[mask] = Z[mask]**2 + C[mask]
img[~mask] = i
img[mask] = i
return img.T
img = mandelbrot(800, 600, 200, -2.5, 1.0, -1.3, 1.3)
plt.figure(figsize=(10,7),facecolor='#0f1720')
plt.imshow(img, cmap='hot', extent=[-2.5,1.0,-1.3,1.3])
plt.xticks([]); plt.yticks([])
plt.show()
这个集合有一个极为特殊的性质:它的边界是处处粗糙的。不管你把放大倍数调到多大,边界上总有新的结构冒出来。你放大到原子尺度,它依然有凸起、凹陷、螺旋——永远看不完。正是因为这个边界复杂到了极致,它的 Hausdorff 维数被证明等于 2。也就是说,一条"线"——如果它可以被叫做线的话——复杂到了填满一个平面的程度。
分数维的存在告诉我们什么
维度不是一个必须整数的东西——它更像是在描述"这个形状在一个空间里填充了多少"。科赫雪花比线更挤所以维度比 1 大,但不如面那么密集所以维度比 2 小。谢尔宾斯基三角形比科赫雪花更靠近 2,因为它覆盖的面积比例更大。
现实中很多东西的维度可能不是整数。海岸线、血管网络、肺的支气管树、河网水系——这些自然形状都或多或少有自相似性,它们的有效维度是一个比整数更有信息量的描述方式。
这也许也可以当作一种思维方式来琢磨。日常做判断的时候,很多事并不是非黑即白、非零即一的简单二分。在 1 和 0 之间、在 1 和 2 之间,可能存在着连续的、丰富的光谱式的过渡。不是维度可以随便定义,而是很多看起来理所当然的"整数"划分,换个角度去看就有更多东西在中间。