跳到主要内容

算法与生成系统

引言:代码即创造

如果自然是无意识的内容生成者,数据流是现实的数字镜像,那么算法生成系统则是纯粹的创造——用数学和逻辑从虚无中涌现出无限可能。从简单的随机数生成器到复杂的AI模型,算法使我们能够设计专属的"宇宙规则"。


一、随机性:混沌的艺术

1.1 伪随机数生成器(PRNG)

线性同余生成器(LCG)

公式

X(n+1) = (a * X(n) + c) mod m

特性

  • 确定性(相同种子 → 相同序列)
  • 周期性(最多m个不重复值)
  • 快速但不够"随机"

应用

class SimpleLCG:
def __init__(self, seed=42):
self.state = seed

def next(self):
self.state = (1103515245 * self.state + 12345) % (2**31)
return self.state / (2**31) # 归一化到[0,1)

rng = SimpleLCG()
for _ in range(10):
print(rng.next())

梅森旋转(Mersenne Twister)

  • Python默认PRNG
  • 周期 2^19937 - 1
  • 统计性质优秀

XorShift, PCG

  • 更快、更小状态空间
  • 适合游戏、模拟

1.2 真随机数生成器(TRNG)

物理随机源

  • 量子随机:光子偏振、真空涨落
  • 热噪声:电阻的Johnson-Nyquist噪声
  • 放射性衰变:不可预测的核事件
  • 大气噪声:random.org使用的方法

在线服务

import requests
# ANU量子随机数
response = requests.get('https://qrng.anu.edu.au/API/jsonI.php?length=10&type=uint8')
random_numbers = response.json()['data']

1.3 噪声函数

Perlin噪声

特点

  • 连续、可微
  • 多尺度叠加(Octaves)
  • 自然纹理感

代码

from noise import pnoise2

# 生成2D Perlin噪声地形
for y in range(100):
for x in range(100):
value = pnoise2(x/10.0, y/10.0, octaves=4)
# value ∈ [-1, 1],可映射到高度、颜色等

应用

  • 程序生成地形
  • 云纹理
  • 自然动画

Simplex噪声

  • Perlin的改进版(更快,无方向性伪影)
  • 高维噪声更高效

Worley噪声(细胞噪声)

  • 生成泡沫、细胞、石头纹理
  • 基于Voronoi图

二、程序生成内容(Procedural Generation)

2.1 无限地形

Minecraft式体素世界

算法

  1. 种子 → 伪随机生成器
  2. Perlin噪声 → 高度图
  3. 生物群系映射(温度、湿度噪声)
  4. 洞穴系统(3D Worm算法)
  5. 矿物分布(概率放置)

关键代码

def generate_chunk(seed, chunk_x, chunk_z):
rng = SimpleLCG(seed + hash((chunk_x, chunk_z)))

for x in range(16):
for z in range(16):
world_x = chunk_x * 16 + x
world_z = chunk_z * 16 + z

# 基础高度
height = int(pnoise2(world_x/100, world_z/100) * 20 + 64)

# 生成柱状方块
for y in range(height):
if y == 0:
block = BEDROCK
elif y < height - 4:
block = STONE
elif y < height - 1:
block = DIRT
else:
block = GRASS

set_block(world_x, y, world_z, block)

优势

  • 无限世界,按需生成
  • 确定性:相同坐标总是生成相同地形
  • 内存高效:不需存储所有数据

No Man's Sky式星球

  • 18,446,744,073,709,551,616 个可探索行星
  • 每个星球:地形、生态、生物、天气
  • 全部从64位种子生成

2.2 迷宫与地牢

递归回溯算法

def generate_maze(width, height):
maze = [[WALL] * width for _ in range(height)]

def carve(x, y):
maze[y][x] = PATH
directions = [(0,1), (1,0), (0,-1), (-1,0)]
random.shuffle(directions)

