Langton 蚂蚁 图灵完备 涌现
1986年,Chris Langton提出了一个极其简单的二维CA:一个"蚂蚁"在网格上行走,规则只有两条:
Langton蚂蚁规则:
就这么简单!但它的行为令人震惊——前500步左右看似混沌,然后突然开始构建一条"高速公路",永远向一个方向延伸...
| 阶段 | 步数范围 | 行为 | 特征 |
|---|---|---|---|
| 混沌期 | 0~500 | 看似随机的对称图案 | 中心区域呈近似对称 |
| 过渡期 | 500~10000 | 偶尔出现短暂的"准高速公路" | 局部有序结构出现又消失 |
| 高速公路 | >10000 | 稳定的对角线高速公路 | 每104步重复一次,向对角线方向无限延伸 |
// ============================================================================
// langton_ant.v - Langton蚂蚁硬件引擎
// 支持多色扩展( generalized Langton's ant)
// ============================================================================
module langton_ant #(
parameter WIDTH = 128, // 网格宽度
parameter HEIGHT = 128, // 网格高度
parameter COLORS = 2 // 颜色数(2=经典版)
)(
input wire clk,
input wire rst_n,
input wire enable,
input wire init,
output wire [1:0] ant_dir, // 蚂蚁方向(0=N,1=E,2=S,3=W)
output wire [7:0] ant_x, // 蚂蚁X坐标
output wire [7:0] ant_y, // 蚂蚁Y坐标
output wire [31:0] step_count,
output wire [WIDTH*HEIGHT-1:0] grid // 网格状态
);
// ---- 网格状态(每格1位,2色版本) ----
reg [WIDTH*HEIGHT-1:0] grid_reg;
// ---- 蚂蚁状态 ----
reg [7:0] ax, ay; // 位置
reg [1:0] dir; // 方向: 00=北 01=东 10=南 11=西
reg [31:0] steps;
// ---- 当前格子颜色 ----
wire [WIDTH*HEIGHT-1:0] idx = ay * WIDTH + ax;
wire current_color = grid_reg[idx];
// ---- 下一方向计算 ----
// 白色(0)→右转: dir+1; 黑色(1)→左转: dir-1
wire [1:0] next_dir = current_color ? (dir - 2'd1) : (dir + 2'd1);
// ---- 下一位置计算 ----
reg [7:0] next_x, next_y;
always @(*) begin
next_x = ax;
next_y = ay;
case (next_dir)
2'd0: next_y = (ay == 0) ? HEIGHT - 1 : ay - 1; // 北
2'd1: next_x = (ax == WIDTH - 1) ? 0 : ax + 1; // 东
2'd2: next_y = (ay == HEIGHT - 1) ? 0 : ay + 1; // 南
2'd3: next_x = (ax == 0) ? WIDTH - 1 : ax - 1; // 西
endcase
end
// ---- 状态更新 ----
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
grid_reg <= {WIDTH*HEIGHT{1'b0}};
ax <= WIDTH / 2;
ay <= HEIGHT / 2;
dir <= 2'd0;
steps <= 32'd0;
end else if (init) begin
grid_reg <= {WIDTH*HEIGHT{1'b0}};
ax <= WIDTH / 2;
ay <= HEIGHT / 2;
dir <= 2'd0;
steps <= 32'd0;
end else if (enable) begin
// 翻转当前格子颜色
grid_reg[idx] <= ~current_color;
// 更新蚂蚁位置和方向
ax <= next_x;
ay <= next_y;
dir <= next_dir;
steps <= steps + 32'd1;
end
end
assign ant_dir = dir;
assign ant_x = ax;
assign ant_y = ay;
assign step_count = steps;
assign grid = grid_reg;
endmodule
广义Langton蚂蚁:将2色扩展为k色,规则字符串指定每种颜色时的转向:
规则 R = r_0 r_1 ... r_{k-1},其中 r_i ∈ {L, R}
经典版:k=2, R="RL"(白→右转,黑→左转)
有趣扩展:
// ============================================================================
// langton_ant_general.v - 广义Langton蚂蚁
// 支持任意颜色数和转向规则
// ============================================================================
module langton_ant_general #(
parameter WIDTH = 128,
parameter HEIGHT = 128,
parameter COLORS = 4, // 颜色数
parameter [COLORS*2-1:0] RULE = 8'b01_00_01_00 // R=01,L=00
)(
input wire clk,
input wire rst_n,
input wire enable,
input wire init,
output wire [1:0] ant_dir,
output wire [7:0] ant_x,
output wire [7:0] ant_y,
output wire [31:0] step_count
);
// 每格存储颜色索引(log2(COLORS)位)
localparam CW = $clog2(COLORS);
reg [CW-1:0] grid [0:WIDTH*HEIGHT-1];
reg [7:0] ax, ay;
reg [1:0] dir;
reg [31:0] steps;
wire [CW-1:0] idx = ay * WIDTH + ax;
wire [CW-1:0] current_color = grid[idx];
// 规则查找:获取转向
wire turn_right = RULE[current_color * 2 +: 2] == 2'b01;
// 方向更新
wire [1:0] next_dir = turn_right ? (dir + 2'd1) : (dir - 2'd1);
// 下一颜色
wire [CW-1:0] next_color = (current_color == COLORS - 1) ? {CW{1'b0}} : current_color + 1'd1;
// 位置更新
reg [7:0] next_x, next_y;
always @(*) begin
next_x = ax; next_y = ay;
case (next_dir)
2'd0: next_y = (ay == 0) ? HEIGHT - 1 : ay - 1;
2'd1: next_x = (ax == WIDTH - 1) ? 0 : ax + 1;
2'd2: next_y = (ay == HEIGHT - 1) ? 0 : ay + 1;
2'd3: next_x = (ax == 0) ? WIDTH - 1 : ax - 1;
endcase
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
ax <= WIDTH/2; ay <= HEIGHT/2;
dir <= 2'd0; steps <= 32'd0;
end else if (init) begin
ax <= WIDTH/2; ay <= HEIGHT/2;
dir <= 2'd0; steps <= 32'd0;
for (integer i = 0; i < WIDTH*HEIGHT; i = i + 1)
grid[i] <= {CW{1'b0}};
end else if (enable) begin
grid[idx] <= next_color;
ax <= next_x; ay <= next_y;
dir <= next_dir;
steps <= steps + 32'd1;
end
end
assign ant_dir = dir;
assign ant_x = ax;
assign ant_y = ay;
assign step_count = steps;
endmodule
图灵完备性:Langton蚂蚁(以及其多色扩展)已被证明是图灵完备的!
证明方法:在蚂蚁的行为中编码图灵机的纸带读写头
这意味着即使是最简单的蚂蚁,理论上也可以执行任意计算
高速公路猜想:对于经典2色蚂蚁,从任意有限初始配置出发,是否总会构建高速公路?
这个猜想仍未被证明!但大量实验证据支持它
注意:在非空初始配置上,蚂蚁可能不会建造高速公路——这取决于初始图案
你已经进入人工生命领域!Langton蚂蚁展示了极端简单的规则如何产生令人惊讶的复杂行为。
计算复杂性分析:
Langton蚂蚁的每步计算量:
总计算量:O(1)/步——与网格大小无关!
这使得Langton蚂蚁成为O(N)时间复杂度的系统,N=步数
高速公路的渐近行为:
高速公路每104步重复一次,偏移量(2,2)
渐近速度:v = (2,2)/104 = (1/52, 1/52)
这是Langton蚂蚁的"终态"——无论初始条件如何(有限非空),最终都会进入这个状态
多蚂蚁的交互:
当N只蚂蚁共享同一网格时,它们的交互极其复杂
两只蚂蚁的交互可能:破坏对方的高速公路、创造新的高速公路、形成周期性结构
N只蚂蚁的宏观行为目前没有理论预测
// 多蚂蚁引擎 - 支持N只蚂蚁同时运行
module multi_ant #(
parameter WIDTH = 128,
parameter HEIGHT = 128,
parameter NUM_ANTS = 4
)(
input wire clk,
input wire rst_n,
input wire enable,
output wire [7:0] ant_x [0:NUM_ANTS-1],
output wire [7:0] ant_y [0:NUM_ANTS-1],
output wire [1:0] ant_dir [0:NUM_ANTS-1],
output wire [WIDTH*HEIGHT-1:0] grid
);
reg [WIDTH*HEIGHT-1:0] grid_r;
reg [7:0] ax [0:NUM_ANTS-1];
reg [7:0] ay [0:NUM_ANTS-1];
reg [1:0] adir [0:NUM_ANTS-1];
reg [31:0] steps;
integer a;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
grid_r <= {WIDTH*HEIGHT{1'b0}};
for (a = 0; a < NUM_ANTS; a = a + 1) begin
ax[a] <= WIDTH/2 + a*8;
ay[a] <= HEIGHT/2;
adir[a] <= a[1:0];
end
end else if (enable) begin
for (a = 0; a < NUM_ANTS; a = a + 1) begin
reg [15:0] idx_a;
reg cur_color;
reg [1:0] ndir;
idx_a = ay[a] * WIDTH + ax[a];
cur_color = grid_r[idx_a];
ndir = cur_color ? (adir[a] - 2'd1) : (adir[a] + 2'd1);
grid_r[idx_a] <= ~cur_color;
adir[a] <= ndir;
case (ndir)
2'd0: ay[a] <= (ay[a]==0) ? HEIGHT-1 : ay[a]-1;
2'd1: ax[a] <= (ax[a]==WIDTH-1) ? 0 : ax[a]+1;
2'd2: ay[a] <= (ay[a]==HEIGHT-1) ? 0 : ay[a]+1;
2'd3: ax[a] <= (ax[a]==0) ? WIDTH-1 : ax[a]-1;
endcase
end
steps <= steps + 32'd1;
end
end
genvar gi;
generate
for (gi = 0; gi < NUM_ANTS; gi = gi + 1) begin
assign ant_x[gi] = ax[gi];
assign ant_y[gi] = ay[gi];
assign ant_dir[gi] = adir[gi];
end
endgenerate
assign grid = grid_r;
endmodule
多蚂蚁的资源开销:
每只蚂蚁:8位x + 8位y + 2位方向 = 18位寄存器
4只蚂蚁:72位额外寄存器 + 4组位置更新逻辑
网格存储不变:WIDTH×HEIGHT位
注意:多蚂蚁每步需要顺序更新(蚂蚁a的写入影响蚂蚁b的读取)
解决方案:所有蚂蚁同时读取,同时计算,同时写入。如果两只蚂蚁写同一格,后者优先。
元胞自动机课程 · 从Conway到Langton到Lattice Gas