【电子战】第20篇:凸优化与对数障碍法【含matlab代码】

第20篇:凸优化与对数障碍法

一、作用:当"约束"遇上"优化"

上一篇我们讲了贝叶斯估计------它告诉我们如何融合先验与数据。但有一个问题没有解决:

如果已知目标必须在地面上呢?如果已知目标在某个多边形区域内呢?

这类问题就是约束优化(Constrained Optimization) 。它的数学形式是:

min⁡xf(x)s.t.gi(x)≤0,hj(x)=0\min_{\mathbf{x}} f(\mathbf{x}) \quad \text{s.t.} \quad g_i(\mathbf{x}) \leq 0, \quad h_j(\mathbf{x}) = 0xminf(x)s.t.gi(x)≤0,hj(x)=0

其中:

  • f(x)f(\mathbf{x})f(x):目标函数(如定位误差);
  • gi(x)g_i(\mathbf{x})gi(x):不等式约束(如"目标必须在某个区域内");
  • hj(x)h_j(\mathbf{x})hj(x):等式约束(如"目标必须在某条线上")。

如果 fff 和 gig_igi 都是凸函数 ,这类问题叫凸优化。凸优化有一个极好的性质:

任何局部最优解都是全局最优解。

这意味着不用担心陷入局部极小------这是非凸优化(如神经网络训练)梦寐以求的性质。

对数障碍法(Logarithmic Barrier Method) 是求解凸优化问题的一类优雅算法。它的核心思想是:

把"硬约束"转化为"软惩罚",把有约束问题变成无约束问题。

本篇核心作用 :从拉格朗日乘子法出发,推导对数障碍法的数学原理;用 MATLAB 画出一维和二维的对数障碍函数;复现原书图6.2和 book2 图5.14------展示凸优化如何从四个不同初始点收敛到同一全局最优解。

代码出处 :ch6_drawFigures(图6.2)、book2_ch5_drawFigures(图5.14)。


二、原理:数学上发生了什么?

2.1 无约束优化的"梯度下降"

先从最简单的无约束问题开始:

min⁡xf(x)\min_{\mathbf{x}} f(\mathbf{x})xminf(x)

梯度下降迭代:

xk+1=xk−α∇f(xk)\mathbf{x}_{k+1} = \mathbf{x}_k - \alpha \nabla f(\mathbf{x}_k)xk+1=xk−α∇f(xk)

其中 α\alphaα 是步长。当 fff 是凸函数时,梯度下降保证收敛到全局最优。

2.2 等式约束:拉格朗日乘子法

考虑一个等式约束问题:

min⁡xf(x)s.t.h(x)=0\min_{\mathbf{x}} f(\mathbf{x}) \quad \text{s.t.} \quad h(\mathbf{x}) = 0xminf(x)s.t.h(x)=0

拉格朗日函数定义为:

L(x,λ)=f(x)+λ⋅h(x)\mathcal{L}(\mathbf{x}, \lambda) = f(\mathbf{x}) + \lambda \cdot h(\mathbf{x})L(x,λ)=f(x)+λ⋅h(x)

拉格朗日乘子法 :在最优点处,L\mathcal{L}L 对 x\mathbf{x}x 和 λ\lambdaλ 的偏导都为零:

∇xL=0,∇λL=0\nabla_{\mathbf{x}} \mathcal{L} = 0, \quad \nabla_\lambda \mathcal{L} = 0∇xL=0,∇λL=0

几何直觉 :在最优点处,目标函数的梯度与约束函数的梯度平行------沿约束曲面移动不能改善目标。

2.3 不等式约束:KKT 条件

对于不等式约束:

min⁡xf(x)s.t.g(x)≤0\min_{\mathbf{x}} f(\mathbf{x}) \quad \text{s.t.} \quad g(\mathbf{x}) \leq 0xminf(x)s.t.g(x)≤0

拉格朗日函数扩展为:

L(x,μ)=f(x)+μ⋅g(x)\mathcal{L}(\mathbf{x}, \mu) = f(\mathbf{x}) + \mu \cdot g(\mathbf{x})L(x,μ)=f(x)+μ⋅g(x)

KKT(Karush-Kuhn-Tucker)条件是最优解的必要条件:

