LT 码是第一代实用喷泉码 (Luby, 2002),核心思想:发送端产生无限编码包 (每个包是 K 个源符号的随机 XOR),接收端只要收到 ≈K(1+ε) 个包就能高概率恢复全部 K 个源符号,不需要握手重传。
一、Robust Soliton 度分布(核心)
参数:
- (KKK):源符号数
- (ccc):冗余控制(典型 0.1~0.5)
- (δ\deltaδ):译码失败概率上界(典型 0.01~0.05)
R=cKln(K/δ),τi={RiK,i=1,...,K/R−1RKln(Rδ),i=K/R0,i>K/RR = c\sqrt{K}\ln(K/\delta),\quad \tau_i = \begin{cases} \displaystyle\frac{R}{iK}, & i=1,\dots,K/R-1\\6pt \displaystyle\frac{R}{K}\ln\left(\frac{R}{\delta}\right), & i=K/R\\6pt 0, & i>K/R \end{cases}R=cK ln(K/δ),τi=⎩ ⎨ ⎧iKR,KRln(δR),0,i=1,...,K/R−1i=K/Ri>K/R
ρi=μi+τi∑(μ+τ),μi={1/K,i=11/i(i−1),i=2..K\rho_i = \frac{\mu_i+\tau_i}{\sum(\mu+\tau)},\qquad \mu_i=\begin{cases} 1/K, & i=1\\ 1/i(i-1), & i=2..K \end{cases}ρi=∑(μ+τ)μi+τi,μi={1/K,1/i(i−1),i=1i=2..K
matlab
%% robust_soliton.m
function rho = robust_soliton(K, c, delta)
% RSD 度分布, 返回 1×K 向量 rho(d) for d=1..K
R = c * sqrt(K) * log(K/delta);
% Ideal Soliton μ
mu = zeros(1, K);
mu(1) = 1/K;
for i = 2:K
mu(i) = 1/(i*(i-1));
end
% Robust 附加峰 τ
tau = zeros(1, K);
for i = 1:K
if i < K/R
tau(i) = R / (i*K);
elseif i == floor(K/R)
tau(i) = R/K * log(R/delta);
end
end
rho = (mu + tau) / sum(mu + tau);
end
典型值
c=0.1, δ=0.01,平均度 ≈c·ln(K/δ) ≈ 3~5,小 K 时稍大。
二、LT 编码
每个编码包:按 RSD 采度 d → 随机选 d 个源符号 → XOR。
matlab
%% lt_encode.m
function [code, neighbors] = lt_encode(src, rho, N)
% src: 1×K 二进制源符号(也可扩到 GF(2^m))
% rho: RSD 度分布
% N: 要产生的编码包数
% code: N×1 编码符号
% neighbors: cell, 每个元素是选中的源符号下标
K = length(src);
code = zeros(N, 1);
neighbors = cell(N,1);
for n = 1:N
d = randsample(K, 1, true, rho); % 按 RSD 采样度
idx = randsample(K, d, false); % 随机选 d 个源符号
neighbors{n} = idx;
code(n) = mod(sum(src(idx)), 2); % XOR
end
end
三、Peeling 译码(BEC / 无噪理想情况)
这是 LT 最经典的译码,消息传递的简化版 :找度=1 的编码包 → 恢复对应源符号 → 从相连其他编码包里"消去"它 → 度数减 1,产生新的度=1 包(叫 ripple),循环。
matlab
%% lt_decode_peeling.m
function [decoded, success, iter] = lt_decode_peeling(code, neighbors, K)
% code: M×1 收到的编码包(BEC 下假设没丢,丢包=没收到,M<K 也能试)
% neighbors: cell(M,1)
% decoded: 1×K 恢复结果
% success: 是否全部恢复
M = length(code);
decoded = nan(1, K);
% 维护每个编码包的当前值和剩余度
val = code(:).';
deg = cellfun(@length, neighbors);
iter = 0;
while true
% 找度=1 且对应源未恢复的编码包
cand = find(deg == 1);
if isempty(cand), break; end
idx = cand(1);
sid = neighbors{idx}(1); % 唯一的源符号
if isnan(decoded(sid))
decoded(sid) = val(idx); % 恢复!
else
% 已被恢复,跳过(数值应一致,否则冲突)
end
% 消去:在所有包含 sid 的其他编码包中 XOR 掉
for j = 1:M
if any(neighbors{j} == sid) && j ~= idx
val(j) = mod(val(j) + decoded(sid), 2);
neighbors{j}(neighbors{j}==sid) = [];
deg(j) = deg(j) - 1;
end
end
% 本包已用完
deg(idx) = 0; neighbors{idx} = [];
iter = iter + 1;
end
success = ~any(isnan(decoded));
end
参考代码 LT码 喷泉码的MATLAB实现 www.youwenfan.com/contentcsw/82576.html
四、主脚本:扫 overhead,画成功率
matlab
%% main_lt.m
clear; clc; close all;
K = 500;
c = 0.1; delta = 0.01;
rho = robust_soliton(K, c, delta);
overhead = 1.0:0.05:1.5; % M/K
trials = 200;
success_rate = zeros(size(overhead));
for o = 1:length(overhead)
M = round(K * overhead(o));
cnt = 0;
for t = 1:trials
src = randi([0 1], 1, K);
[code, neigh] = lt_encode(src, rho, M);
[dec, ok] = lt_decode_peeling(code, neigh, K);
if ok && isequal(dec, src), cnt = cnt + 1; end
end
success_rate(o) = cnt / trials;
fprintf('M/K=%.2f, success=%.2f\n', overhead(o), success_rate(o));
end
figure('Color','white')
plot(overhead, success_rate, 'bo-', 'LineWidth',1.5)
xlabel('Overhead M/K')
ylabel('Decode Success Rate')
title(sprintf('LT Code (K=%d, c=%.2f, \\delta=%.3f)', K, c, delta))
grid on
跑出来典型曲线:overhead≈1.05~1.1 开始起飞,1.2 以后接近 1,符合 RSD 设计预期。