for dx, dy in directions:
nx, ny = x + 2*dx, y + 2*dy
if 0 <= nx < width and 0 <= ny < height and maze[ny][nx] == WALL:
maze[y+dy][x+dx] = PATH # 移除墙
carve(nx, ny)

carve(1, 1)
return maze

BSP(二叉空间分割)地牢

  1. 递归划分空间为房间
  2. 用走廊连接兄弟房间
  3. 放置门、宝箱、敌人

应用:Rogue-like游戏

2.3 程序音乐

生成旋律

规则示例

import random
from midiutil import MIDIFile

# 音阶(C大调)
scale = [60, 62, 64, 65, 67, 69, 71, 72]

def generate_melody(length=16):
melody = [random.choice(scale)]

for _ in range(length - 1):
# 倾向于小跳跃(级进)
step = random.choice([-2, -1, -1, 0, 1, 1, 2])
next_note = melody[-1] + step

# 约束在音阶内
while next_note not in scale:
next_note += 1 if step > 0 else -1

melody.append(next_note)

return melody

# 写入MIDI
midi = MIDIFile(1)
for i, note in enumerate(generate_melody()):
midi.addNote(0, 0, note, i*0.5, 0.5, 100)

with open("melody.mid", "wb") as f:
midi.writeFile(f)

生成和声

  • 马尔可夫链:基于和弦进行概率
  • L-系统:分形音乐结构

案例:Brian Eno的生成音乐

  • 《Music for Airports》
  • 系统:多个独立循环,长度互质,产生超长不重复组合

2.4 程序艺术

分形

曼德布罗特集

def mandelbrot(c, max_iter=100):
z = 0
for n in range(max_iter):
if abs(z) > 2:
return n
z = z*z + c
return max_iter

# 渲染
for y in range(height):
for x in range(width):
c = complex((x - width/2) / scale, (y - height/2) / scale)
color = mandelbrot(c)
draw_pixel(x, y, colormap(color))

特征

  • 无限缩放,细节不竭
  • 确定性但视觉复杂

其他分形:Julia集、Burning Ship、Newton分形

生成艺术(Generative Art)

Processing/p5.js典型模式

function setup() {
createCanvas(800, 600);
}

function draw() {
// 不清空画布,累积效果
translate(width/2, height/2);
rotate(frameCount * 0.01);

let r = map(sin(frameCount * 0.05), -1, 1, 50, 200);
stroke(255, 20);
noFill();
ellipse(0, 0, r, r);
}

艺术家

  • Tyler Hobbs (Fidenza)
  • Matt DesLauriers
  • Zach Lieberman

三、元胞自动机(Cellular Automata)

3.1 Conway生命游戏

规则

  1. 活细胞周围有2-3个活邻居 → 存活
  2. 死细胞周围有3个活邻居 → 复活
  3. 其他情况 → 死亡

代码

import numpy as np

def step(grid):
neighbors = sum(np.roll(np.roll(grid, i, 0), j, 1)
for i in (-1, 0, 1) for j in (-1, 0, 1)
if (i != 0 or j != 0))

return (neighbors == 3) | (grid & (neighbors == 2))

# 初始化随机状态
grid = np.random.choice([0, 1], size=(100, 100))

# 演化
for generation in range(1000):
grid = step(grid)
display(grid)

涌现模式

  • 静物:Block, Beehive
  • 振荡器:Blinker, Pulsar
  • 飞船:Glider, LWSS
  • :Glider Gun(周期性产生飞船)

哲学意义

  • 简单规则 → 复杂行为
  • 图灵完备(可模拟任何计算)
  • 生命的简化模型

3.2 其他元胞自动机

Rule 30(Wolfram)

规则

当前: 111 110 101 100 011 010 001 000
下一: 0 0 0 1 1 1 1 0

特性

  • 一维元胞自动机
  • 产生混沌模式
  • 可用作伪随机数生成器

代码