∇xL=0(平稳性)\nabla_{\mathbf{x}} \mathcal{L} = 0 \quad \text{(平稳性)}∇xL=0(平稳性)

g(x)≤0(可行性)g(\mathbf{x}) \leq 0 \quad \text{(可行性)}g(x)≤0(可行性)

μ≥0(对偶可行性)\mu \geq 0 \quad \text{(对偶可行性)}μ≥0(对偶可行性)

μ⋅g(x)=0(互补松弛)\mu \cdot g(\mathbf{x}) = 0 \quad \text{(互补松弛)}μ⋅g(x)=0(互补松弛)

互补松弛 是最关键的一条:要么 μ=0\mu = 0μ=0(约束不活跃),要么 g(x)=0g(\mathbf{x}) = 0g(x)=0(约束在边界上活跃)。

2.4 对数障碍法:把"墙"变成"坡"

直接求解 KKT 条件在数值上很麻烦(需要处理活跃集)。对数障碍法提供了一种更优雅的方案。

核心思想 :把硬约束 g(x)≤0g(\mathbf{x}) \leq 0g(x)≤0 转化为障碍函数:

ϕ(x)=−1t∑ilog⁡(−gi(x))\phi(\mathbf{x}) = -\frac{1}{t} \sum_{i} \log(-g_i(\mathbf{x}))ϕ(x)=−t1i∑log(−gi(x))

其中 t>0t > 0t>0 是障碍强度参数。

为什么是 log? 因为当 gi(x)→0−g_i(\mathbf{x}) \to 0^-gi(x)→0−(接近约束边界)时:

−log⁡(−gi(x))→+∞-\log(-g_i(\mathbf{x})) \to +\infty−log(−gi(x))→+∞

这就形成了一个"无穷高的墙"------优化器永远不会越过约束边界。

障碍问题:把原问题转化为无约束问题:

min⁡xf(x)+ϕ(x)=min⁡xf(x)−1t∑ilog⁡(−gi(x))\min_{\mathbf{x}} \left f(\\mathbf{x}) + \\phi(\\mathbf{x}) \\right = \min_{\mathbf{x}} \left f(\\mathbf{x}) - \\frac{1}{t} \\sum_i \\log(-g_i(\\mathbf{x})) \\rightxminf(x)+ϕ(x)=xminf(x)−t1i∑log(−gi(x))

关键性质 :当 t→∞t \to \inftyt→∞ 时,障碍问题的解收敛到原约束问题的解 。实践中,我们采用逐步增大 ttt 的策略:

t0<t1<t2<⋯→∞t_0 < t_1 < t_2 < \cdots \to \inftyt0<t1<t2<⋯→∞

每一步都从上一个解出发做牛顿迭代------热启动(Warm Start) ,收敛极快。

2.5 一维示例

考虑一个简单的一维问题:

min⁡xf(x)=(x−2)2s.t.x≤1\min_x f(x) = (x - 2)^2 \quad \text{s.t.} \quad x \leq 1xminf(x)=(x−2)2s.t.x≤1

理想障碍:

