最优化问题 - 内点法
以下是一种循序推理的方式,来帮助你从基础概念出发,理解 内点法(Interior-Point Method, IPM) 是什么、为什么要用它,以及它是如何工作的。
1. 问题起点:带不等式约束的优化
假设你有一个带不等式约束的优化问题:
min x f ( x ) subject to g i ( x ) ≤ 0 , i = 1 , … , m . \begin{aligned} &\min_{x} \quad f(x) \\ &\text{subject to } \quad g_i(x) \le 0, \quad i=1,\ldots,m. \end{aligned} xminf(x)subject to gi(x)≤0,i=1,…,m.
- f ( x ) f(x) f(x):目标函数
- g i ( x ) ≤ 0 g_i(x) \le 0 gi(x)≤0:不等式约束(例如,控制输入不能超范围)
我们想要找到一个满足所有约束且使目标函数最小的点 x ∗ x^* x∗。
2. 直接在边界上“走”的困难
一种思路是:最优点往往在可行域边界上(很多经典优化问题里,最优解会出现在约束生效的边界)。
- 但是,如果我们只在边界上“走”,常常要先找到并跟随所有活跃约束的交线,这在高维情况下非常复杂。
- 并且,如果问题是非线性的,直接处理“在边界上走”会更难,容易出现数值不稳定或无法收敛的问题。
3. 想法:能不能“在里面”搜索,最后再逼近边界?
为了避免“一上来就卡在边界”,有人提出:
- 先在可行域内部(所有约束 g i ( x ) < 0 g_i(x) < 0 gi(x)<0 都“宽裕”)附近做搜索,那里没有太多束缚,比较容易用连续的梯度法去迭代寻优;
- 当我们逐渐找到一个更优解,需要靠近边界时,再“慢慢地”逼近它。
这样做,就不需要每一步都严格跟在边界上,也能保证可行性(不跑到约束外面去)。
4. 内点法的关键:障碍函数(Barrier Function)
为在域内部搜索,需要一种数学手段,让解“自动”不跑出界。这时就引入了障碍函数。
4.1 形式:对约束加一个“负对数”项
对每个不等式约束 g i ( x ) ≤ 0 g_i(x)\le0 gi(x)≤0,定义一个项:
− log ( − g i ( x ) ) . -\log(-g_i(x)). −log(−gi(x)).
- 如果 g i ( x ) < 0 g_i(x) < 0 gi(x)<0,那么 − g i ( x ) > 0 -g_i(x) > 0 −gi(x)>0,对数是可以求的。
- 一旦 g i ( x ) g_i(x) gi(x) 接近 0(也就是接近边界), − g i ( x ) -g_i(x) −gi(x) 趋向 0,这个对数会趋向 − ∞ -\infty −∞,但我们在目标函数中是带一个负号“-”,变成了一个正无穷大的惩罚。
- 这样一来,就相当于在可行域的边缘设置了一道**“墙”,越靠近边界,代价就越大,解被迫**留在可行域内部。
4.2 组合成“障碍型”目标函数
把原本的目标函数 f ( x ) f(x) f(x) 和障碍项结合:
B ( x , μ ) = f ( x ) − μ ∑ i = 1 m log ( − g i ( x ) ) . B(x, \mu) = f(x) - \mu \sum_{i=1}^m \log\bigl(-g_i(x)\bigr). B(x,μ)=f(x)−μi=1∑mlog(−gi(x)).
- μ > 0 \mu > 0 μ>0 是一个系数,称为“障碍参数(barrier parameter)”。
- 当 μ \mu μ 较大时,障碍惩罚也大,解就离约束边界更远;当我们逐渐减小 μ \mu μ,系统会允许解更靠近边界。
5. 迭代逼近最优解
内点法并不是一次就把问题解决,而是:
- 从一个“较宽松”的问题开始( μ \mu μ 比较大,边界惩罚很强)。
- 求解 min x B ( x , μ ) \min_x B(x, \mu) minxB(x,μ),得到一个可行域内部的解。
- 降低 μ \mu μ 的值,重新求解,这时可以允许解更加靠近(或到达)真正的最优边界。
- 多次迭代后, μ → 0 \mu \to 0 μ→0,解会逼近真实最优解。
这一过程里,算法会用到类似于 牛顿法、KKT 条件 等工具来求解各轮的子问题。
6. 内点法 vs. 其他方法
- 单纯形法(Simplex):在可行域的“顶点—边界—面”上走,比较适合线性规划;但在高维非线性问题上,效率可能较低。
- 内点法:通过“障碍函数”把解留在域内部,逐渐往边界逼近,常在非线性规划(NLP)中表现更好,也更适合大规模问题。
7. 在 MPC 中的应用
MPC 求解器(如 IPOPT)正是利用内点法来处理:
- 多步预测的系统动力学约束
- 输入/状态上下限
- 非线性目标函数
让无人机等系统在高维空间里高效地搜索最优控制输入。
🔑 小结:内点法的一句话总结
内点法是一种在可行域“内部”迭代搜索的求解策略,通过“障碍函数”阻挡解跑出可行域,并逐步放松障碍参数,最终逼近最优解和约束边界。
这就是内点法的核心“推理过程”:与其从边界开始,不如在“里层”走,让数值算法更稳定,再慢慢让解贴近约束边界,从而找到最优。
下面我将针对这段代码的逻辑和实现细节,结合“内点法(障碍函数) + 固定步长梯度下降”这一思路,做一个比较细致的解析。
1. 整体思路与算法框架
目标问题(从注释和注解上看)是:
min f ( x ) = x 1 + x 2 + x 3 s.t. x 1 2 + x 2 2 + x 3 2 ≤ 1. \begin{aligned} &\min \quad f(x) = x_1 + x_2 + x_3 \\ &\text{s.t.} \quad x_1^2 + x_2^2 + x_3^2 \;\le\; 1. \end{aligned} minf(x)=x1+x2+x3s.t.x12+x22+x32≤1.
-
可行域是单位球 { x ∈ R 3 : ∥ x ∥ ≤ 1 } \{x \in \mathbb{R}^3 : \|x\|\le 1 \} {x∈R3:∥x∥≤1};
-
希望用内点法来解决不等式约束 x 1 2 + x 2 2 + x 3 2 ≤ 1 x_1^2 + x_2^2 + x_3^2 \le 1 x12+x22+x32≤1。
通常在内点法中,会把不等式 (g(x) \le 0)(这里 g ( x ) = x 2 + y 2 + z 2 − 1 g(x)=x^2+y^2+z^2 -1 g(x)=x2+y2+z2−1 )转写成形如 (h(x) > 0),再将 (\log h(x)) 当作障碍项(barrier)。本例里定义
h ( x ) = 1 − ( x 1 2 + x 2 2 + x 3 2 ) , h(x) = 1 - (x_1^2 + x_2^2 + x_3^2), h(x)=1−(x12+x22+x32),
于是 h ( x ) > 0 h(x) > 0 h(x)>0等价于 x 1 2 + x 2 2 + x 3 2 < 1 x_1^2 + x_2^2 + x_3^2 < 1 x12+x22+x32<1。 -
内点法的障碍目标函数定义为
B ( x , μ ) = f ( x ) − μ ln ( h ( x ) ) , B(x,\mu) \;=\; f(x)\;-\;\mu \,\ln\bigl(h(x)\bigr), B(x,μ)=f(x)−μln(h(x)),
其中 μ > 0 \mu>0 μ>0 是障碍系数(barrier parameter)。 μ \mu μ 越小, − μ log h ( x ) -\mu \log h(x) −μlogh(x)的惩罚作用越强,最终会将可行解“推”到最接近边界的最优位置上。 -
在固定一个 μ \mu μ 的情况下,常用牛顿法或梯度法去最小化 B ( x , μ ) B(x,\mu) B(x,μ) 。在算法外层循环中,则逐步减小 μ \mu μ(比如乘个衰减因子),让解逐步逼近约束边界并最终得到较准确的可行最优解。
在这份代码中:
-
外层循环 (共
max_outer
次):- 每次先用当前 μ \mu μ 在球内做若干步梯度下降,尝试求解 min B ( x , μ ) \min B(x,\mu) minB(x,μ);
- 之后衰减 μ \mu μ ← \leftarrow ← μ ⋅ \mu \cdot μ⋅ (mu_decay) \text{(mu\_decay)} (mu_decay),进入下一轮;
- 重复,直到 μ \mu μ 足够小或者达到外层迭代上限。
-
内层循环 (共
max_inner
次):- 计算当前 B B B 的梯度 ∇ B ( x , μ ) \nabla B(x,\mu) ∇B(x,μ);
- 做一步固定步长的梯度下降: x ← x − α ∇ B ( x , μ ) x \leftarrow x - \alpha \nabla B(x,\mu) x←x−α∇B(x,μ);
- 如果发现新点 x new x_{\text{new}} xnew不可行(或者离边界过近),就缩小步长再试;
- 如果两次迭代 ∥ x new − x ∥ \|x_{\text{new}} - x\| ∥xnew−x∥ 非常小(<
tol
),就视为收敛并 break。
这样就得到一条渐进接近最优解的迭代轨迹,存放在 x_history
中。
2. 代码主干解析
从最外层开始看起,核心部分在函数
function x_history = interior_point_3d_solve()% 参数mu_init = 1.0; % 初始障碍参数mu_decay = 0.2; % 每轮迭代后 mu 的衰减因子alpha = 0.001; % 固定梯度下降步长tol = 1e-6; % 收敛判据max_outer= 10; % 外层循环次数max_inner= 50; % 每次 mu 下最大内层迭代次数% 初始化可行解(球内)x = [0;0;0]; mu = mu_init;x_history = [];for outer = 1:max_outerfor inner = 1:max_innerg = grad_B(x, mu); x_new = x - alpha*g;% 若越过球边界 => h(x_new) <= 0if h_3d(x_new) <= 1e-9x_new = x - 0.1*alpha*g; % 缩小步长再试end% 收敛判断if norm(x_new - x) < tolx = x_new;break; % 跳出内层循环endx = x_new;x_history = [x_history; x']; end% 减小 mumu = mu * mu_decay;if mu < 1e-12break; % mu 已经很小,不必再迭代endend% 加入最终点x_history = [x_history; x'];
end
mu_init
设为 1.0,之后每次外层循环会mu = mu * mu_decay
,即乘以 0.2。这样大概迭代几次后就会让mu
变得很小。alpha=0.001
是固定的梯度下降步长,相对比较小,所以我们用到max_inner=50
步来让它收敛到一个合适精度。- 收敛阈值
tol=1e-6
:若相邻两步 ∥ x new − x ∥ \|x_{\text{new}}-x\| ∥xnew−x∥ 小于这个值,就认为内层已经收敛。 - 每次更新
x
后都会把它记录到x_history
里,用于可视化迭代轨迹。
这里值得注意的是:如果单纯用固定步长,可能碰到越过可行域边界(即 (x2+y2+z^2>1))的风险。为此,代码做了一个简单检查:
if h_3d(x_new) <= 1e-9x_new = x - 0.1*alpha*g; % 步长缩小10倍
end
当然,这只是一个很“简单粗暴”的处理,工业级内点法通常要做更精细的线搜索或牛顿校正,这里是为了示例演示。
3. 障碍函数与梯度的计算
3.1 h_3d(x)
function val = h_3d(x)val = 1.0 - (x(1)^2 + x(2)^2 + x(3)^2);
end
即 h ( x ) = 1 − r 2 h(x) = 1 - r^2 h(x)=1−r2,其中 r 2 = x 1 2 + x 2 2 + x 3 2 r^2 = x_1^2 + x_2^2 + x_3^2 r2=x12+x22+x32。球内保证 h ( x ) > 0 h(x)>0 h(x)>0。
3.2 B_3d(x, mu)
function val = B_3d(x, mu)val = f_3d(x) - mu*log(h_3d(x));
end
对应障碍目标 B ( x , μ ) = f ( x ) − μ ln ( h ( x ) ) B(x,\mu) = f(x) - \mu\ln(h(x)) B(x,μ)=f(x)−μln(h(x))。
3.3 grad_B(x, mu)
的推导
从数学上看,如果
B ( x , μ ) = f ( x ) − μ ln ( h ( x ) ) , B(x,\mu) \;=\; f(x) \;-\; \mu \,\ln\bigl(h(x)\bigr), B(x,μ)=f(x)−μln(h(x)),
则其梯度为
∇ B ( x , μ ) = ∇ f ( x ) − μ ∇ ln ( h ( x ) ) . \nabla B(x,\mu) = \nabla f(x) \;-\; \mu \,\nabla \ln\bigl(h(x)\bigr). ∇B(x,μ)=∇f(x)−μ∇ln(h(x)).
其中
∇ ln ( h ( x ) ) = 1 h ( x ) ∇ h ( x ) . \nabla \ln(h(x)) = \frac{1}{h(x)} \nabla h(x). ∇ln(h(x))=h(x)1∇h(x).
而 (h(x) = 1 - r^2),(\nabla h(x) = -2x)。所以
∇ ln ( h ( x ) ) = − 2 x 1 − r 2 . \nabla \ln(h(x)) = \frac{-2x}{1-r^2}. ∇ln(h(x))=1−r2−2x.
带上负号“ − μ -\mu −μ”一起,就得到对障碍项的贡献为 + 2 μ x 1 − r 2 +\frac{2\mu x}{1 - r^2} +1−r22μx。
如果我们要最小化 f ( x ) = x 1 + x 2 + x 3 f(x)= x_1 + x_2 + x_3 f(x)=x1+x2+x3,其梯度就是 ( 1 , 1 , 1 ) (1,1,1) (1,1,1)。
于是
∇ B ( x , μ ) = ( 1 , 1 , 1 ) + 2 μ 1 − r 2 ( x 1 , x 2 , x 3 ) . \nabla B(x,\mu) = \bigl(1,1,1\bigr) + \frac{2\mu}{1-r^2}\,\bigl(x_1,x_2,x_3\bigr). ∇B(x,μ)=(1,1,1)+1−r22μ(x1,x2,x3).
在代码中,可以看到:
function g = grad_B(x, mu)hx = h_3d(x); % 1 - r^2dB_dx0 = 1.0 + (2.0 * mu * x(1) / hx);dB_dx1 = 1.0 + (2.0 * mu * x(2) / hx);dB_dx2 = 1.0 + (2.0 * mu * x(3) / hx);g = [dB_dx0; dB_dx1; dB_dx2];
end
正好对应上面的公式:1.0
就是 ∇ f ( x ) \nabla f(x) ∇f(x) 的那一部分, ( 2.0 ∗ m u ∗ x ( i ) / h x ) (2.0*mu*x(i)/hx) (2.0∗mu∗x(i)/hx) 对应障碍项梯度那一部分。
4. 运行与结果
如果修正了 f_3d
,那么在球内最小化 (x+y+z) 的最优解,理论上会落在球面上与 ((1,1,1)) 方向相反的地方,也就是球面朝着 ((-1,-1,-1)) 的方向。其最优解应当是
( − 1 3 , − 1 3 , − 1 3 ) \left(-\frac{1}{\sqrt{3}}, \;-\frac{1}{\sqrt{3}}, \;-\frac{1}{\sqrt{3}}\right) (−31,−31,−31)
因为在约束 x 2 + y 2 + z 2 = 1 x^2+y^2+z^2=1 x2+y2+z2=1 上,(x+y+z) 的最小值就是 − 3 -\sqrt{3} −3。迭代跑起来后,你应该能看到解最终趋近这个点,轨迹会从球心出发,一路在球内前进,并在迭代后期逐渐贴近球面。
如果把可视化部分加上(即下面这段示例):
x_history = interior_point_3d_solve();figure('Color','w','Name','Interior-Point 3D Demo');
hold on; grid on; axis equal;% 绘制单位球面
[Xs, Ys, Zs] = sphere(50);
surf(Xs, Ys, Zs, ...'FaceAlpha',0.1, 'EdgeColor','none', 'FaceColor','c');xlabel('x_0'); ylabel('x_1'); zlabel('x_2');
title('Minimize x_0 + x_1 + x_2 subject to x_0^2 + x_1^2 + x_2^2 \le 1');% 画迭代轨迹
x0_hist = x_history(:,1);
x1_hist = x_history(:,2);
x2_hist = x_history(:,3);
plot3(x0_hist, x1_hist, x2_hist, 'b-o','LineWidth',1.5);% 最后一点标红
plot3(x0_hist(end), x1_hist(end), x2_hist(end), ...'ro', 'MarkerSize',8, 'MarkerFaceColor','r');legend('Unit Sphere','Iter Process','Final Solution');
view(35,25);
就能看到一个球面和从原点出发,沿着负对角线方向慢慢收敛到球面那一点的轨迹。
5. 小结
-
内点法原理:通过把约束 x 1 2 + x 2 2 + x 3 2 ≤ 1 x_1^2 + x_2^2 + x_3^2 \le 1 x12+x22+x32≤1 转化为对数障碍 − μ ln ( 1 − r 2 ) -\mu \ln\bigl(1 - r^2\bigr) −μln(1−r2),并在外层迭代不断减小 μ \mu μ。这能保证迭代点始终在球内 ( h ( x ) > 0 h(x) > 0 h(x)>0),同时在 μ → 0 \mu\to0 μ→0 时逐渐收敛到可行域边界上的最优点。
-
实现细节:
- 用固定步长 + 简单可行性校正(越界时缩步长);
- 用
max_outer
与max_inner
控制多重循环; - 用
tol
判断迭代收敛; - 在每次迭代都记录
x
到x_history
中,用于可视化。
-
需要修正的地方:
代码中的f_3d(x)
与注释/梯度公式不一致,应改回function val = f_3d(x)val = x(1) + x(2) + x(3); end
这样才与“最小化 (x+y+z)”的需求相吻合。
修正后运行,即可得到一个从球心(原点)出发,最终靠近 ( − 1 3 , − 1 3 , − 1 3 ) \bigl(-\frac{1}{\sqrt{3}},-\frac{1}{\sqrt{3}},-\frac{1}{\sqrt{3}}\bigr) (−31,−31,−31) 的迭代过程。
参考:为什么最优解是 ( − 1 / 3 , − 1 / 3 , − 1 / 3 ) \bigl(-1/\sqrt{3},-1/\sqrt{3},-1/\sqrt{3}\bigr) (−1/3,−1/3,−1/3)?
因为在单位球约束下,若要最小化 x 1 + x 2 + x 3 x_1+x_2+x_3 x1+x2+x3,相当于“在球面上找与(1,1,1)方向夹角最大的点”——也就是与 ( 1 , 1 , 1 ) (1,1,1) (1,1,1) 反方向的单位向量。它正好是 − 1 3 ( 1 , 1 , 1 ) \frac{-1}{\sqrt{3}}(1,1,1) 3−1(1,1,1)。目标值是
x 1 + x 2 + x 3 = − 3 . x_1 + x_2 + x_3 = -\sqrt{3}. x1+x2+x3=−3.
这与几何直觉、拉格朗日乘子法都能得到一样的结果。
6. 结语
- 该代码很好地演示了使用对数障碍(log-barrier)的内点法思路:用一系列的无约束子问题(带障碍项)来逼近有约束优化,并在外层迭代中逐渐减小障碍系数 (\mu),使解贴近约束边界的最优解。
- 不过,在正式应用时,往往不会用固定步长的简单梯度下降,而会用牛顿法或线搜索,以获得更好的数值稳定性和收敛速度。
- 代码本身最大的问题是
f_3d
与注释/公式不匹配,只要改回f_3d(x) = x(1)+x(2)+x(3)
即可与文档保持一致,也能正确体现“最小化 ∑ x i \sum x_i ∑xi”的意图。
在使用对数障碍(log‐barrier)形式的内点法时, μ \mu μ(有时也记作 t t t 或 ν \nu ν)通常被称为障碍参数(barrier parameter)。它的核心作用是:
-
控制对数障碍项的“强度”
在障碍型目标函数
B ( x , μ ) = f ( x ) − μ ln ( h ( x ) ) B(x,\mu) \;=\; f(x)\;-\;\mu \,\ln\bigl(h(x)\bigr) B(x,μ)=f(x)−μln(h(x))
中,(\mu) 决定了 (-\mu \ln\bigl(h(x)\bigr)) 这部分惩罚力度的大小。- 当 (\mu) 较大时,对(\ln(h(x)))的惩罚力度相对较小,算法对靠近约束边界的“敏感度”不高,所以在收敛初期可以更自由地在可行域里移动。
- 当 (\mu) 变小时,(-\mu \ln(h(x)))会变得更尖锐,迫使解更加贴近且“贴合”可行域的边界(若这是最优解所在的位置)。
-
帮助逐步逼近最优解并保持可行
内点法的思路是:一开始用较大的 (\mu)(障碍作用较弱)来保证算法稳步地在可行域里进行搜索;之后在外层循环中逐步减小 (\mu),使对数障碍项逐渐变得陡峭,从而把解“推”到真正需要的边界附近并逼近最优解。 -
数值上的平衡
- 如果 (\mu) 过小,一开始 (-\mu \ln(h(x))) 的势垒就会非常强,导致很难在可行域里移动,且容易产生数值不稳定(如(\ln(h(x)))趋向负无穷)。
- 如果 (\mu) 过大,到收敛后期也无法精确地在边界附近找到最优解。所以通常会有一条**“(\mu)衰减”路径**(比如 (\mu \leftarrow \beta \mu),(\beta<1))来让解逐步逼近最优值。
简而言之:(\mu) 是控制“障碍强度”的调节器。随着 (\mu) 从大到小的不断衰减,解会逐渐向可行域边界靠拢并最终获得精确的约束最优解。
完整代码
function x_history = interior_point_3d_solve()
%{使用内点法(障碍函数 + 固定步长梯度下降)求解:min f(x) = x(1) + x(2) + x(3)s.t. x(1)^2 + x(2)^2 + x(3)^2 <= 1.内点法: 定义障碍型目标B(x, mu) = f(x) - mu * log( h(x) ), 其中h(x) = 1 - (x0^2 + x1^2 + x2^2).输出:x_history: 每个迭代得到的 (x0, x1, x2).
%}% 参数mu_init = 1.0; % 初始障碍参数mu_decay = 0.2; % 每轮迭代后 mu 的衰减因子alpha = 0.001; % 梯度下降步长tol = 1e-6; % 收敛阈值max_outer = 10; % 外层循环(更新 mu)次数max_inner = 50; % 每次 mu 下最大迭代次数% 初始化可行解 (x0, x1, x2),球内,例如原点x = [0; 0; 0]; mu = mu_init;x_history = [];for outer = 1:max_outerfor inner = 1:max_innerg = grad_B(x, mu); % 计算梯度x_new = x - alpha*g;% 如果越过球边界 => h(x_new) <= 0 => x_new^2+y^2+z^2 >=1% 简单地缩小步长再试if h_3d(x_new) <= 1e-9x_new = x - 0.1*alpha*g;end% 收敛判断if norm(x_new - x) < tolx = x_new;break;endx = x_new;x_history = [x_history; x']; % 记录轨迹(行向量)end% 降低 mu 使解更逼近约束边界mu = mu * mu_decay;if mu < 1e-12break;endend% 最后再将最终点加入x_history = [x_history; x'];
end%% 目标函数 f(x)
function val = f_3d(x)% f(x0, x1, x2) = x0 + x1 + x2val = x(1) + x(2) + x(3);
end%% 障碍函数项 h(x) = 1 - (x0^2 + x1^2 + x2^2)
function val = h_3d(x)val = 1.0 - (x(1)^2 + x(2)^2 + x(3)^2);
end%% 障碍型目标 B(x, mu) = f(x) - mu*ln(h(x))
function val = B_3d(x, mu)val = f_3d(x) - mu*log(h_3d(x));
end%% B(x, mu) 的梯度
function g = grad_B(x, mu)
%{B(x) = (x0 + x1 + x2) - mu * ln(1 - r^2),其中 r^2 = x0^2 + x1^2 + x2^2=> dB/dx0 = 1 + [2 mu x0 / (1 - r^2)]=> dB/dx1 = 1 + [2 mu x1 / (1 - r^2)]=> dB/dx2 = 1 + [2 mu x2 / (1 - r^2)]
%}hx = h_3d(x);r2 = x(1)^2 + x(2)^2 + x(3)^2;% hx = 1 - r2 > 0 (只要在球内)dB_dx0 = 1.0 + (2.0 * mu * x(1) / hx);dB_dx1 = 1.0 + (2.0 * mu * x(2) / hx);dB_dx2 = 1.0 + (2.0 * mu * x(3) / hx);g = [dB_dx0; dB_dx1; dB_dx2];
end%{演示如何在 3D 中用“障碍函数 + 简单梯度下降”的内点法来最小化 f(x) = x0 + x1 + x2subject to x0^2 + x1^2 + x2^2 <= 1.可行域是单位球 (x0^2 + x1^2 + x2^2 <= 1)。我们会在图中绘制球面,并用散点绘制迭代轨迹。
%}% 1) 调用求解函数,得到每步迭代的解 x(k)
x_history = interior_point_3d_solve();% 2) 可视化
figure('Color','w','Name','Interior-Point 3D Demo');
hold on; grid on; axis equal; % 3D 坐标中,最好设 axis equal% 2.1 绘制单位球面(x0^2 + x1^2 + x2^2 = 1)
[Xs, Ys, Zs] = sphere(50);
% sphere() 生成一个半径为 1 的球面网格
surf(Xs, Ys, Zs, 'FaceAlpha',0.1, 'EdgeColor','none', 'FaceColor','c');
% 给球面一个半透明的青色xlabel('x_0'); ylabel('x_1'); zlabel('x_2');
title('Minimize x_0 + x_1 + x_2 subject to x_0^2 + x_1^2 + x_2^2 \le 1');% 2.2 绘制迭代轨迹
x0_hist = x_history(:,1);
x1_hist = x_history(:,2);
x2_hist = x_history(:,3);nPoints = size(x_history,1);
if nPoints > 1% 中间过程点用蓝色散点plot3(x0_hist(1:end-1), x1_hist(1:end-1), x2_hist(1:end-1), ...'bo-', 'LineWidth',1.5, 'MarkerSize',4, 'MarkerFaceColor','b');
end% 最后一点用红色标记
plot3(x0_hist(end), x1_hist(end), x2_hist(end), ...'ro', 'MarkerSize',8, 'MarkerFaceColor','r');legend('Unit Sphere (Constraint)', 'Iter Process', 'Final Solution');
view(35, 25); % 调整3D视角
相关文章:

最优化问题 - 内点法
以下是一种循序推理的方式,来帮助你从基础概念出发,理解 内点法(Interior-Point Method, IPM) 是什么、为什么要用它,以及它是如何工作的。 1. 问题起点:带不等式约束的优化 假设你有一个带不等式约束的优…...

vim交换文件的工作原理
在vim中,交换文件是一个临时文件,当我们使用vim打开一个文件进行编辑(一定得是做出了修改才会产生交换文件)时候,vim就会自动创建一个交换文件,而之后我们对于文件的一系列修改都是在交换文件中进行的&…...

CISCO路由基础全集
第一章:交换机的工作原理和基本技能_交换机有操作系统吗-CSDN博客文章浏览阅读1.1k次,点赞24次,收藏24次。交换机可看成是一台特殊的计算机,同样有CPU、存储介质和操作系统,只是与计算机的稍有不同。作为数据交换设备&…...

网络直播时代的营销新策略:基于受众分析与开源AI智能名片2+1链动模式S2B2C商城小程序源码的探索
摘要:随着互联网技术的飞速发展,网络直播作为一种新兴的、极具影响力的媒体形式,正逐渐改变着人们的娱乐方式、消费习惯乃至社交模式。据中国互联网络信息中心数据显示,网络直播用户规模已达到3.25亿,占网民总数的45.8…...
2024年终总结——今年是蜕变的一年
2024年终总结 摘要前因转折找工作工作的成长人生的意义 摘要 2024我从国企出来,兜兜转转还是去了北京,一边是工资低、感情受挫,一边是压力大、项目经历少,让我一度找不到自己梦寐以求的工作,我投了一家又一家ÿ…...
AutoDL 云服务器:普通 用户 miniconda 配置
AutoDL 初始状态下只有root用户,miniconda 安装在root用户目录下 /// 增加普通用户 rootautodl-container-1c0641804d-5bb7040c:~/Desktop# apt updaterootautodl-container-1c0641804d-5bb7040c:~/Desktop# apt install sudorootautodl-container-1c0641804d-5…...