def rule30(row):
new_row = [0] * len(row)
for i in range(1, len(row) - 1):
pattern = row[i-1] * 4 + row[i] * 2 + row[i+1]
new_row[i] = (30 >> pattern) & 1
return new_row

Langton蚂蚁

规则

  • 白格上:右转,翻转格子,前进
  • 黑格上:左转,翻转格子,前进

涌现

  • 初期混乱
  • 10000步后进入"高速公路"模式(周期性)

四、L-系统(Lindenmayer Systems)

4.1 原理

形式文法

  • 公理:初始字符串
  • 规则:字符替换规则
  • 迭代:反复应用规则

4.2 植物生长模拟

例子:分形树

公理: F
规则: F → F[+F]F[-F]F

解释:
F: 前进
[: 保存状态
]: 恢复状态
+: 右转25°
-: 左转25°

代码

def l_system(axiom, rules, iterations):
current = axiom
for _ in range(iterations):
next_gen = ""
for char in current:
next_gen += rules.get(char, char)
current = next_gen
return current

def draw_l_system(instructions, angle=25):
stack = []
pos = (0, 0)
direction = 90

for cmd in instructions:
if cmd == 'F':
new_pos = (pos[0] + cos(radians(direction)),
pos[1] + sin(radians(direction)))
draw_line(pos, new_pos)
pos = new_pos
elif cmd == '+':
direction += angle
elif cmd == '-':
direction -= angle
elif cmd == '[':
stack.append((pos, direction))
elif cmd == ']':
pos, direction = stack.pop()

# 生成并绘制
instructions = l_system("F", {"F": "F[+F]F[-F]F"}, 4)
draw_l_system(instructions)

应用

  • 树木、蕨类、藻类建模
  • 程序生成植被

4.3 分形曲线

Koch雪花

公理: F--F--F
规则: F → F+F--F+F
角度: 60°

Dragon曲线

公理: FX
规则: X → X+YF+
Y → -FX-Y

五、人工智能生成

5.1 文本生成

马尔可夫链

原理:基于前N个词预测下一个词

代码

import random
from collections import defaultdict

def build_markov_chain(text, order=2):
words = text.split()
chain = defaultdict(list)

for i in range(len(words) - order):
key = tuple(words[i:i+order])
next_word = words[i+order]
chain[key].append(next_word)

return chain

def generate_text(chain, length=50, order=2):
# 随机起始
current = random.choice(list(chain.keys()))
result = list(current)

for _ in range(length - order):
if current not in chain:
break
next_word = random.choice(chain[current])
result.append(next_word)
current = tuple(result[-order:])

return ' '.join(result)

# 训练
corpus = """Your training text here..."""
chain = build_markov_chain(corpus, order=2)
print(generate_text(chain, length=100))

GPT系列(Transformer)

能力

  • 长文本连贯性
  • 多种风格模仿
  • 按提示生成

持续生成

# 使用OpenAI API
import openai

def stream_story():
response = openai.ChatCompletion.create(
model="gpt-4",
messages=[{"role": "user", "content": "讲一个无尽的故事"}],
stream=True
)

for chunk in response:
if 'content' in chunk['choices'][0]['delta']:
yield chunk['choices'][0]['delta']['content']

for word in stream_story():
print(word, end='', flush=True)

5.2 图像生成

GAN(生成对抗网络)

原理

  • 生成器:噪声 → 图像
  • 判别器:图像 → 真/假
  • 对抗训练

应用

  • 人脸生成(This Person Does Not Exist)
  • 艺术风格迁移
  • 图像修复

Diffusion模型

代表:Stable Diffusion, DALL-E, Midjourney

特点

  • 文本提示控制
  • 高质量、多样性
  • 可持续生成变体

持续生成应用

from diffusers import StableDiffusionPipeline

pipe = StableDiffusionPipeline.from_pretrained("stabilityai/stable-diffusion-2")