I(x)={0x<1+∞x≥1I(x) = \begin{cases} 0 & x < 1 \\ +\infty & x \geq 1 \end{cases}I(x)={0+∞x<1x≥1

对数障碍:

ϕ(x)=−1tlog⁡(1−x)\phi(x) = -\frac{1}{t} \log(1 - x)ϕ(x)=−t1log(1−x)

障碍后的目标函数:

F(x)=(x−2)2−1tlog⁡(1−x)F(x) = (x - 2)^2 - \frac{1}{t} \log(1 - x)F(x)=(x−2)2−t1log(1−x)

当 t=0.5,1,2t = 0.5, 1, 2t=0.5,1,2 时,这个函数的形状会不同------ttt 越大,最优点越接近 x=1x = 1x=1。


三、完整代码(可直接运行)

matlab 复制代码
%% ========================================================================
% 第20篇:凸优化与对数障碍法
% 参考出处:O'Donoughue, "Emitter Detection and Geolocation for EW",
%           ch6_drawFigures.m, Figure 6.2
%           O'Donoughue, "Practical Geolocation for EW using MATLAB",
%           book2_ch5_drawFigures.m, Figure 5.14
%           https://github.com/nodonoughue/emitter-detection-book
% ========================================================================

clear; close all; clc;
rng(2024);

%% ==================== 图1:一维对数障碍的直观 ====================

fprintf('======= 一维对数障碍 =======\n');

% 目标函数:f(x) = (x-2)^2,无约束最优 x=2
% 约束:x <= 1
% 真实约束最优:x* = 1

x_grid = linspace(-3, 0.999, 1000);

% 理想障碍
I_ideal = zeros(size(x_grid));
I_ideal(x_grid > 0) = Inf;   % 硬约束(用边界截断表示)

% 对数障碍(不同 t)
t_set = [0.5, 1, 2, 5];
n_t = numel(t_set);

figure('Name','Fig1 Barrier 1D','Position',[80 80 900 600]);
hold on;

colors = lines(n_t);
for idx = 1:n_t
    t = t_set(idx);
    phi = -1/t * log(1 - x_grid);
    phi(x_grid >= 1) = NaN;   % 定义域限制
    plot(x_grid, phi, 'Color', colors(idx,:), 'LineWidth', 2, ...
        'DisplayName', sprintf('t = %.1f', t));
end

% 理想障碍(红色虚线)
plot([0.999, 1.001], [0, 0], 'k-', 'LineWidth', 3);
plot([1, 1], [0, 10], 'r--', 'LineWidth', 2, 'DisplayName', '理想障碍');

xlabel('x'); ylabel('障碍函数 \phi(x) = -(1/t) log(1-x)');
title('一维对数障碍:从"软坡"到"硬墙"');
legend('Location', 'northwest');
grid on;
xlim([-3, 1.2]); ylim([0, 8]);

% 障碍后的目标函数
figure('Name','Fig1b Barrier Objective','Position',[100 100 900 600]);
hold on;

% 原始目标
f_orig = (x_grid - 2).^2;
plot(x_grid, f_orig, 'k-', 'LineWidth', 2, 'DisplayName', 'f(x) = (x-2)^2');

% 障碍后的目标(不同 t)
for idx = 1:n_t
    t = t_set(idx);
    phi = -1/t * log(1 - x_grid);
    phi(x_grid >= 1) = NaN;
    F_total = f_orig + phi;

    plot(x_grid, F_total, 'Color', colors(idx,:), 'LineWidth', 2, ...
        'DisplayName', sprintf('f + \\phi (t=%.1f)', t));

    % 找最小点
    [~, idx_min] = min(F_total);
    x_min = x_grid(idx_min);
    plot(x_min, F_total(idx_min), 'o', 'Color', colors(idx,:), ...
        'MarkerSize', 12, 'MarkerFaceColor', colors(idx,:), ...
        'HandleVisibility', 'off');
end

xline(1, 'r--', 'LineWidth', 2, 'DisplayName', '约束边界 x=1');
xline(2, 'b:', 'LineWidth', 2, 'DisplayName', '无约束最优 x=2');

xlabel('x'); ylabel('目标函数');
title('对数障碍法:t 越大,最优解越接近约束边界');
legend('Location', 'northeast');
grid on;
xlim([-3, 2.5]); ylim([0, 15]);

% 数值汇总
fprintf('\nt 值对最优解的影响:\n');
fprintf('%-8s %-15s\n', 't', 'x*');
fprintf('--------------------\n');
for idx = 1:n_t
    t = t_set(idx);
    phi = -1/t * log(1 - x_grid);
    phi(x_grid >= 1) = NaN;
    F_total = (x_grid - 2).^2 + phi;
    [~, idx_min] = min(F_total);
    fprintf('%-8.1f %-15.4f\n', t, x_grid(idx_min));
end

%% ==================== 图2:二维无约束优化(复现原书图6.2) ====================

fprintf('\n======= 二维无约束优化 =======\n');

% 目标函数:f(x,y) = (x-1)^2 + 5*(y-0.5)^2
% 全局最优:(1, 0.5)

f2d = @(x, y) (x - 1).^2 + 5*(y - 0.5).^2;

% 四个不同的初始点
x_init = [-3, 2.0;
           2, -1.5;
           1,  2.2;
           1,  0.6];

n_init = size(x_init, 1);

% 梯度下降
alpha = 0.1;         % 步长
max_iter = 100;
tol = 1e-6;

trajectories = cell(n_init, 1);

for i = 1:n_init
    x_curr = x_init(i, :)';
    traj = x_curr';

    for k = 1:max_iter
        % 梯度
        g = [2*(x_curr(1) - 1); 10*(x_curr(2) - 0.5)];

        % 更新
        x_new = x_curr - alpha * g;
        traj = [traj; x_new'];
        x_curr = x_new;

        if norm(g) < tol
            break;
        end
    end
    trajectories{i} = traj;
end

% 绘图
figure('Name','Fig2 Unconstrained 2D','Position',[120 120 900 700]);

% 等高线
x_range = -5:0.05:5;
y_range = -3:0.05:3;
[XX, YY] = meshgrid(x_range, y_range);
FF = f2d(XX, YY);

contour(XX, YY, FF, 20, 'k-', 'LineWidth', 0.8);
hold on;
colormap(gray);

% 真实最优
plot(1, 0.5, 'rp', 'MarkerSize', 20, 'MarkerFaceColor', 'r', ...
    'DisplayName', '全局最优 (1, 0.5)');

% 四条轨迹
colors_traj = lines(n_init);
for i = 1:n_init
    traj = trajectories{i};
    plot(traj(:,1), traj(:,2), 'o-', 'Color', colors_traj(i,:), ...
        'LineWidth', 2, 'MarkerSize', 6, ...
        'DisplayName', sprintf('初始点 %d: (%.1f, %.1f)', ...
        i, x_init(i,1), x_init(i,2)));
end

xlabel('x'); ylabel('y');
title('二维无约束优化:不同初始点收敛到同一全局最优');
legend('Location', 'northeast');
axis equal; grid on;

fprintf('\n各初始点的最终位置:\n');
for i = 1:n_init
    final = trajectories{i}(end, :);
    fprintf('  初始点 %d: (%.1f, %.1f) -> (%.4f, %.4f),迭代 %d 次\n', ...
        i, x_init(i,1), x_init(i,2), final(1), final(2), ...
        size(trajectories{i}, 1) - 1);
end

%% ==================== 图3:二维对数障碍(约束优化) ====================

fprintf('\n======= 二维对数障碍(约束优化) =======\n');

% 目标函数:与图2相同
% 约束:x <= 0.5(目标必须在左半平面)

% 障碍函数:-1/t * log(0.5 - x)
t_barrier = 5;

% 障碍后的目标
F_barrier = @(x, y) f2d(x, y) - (1/t_barrier) * log(0.5 - x);

% 梯度下降(带障碍)
x_init_2d = [-3, 2.0;
              2, -1.5;
              1,  2.2;
              1,  0.6];

trajectories_b = cell(n_init, 1);

for i = 1:n_init
    x_curr = x_init_2d(i, :)';

    % 如果初始点在约束外,先投影回来
    if x_curr(1) >= 0.5
        x_curr(1) = 0.45;
    end

    traj = x_curr';

    for k = 1:max_iter
        % 梯度(含障碍项)
        g_orig = [2*(x_curr(1) - 1); 10*(x_curr(2) - 0.5)];
        g_barrier = [(1/t_barrier) / (0.5 - x_curr(1)); 0];
        g = g_orig + g_barrier;

        % 更新
        x_new = x_curr - alpha * g;

        % 防止越界
        if x_new(1) >= 0.5
            x_new(1) = 0.4999;
        end

        traj = [traj; x_new'];
        x_curr = x_new;

        if norm(g) < tol
            break;
        end
    end
    trajectories_b{i} = traj;
end

% 约束最优:x*=0.5, y*=0.5
fprintf('约束优化真实最优: (0.5, 0.5)\n');

% 绘图
figure('Name','Fig3 Barrier 2D','Position',[140 140 900 700]);

% 绘制无障碍等高线(灰度)
contour(XX, YY, FF, 20, 'Color', [0.7, 0.7, 0.7], 'LineWidth', 0.8);
hold on;

% 绘制障碍后的等高线(彩色)
F_barrier_grid = F_barrier(XX, YY);
F_barrier_grid(XX >= 0.5) = NaN;
contour(XX, YY, F_barrier_grid, 20, 'b-', 'LineWidth', 0.8);

% 标注约束边界
xline(0.5, 'r--', 'LineWidth', 2, 'DisplayName', '约束边界 x=0.5');

% 真实最优(无约束)
plot(1, 0.5, 'kp', 'MarkerSize', 18, 'LineWidth', 2, ...
    'DisplayName', '无约束最优 (1, 0.5)');

% 约束最优
plot(0.5, 0.5, 'rp', 'MarkerSize', 20, 'MarkerFaceColor', 'r', ...
    'DisplayName', '约束最优 (0.5, 0.5)');

% 四条轨迹
colors_traj = lines(n_init);
for i = 1:n_init
    traj = trajectories_b{i};
    plot(traj(:,1), traj(:,2), 'o-', 'Color', colors_traj(i,:), ...
        'LineWidth', 2, 'MarkerSize', 6, ...
        'DisplayName', sprintf('初始点 %d', i));
end

xlabel('x'); ylabel('y');
title(sprintf('二维对数障碍:目标被"推"到约束边界上(t=%.1f)', t_barrier));
legend('Location', 'northeast');
axis equal; grid on;
xlim([-5, 5]); ylim([-3, 3]);

fprintf('\n各初始点的最终位置(约束优化):\n');
for i = 1:n_init
    final = trajectories_b{i}(end, :);
    fprintf('  初始点 %d: (%.1f, %.1f) -> (%.4f, %.4f)\n', ...
        i, x_init_2d(i,1), x_init_2d(i,2), final(1), final(2));
end

%% ==================== 图4:t 增大的效果(内点法) ====================

fprintf('\n======= 对数障碍法:逐步增大 t =======\n');

t_sequence = [0.5, 1, 2, 5, 20];
x_path = zeros(numel(t_sequence), 2);

x_curr = [-3; 2];   % 初始点

for idx = 1:numel(t_sequence)
    t = t_sequence(idx);

    for k = 1:max_iter
        g_orig = [2*(x_curr(1) - 1); 10*(x_curr(2) - 0.5)];
        g_barrier = [(1/t) / (0.5 - x_curr(1)); 0];
        g = g_orig + g_barrier;

        x_new = x_curr - alpha * g;
        if x_new(1) >= 0.5
            x_new(1) = 0.4999;
        end
        x_curr = x_new;

        if norm(g) < tol
            break;
        end
    end

    x_path(idx, :) = x_curr';
    fprintf('  t = %5.1f -> 解 (%.4f, %.4f)\n', t, x_curr(1), x_curr(2));
end

figure('Name','Fig4 Increasing t','Position',[160 160 900 700]);

contour(XX, YY, FF, 20, 'Color', [0.7, 0.7, 0.7], 'LineWidth', 0.8);
hold on;

F_bg = @(x, y) f2d(x, y) - (1/20) * log(0.5 - x);
F_bg_grid = F_bg(XX, YY);
F_bg_grid(XX >= 0.5) = NaN;
contour(XX, YY, F_bg_grid, 20, 'b-', 'LineWidth', 0.8);

xline(0.5, 'r--', 'LineWidth', 2, 'DisplayName', '约束边界');

plot(1, 0.5, 'kp', 'MarkerSize', 18, 'LineWidth', 2, 'DisplayName', '无约束最优');
plot(0.5, 0.5, 'rp', 'MarkerSize', 20, 'MarkerFaceColor', 'r', ...
    'DisplayName', '约束最优');

% 路径
for idx = 1:numel(t_sequence)
    if idx > 1
        plot([x_path(idx-1,1), x_path(idx,1)], ...
             [x_path(idx-1,2), x_path(idx,2)], 'k-', 'LineWidth', 1.5, ...
             'HandleVisibility', 'off');
    end
end

scatter(x_path(:,1), x_path(:,2), 100, 1:numel(t_sequence), 'filled');
colormap(jet);
colorbar;
clim([0, numel(t_sequence)+1]);

xlabel('x'); ylabel('y');
title('对数障碍法:逐步增大 t 逼近约束最优');
legend('Location', 'northeast');
axis equal; grid on;
xlim([-5, 5]); ylim([-3, 3]);

%% ==================== 图5:对数障碍 vs 理想障碍(一维详细对比) ====================

fprintf('\n======= 对数障碍 vs 理想障碍 =======\n');

x_grid = linspace(-3, 0.999, 500);

figure('Name','Fig5 Barrier Comparison','Position',[180 180 900 700]);

% 子图1:理想障碍
subplot(1,3,1);
hold on;
% 理想障碍
plot([-3, 1], [0, 0], 'b-', 'LineWidth', 3);
plot([1, 1], [0, 10], 'r-', 'LineWidth', 3);
plot(1, 10, 'r^', 'MarkerSize', 15, 'MarkerFaceColor', 'r');
xlabel('x'); ylabel('障碍函数');
title('理想障碍');
grid on; xlim([-3, 1.5]); ylim([-1, 11]);
legend('0(可行域内)', '+\infty(不可行)', 'Location', 'northwest');

% 子图2:不同 t 的对数障碍
subplot(1,3,2);
hold on;
t_set = [0.5, 2, 10];
colors = lines(numel(t_set));
for idx = 1:numel(t_set)
    t = t_set(idx);
    phi = -1/t * log(1 - x_grid);
    phi(x_grid >= 1) = NaN;
    plot(x_grid, phi, 'Color', colors(idx,:), 'LineWidth', 2, ...
        'DisplayName', sprintf('t = %.1f', t));
end
xlabel('x'); ylabel('对数障碍');
title('对数障碍(不同 t)');
grid on; xlim([-3, 1.5]); ylim([-0.5, 5]);
legend('Location', 'northwest');

% 子图3:t → ∞ 的极限
subplot(1,3,3);
hold on;
plot([-3, 1], [0, 0], 'b-', 'LineWidth', 3);
plot([1, 1], [0, 10], 'r--', 'LineWidth', 3);
for idx = 1:numel(t_set)
    t = t_set(idx);
    phi = -1/t * log(1 - x_grid);
    phi(x_grid >= 1) = NaN;
    plot(x_grid, phi, 'Color', colors(idx,:), 'LineWidth', 2, ...
        'HandleVisibility', 'off');
end
xlabel('x'); ylabel('障碍函数');
title('t \rightarrow \infty 时逼近理想障碍');
grid on; xlim([-3, 1.5]); ylim([-0.5, 5]);
legend('理想障碍', 'Location', 'northwest');

sgtitle('对数障碍法:从"软坡"到"硬墙"', ...
    'FontSize', 14, 'FontWeight', 'bold');

fprintf('\n======= 全部完成 =======\n');

四、代码讲解:为什么这么写?

4.1 图1:为什么 ttt 越大,最优解越接近边界?

matlab 复制代码
phi = -1/t * log(1 - x_grid);

物理解释 :ttt 控制"障碍的陡峭程度":

  • ttt 小 → 障碍平缓,优化器可以"偷懒"远离边界;
  • ttt 大 → 障碍陡峭,优化器被"挤"到边界上。

数学解释 :最优解满足 ∇f+∇ϕ=0\nabla f + \nabla \phi = 0∇f+∇ϕ=0,即:

2(x−2)+1t⋅11−x=02(x - 2) + \frac{1}{t} \cdot \frac{1}{1 - x} = 02(x−2)+t1⋅1−x1=0

当 t→∞t \to \inftyt→∞ 时,第二项 →0\to 0→0,最优解趋近于约束边界 x=1x = 1x=1。

4.2 图2:为什么无约束优化能收敛到全局最优?

matlab 复制代码
g = [2*(x_curr(1) - 1); 10*(x_curr(2) - 0.5)];
x_new = x_curr - alpha * g;

关键 :f(x,y)=(x−1)2+5(y−0.5)2f(x,y) = (x-1)^2 + 5(y-0.5)^2f(x,y)=(x−1)2+5(y−0.5)2 是凸函数 (二次型,Hessian 正定)。凸函数的梯度下降保证收敛到全局最优------不管初始点在哪里。

四条轨迹的对比 :从 (−3,2)(-3, 2)(−3,2)、(2,−1.5)(2, -1.5)(2,−1.5)、(1,2.2)(1, 2.2)(1,2.2)、(1,0.6)(1, 0.6)(1,0.6) 出发,最终都收敛到 (1,0.5)(1, 0.5)(1,0.5)------这就是凸优化的魅力。

4.3 图3:二维对数障碍的"推挤"效应

matlab 复制代码
g_barrier = [(1/t_barrier) / (0.5 - x_curr(1)); 0];

注意 :障碍项只对 xxx 方向有梯度------因为约束是 x≤0.5x \leq 0.5x≤0.5,与 yyy 无关。

物理图像 :优化器在 xxx 方向被"推"向 x=0.5x = 0.5x=0.5,在 yyy 方向仍然自由地走向 y=0.5y = 0.5y=0.5。最终停在 (0.5,0.5)(0.5, 0.5)(0.5,0.5)------约束边界上的最优解。

4.4 图4:为什么 ttt 要逐步增大?

matlab 复制代码
t_sequence = [0.5, 1, 2, 5, 20];

数值原因 :如果直接从 t=∞t = \inftyt=∞(硬约束)开始,问题会变成"求解 KKT 系统"------这需要活跃集识别,数值上很麻烦。

逐步增大 ttt的策略叫内点法(Interior Point Method) :

  1. 先用小 ttt 求解,得到一个"还凑合"的解;
  2. 增大 ttt,用上一个解作为初始点(热启动);
  3. 重复直到 ttt 足够大,解足够接近约束边界。

优势 :每步都是无约束优化,用牛顿法或梯度下降都能快速收敛。这是现代凸优化求解器(如 CVX、MOSEK)的核心算法。

4.5 图5:对数障碍 vs 理想障碍

理想障碍 在边界处从 0 跳变 到 +∞+\infty+∞------不连续、不可导,无法用梯度方法。

对数障碍 在边界处光滑趋于 +∞+\infty+∞------连续、可导,适合梯度方法。

代价 :对数障碍允许解"稍微越界一点点"------但通过增大 ttt 可以把这点"越界"压到任意小。


五、运行结果解读

运行代码后,你将看到 5 张图:

图1:一维对数障碍

  • 左图 :不同 ttt 对应的障碍函数。ttt 越大,曲线越陡------t=5t = 5t=5 时几乎和理想障碍一样陡;
  • 右图 :障碍后的目标函数 f+ϕf + \phif+ϕ。可以看到最小值点随 ttt 增大向右移动 ,最终逼近 x=1x = 1x=1。

图2:二维无约束优化

四条彩色轨迹从不同初始点出发,最终都收敛到红色五角星(1, 0.5)------凸优化的全局收敛性。

图3:二维对数障碍

  • 灰色等高线:原始目标函数;
  • 蓝色等高线:障碍后的目标函数;
  • 红色虚线 :约束边界 x=0.5x = 0.5x=0.5;
  • 红色五角星 :约束最优 (0.5,0.5)(0.5, 0.5)(0.5,0.5)。

四条轨迹都被"推"到边界上------这是对数障碍法的核心特征。

图4:逐步增大 ttt

彩色圆点从深蓝(t=0.5t=0.5t=0.5)渐变到红色(t=20t=20t=20),显示解沿一条路径逐步逼近约束边界。这就是内点法的"中心路径"。

图5:对数障碍 vs 理想障碍

三张子图并排对比:

  • 左:理想障碍(不可导);
  • 中 :对数障碍(t=0.5,2,10t=0.5, 2, 10t=0.5,2,10);
  • 右 :t→∞t \to \inftyt→∞ 时对数障碍逼近理想障碍。

六、工程实战的四条准则

准则 数学依据 工程做法
1. 凸问题优先 局部最优 = 全局最优 尽量把问题表述成凸优化
2. 对数障碍处理不等式 光滑化硬约束 用 -1/t * log(-g(x))
3. ttt 逐步增大 内点法收敛性 t *= 2 或 t *= 10
4. 热启动加速 相邻问题的解接近 用上一个解作为下一步初值

七、延伸思考

7.1 与拉格朗日乘子法的关系

对数障碍法和拉格朗日乘子法是对偶的:

  • 拉格朗日法 :引入乘子 μ\muμ,把约束"加入"目标;
  • 障碍法:引入障碍函数,把约束"吸收"到目标。

在最优点处,两者等价:μi=1/(t⋅(−gi))\mu_i = 1/(t \cdot (-g_i))μi=1/(t⋅(−gi))。

7.2 约束优化在定位中的应用

场景一:目标必须在地面上

目标高度约束 z≥0z \geq 0z≥0:

min⁡∥z−h(x)∥2s.t.−z≤0\min \|\mathbf{z} - \mathbf{h}(\mathbf{x})\|^2 \quad \text{s.t.} \quad -z \leq 0min∥z−h(x)∥2s.t.−z≤0

场景二:目标必须在某个多边形内

多边形约束 Ax≤bA\mathbf{x} \leq bAx≤b:

min⁡∥z−h(x)∥2s.t.Ax≤b\min \|\mathbf{z} - \mathbf{h}(\mathbf{x})\|^2 \quad \text{s.t.} \quad A\mathbf{x} \leq bmin∥z−h(x)∥2s.t.Ax≤b

场景三:目标速度有限

速度约束 ∥v∥≤vmax\|\mathbf{v}\| \leq v_{max}∥v∥≤vmax:

min⁡∥z−h(x)∥2s.t.∥v∥2−vmax2≤0\min \|\mathbf{z} - \mathbf{h}(\mathbf{x})\|^2 \quad \text{s.t.} \quad \|\mathbf{v}\|^2 - v_{max}^2 \leq 0min∥z−h(x)∥2s.t.∥v∥2−vmax2≤0

7.3 与后续篇章的关系

本篇讲的是静态优化 ------对一个时刻的状态做约束优化。第21篇我们将进入扩展卡尔曼滤波(EKF) ------把贝叶斯估计推广到动态系统。届时你会看到:

  • 预测步:用状态方程传播先验;
  • 更新步:用观测数据修正后验;
  • 约束:在 EKF 中也可以用对数障碍或投影方法处理。

下一篇预告(第21篇):扩展卡尔曼滤波(EKF)与动态跟踪

静止目标的定位只是起点。当目标以 300 m/s 飞行时,你要处理的不是"一个点",而是一条轨迹 。扩展卡尔曼滤波(EKF) 是动态跟踪的标准工具:

  • 状态方程 :xk+1=Fxk+wk\mathbf{x}_{k+1} = \mathbf{F}\mathbf{x}_k + \mathbf{w}_kxk+1=Fxk+wk(目标如何运动);
  • 观测方程 :zk=h(xk)+vk\mathbf{z}_k = \mathbf{h}(\mathbf{x}_k) + \mathbf{v}_kzk=h(xk)+vk(我们能测到什么);
  • 更新:贝叶斯公式的递归实现(先验 → 后验)。

我们将用 MATLAB 完整实现 EKF 跟踪 :从目标的匀速直线运动开始,逐步加入 AOA/TDOA 观测,画出目标轨迹与估计轨迹的对比 ,并分析 EKF 在几何退化下的稳定性。同时解析原书 book2 第7章(图7.1~7.5、7.8a/b)。敬请期待!

相关推荐
Wang's Blog1 小时前
Java框架 SpringCloud 快速入门: 服务拆分案例 Demo
java·开发语言·spring cloud
小小龙学IT1 小时前
Python SQLAlchemy 2.0 深度解析:从 Core 到 ORM 的数据访问双引擎
开发语言·数据库·python
2601_962885721 小时前
如何用 Python 计算 ROC 变动率指标做动量分析?
开发语言·python·算法
潼心1412o2 小时前
C++初阶(长期更新)第9讲:string(上)
开发语言·c++
朝朝辞暮i2 小时前
C++ 第 39 章: 阶段性总复习——类、对象、构造、继承、this、指针与智能指针
开发语言·c++·算法·ros2
掉进电商坑三年没爬出来的东叔2 小时前
青龙面板进阶:一个面板聚合多平台签到,所有积分自动领
java·开发语言
iCxhust3 小时前
51单片机电力载波应用开发(七)广播通讯
c语言·开发语言·单片机·嵌入式硬件·51单片机
殷色玫瑰3 小时前
C++ STL:stack、queue、priority_queue 与容器适配器详解
java·开发语言·数据结构·c++·算法·visualstudio
IT方大同3 小时前
java输入输出+方法
java·开发语言·python