渲染流程概述
渲染流程包括 CPU应用程序端渲染逻辑 和 GPU渲染管线 一、CPU应用程序端渲染逻辑 剔除操作对物体进行渲染排序打包数据调用Shader SetPassCall 和 Drawcall 1.剔除操作 视椎体剔除 (给物体一个包围盒,利用包围盒和摄像机的视椎体进行碰撞检测…...
前端力扣刷题 | 4:hot100之 子串
560. 和为K的子数组 给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例: 输入:nums [1,1,1], k 2 输出:2 法一:暴力法 var subar…...
Julia 之 @btime 精准测量详解
Julia 语言因其高性能和易用性在科学计算、数据分析等领域获得了广泛关注。在性能优化中,精准测量代码执行时间是至关重要的任务,而 Julia 提供了强大的工具 btime 来辅助这一任务。本文将围绕 Julia 的 btime 来展开,帮助读者深入理解并高效…...
【Django教程】用户管理系统
Get Started With Django User Management 开始使用Django用户管理 By the end of this tutorial, you’ll understand that: 在本教程结束时,您将了解: Django’s user authentication is a built-in authentication system that comes with pre-conf…...
【机器学习】自定义数据集 使用pytorch框架实现逻辑回归并保存模型,然后保存模型后再加载模型进行预测
一、使用pytorch框架实现逻辑回归 1. 数据部分: 首先自定义了一个简单的数据集,特征 X 是 100 个随机样本,每个样本一个特征,目标值 y 基于线性关系并添加了噪声。将 numpy 数组转换为 PyTorch 张量,方便后续在模型中…...

C语言连接Mysql
目录 C语言连接Mysql下载 mysql 开发库 方法介绍mysql_init()mysql_real_connect()mysql_query()mysql_store_result()mysql_num_fields()mysql_fetch_fields()mysql_fetch_row()mysql_free_result()mysql_close() 完整代码 C语言连接Mysql 下载 mysql 开发库 方法一…...

Windows上通过Git Bash激活Anaconda
在Windows上配置完Anaconda后,普遍通过Anaconda Prompt激活虚拟环境并执行Python,如下图所示: 有时需要连续执行多个python脚本时,直接在Anaconda Prompt下可以通过在以下方式,即命令间通过&&连接,…...

面试经典150题——图
文章目录 1、岛屿数量1.1 题目链接1.2 题目描述1.3 解题代码1.4 解题思路 2、被围绕的区域2.1 题目链接2.2 题目描述2.3 解题代码2.4 解题思路 3、克隆图3.1 题目链接3.2 题目描述3.3 解题代码3.4 解题思路 4、除法求值4.1 题目链接4.2 题目描述4.3 解题代码4.4 解题思路 5、课…...

学习数据结构(1)时间复杂度
1.数据结构和算法 (1)数据结构是计算机存储、组织数据的方式,指相互之间存在⼀种或多种特定关系的数据元素的集合 (2)算法就是定义良好的计算过程,取一个或一组的值为输入,并产生出一个或一组…...

项目集成GateWay
文章目录 1.环境搭建1.创建sunrays-common-cloud-gateway-starter模块2.目录结构3.自动配置1.GateWayAutoConfiguration.java2.spring.factories 3.pom.xml4.注意:GateWay不能跟Web一起引入! 1.环境搭建 1.创建sunrays-common-cloud-gateway-starter模块…...
【Ubuntu】使用远程桌面协议(RDP)在Windows上远程连接Ubuntu
使用远程桌面协议(RDP)在Windows上远程连接Ubuntu 远程桌面协议(RDP)是一种允许用户通过图形界面远程控制计算机的协议。本文将详细介绍如何在Ubuntu上安装和配置xrdp,并通过Windows的远程桌面连接工具访问Ubuntu。 …...
python3+TensorFlow 2.x 基础学习(一)
目录 TensorFlow 2.x基础 1、安装 TensorFlow 2.x 2、TensorFlow 2.x 基础概念 2、1 Eager Execution 2、2 TensorFlow 张量(Tensor) 3、使用Keras构建神经网络模型 3、1 构建 Sequential 模型 3、2 编译模型 1、Optimizer(优化器&a…...
《活出人生的厚度》
《活出人生的厚度》可以从不同角度来理解和实践,以下为你提供一些拓展内容: ### 不断学习与自我提升 - **持续知识更新**:保持对新知识的渴望,利用各种渠道学习,如在线课程、学术讲座、行业研讨会等。例如,…...

安装 docker 详解
在平常的开发工作中,我们经常需要部署项目。随着 Docker 容器的出现,大大提高了部署效率。Docker 容器包含了应用程序运行所需的所有依赖,避免了换环境运行问题。可以在短时间内创建、启动和停止容器,大大提高了应用的部署速度&am…...

华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...