# 持续生成不同种子的图像
prompt = "A serene landscape at sunset"
for seed in range(1000):
image = pipe(prompt, generator=torch.manual_seed(seed)).images[0]
display(image)

5.3 音乐生成

RNN/LSTM音乐模型

训练:MIDI数据集 生成:逐音符采样

MusicVAE, Magenta

  • Google Magenta项目
  • 插值、延续、变奏

Jukebox (OpenAI)

  • 生成原始音频(非MIDI)
  • 多种流派和艺术家风格

六、混合系统:规则+AI

6.1 程序辅助AI

例子:AI地牢主持

  • 规则系统:游戏机制、物理法则
  • AI模型:故事叙述、NPC对话

6.2 AI辅助程序

例子:波浪函数坍缩(WFC)

  • 算法:基于样本的约束满足
  • AI增强:学习更好的约束权重

6.3 人机协作生成

Photoshop生成填充

  • 用户:选区+提示
  • AI:生成内容
  • 系统:无缝融合

七、评估生成系统

7.1 多样性(Diversity)

度量

  • 唯一性比例
  • 分布熵

避免:模式崩溃(Mode Collapse)

7.2 连贯性(Coherence)

文本:语法正确性、逻辑一致 图像:无伪影、透视正确 音乐:和声规则、节奏稳定

7.3 可控性(Control)

参数化

  • 显式:难度、风格、主题
  • 隐式:种子、潜空间向量

理想:高维参数空间,每个维度有明确语义

7.4 惊喜度(Novelty)

平衡

  • 太熟悉 = 无聊
  • 太奇怪 = 不可理解

最佳点:边缘熵(edge of entropy)


八、哲学思考

8.1 创造性的本质

问题:算法生成算"创造"吗?

观点

  • 工具论:算法是工具,创造者是编程者
  • 协作论:人设定框架,算法探索空间,共同创造
  • 自主论:复杂AI系统展现真正创造性

8.2 无限可能的诅咒

问题:能生成一切 = 难以找到好的

解决

  • 策展(Curation):人工筛选
  • 适应度函数(Fitness):自动评估
  • 交互式进化:用户反馈引导

8.3 确定性vs随机性

观察

  • 纯确定:可复现,但可预测
  • 纯随机:不可复现,难以调试

实践

  • 种子控制的随机性
  • 确定性框架+随机细节

九、实践项目建议

9.1 入门:无限迷宫浏览器

技术

  • Web界面(HTML Canvas)
  • JavaScript程序生成
  • URL存储种子(可分享)

9.2 进阶:程序音乐播放器

功能

  • 实时生成无尽音乐
  • 参数调节(速度、情绪、复杂度)
  • Web Audio API

9.3 高级:生成游戏引擎

组件

  • 地形生成
  • 任务生成
  • NPC对话(AI)
  • 物品属性随机化

9.4 艺术:生成视觉装置

硬件

  • 投影仪/LED矩阵
  • 传感器输入(声音、动作)
  • 实时渲染生成图形

十、资源与工具

10.1 编程库

Python

  • noise:Perlin/Simplex噪声
  • numpy:数值计算
  • Pillow:图像处理

JavaScript

  • p5.js:创意编程
  • three.js:3D生成
  • tone.js:音频生成

10.2 学习资源

书籍

  • 《The Nature of Code》Daniel Shiffman
  • 《Procedural Generation in Game Design》
  • 《Generative Design》

在线

  • Coding Train (YouTube)
  • Generative Hut
  • Shadertoy (着色器艺术)

十一、总结

算法生成系统将抽象规则转化为具体内容,是持续内容生成的智力维度。

核心要点

  1. 随机性是基础,但需要结构约束
  2. 程序生成适合无限、动态的内容需求
  3. AI大幅提升生成质量和多样性
  4. 最佳系统平衡控制与惊喜
  5. 生成是创造力的放大器,非替代品

下一篇文档将探讨人类活动与社会系统——集体智慧如何涌现内容。