半定规划(Semidefinite Programming, SDP)是数学优化的一个重要分支,涉及在半正定矩阵锥上进行的凸优化问题。以下是使用 MATLAB 求解半定规划的多种方法,包括专用工具箱和手动实现。
一、使用 CVX 工具箱(推荐方法)
CVX 是斯坦福大学开发的优化建模系统,可高效求解半定规划问题。
安装 CVX
- 访问 http://cvxr.com/cvx/
- 下载并解压到 MATLAB 路径
- 运行
cvx_setup
基本求解示例
% 求解半定规划问题:% min C • X% s.t. A_i • X = b_i, i=1..m% X ≽ 0cvx_begin sdp variableX(2,2)symmetric% 定义对称半正定变量minimize(trace([1,0;0,2]*X))% 目标函数: C=[1,0;0,2]subject totrace([1,0;0,1]*X)==1;% 约束1: A1=I, b1=1trace([0,1;1,0]*X)==0.5;% 约束2: A2=[0,1;1,0], b2=0.5X>=0;% 半正定约束cvx_end% 显示结果disp('最优解 X:');disp(X);disp(['最优值: ',num2str(cvx_optval)]);实际应用示例:最大割问题
% 最大割问题的SDP松弛n=5;% 顶点数W=rand(n,n);% 权重矩阵W=(W+W')/2;% 确保对称W=W-diag(diag(W));% 对角线归零cvx_begin sdp variableX(n,n)symmetricmaximize(sum(sum(W.*X)))% 目标函数subject todiag(X)==ones(n,1);% 对角线为1X>=0;% 半正定约束cvx_end% 随机舍入得到整数解[U,S,V]=svd(X);v=sign(U(:,1));cut_value=sum(W(v>0,v<0));disp(['最大割值: ',num2str(cut_value)]);二、使用 YALMIP 工具箱
YALMIP 是另一个强大的优化建模工具箱,支持多种求解器。
安装 YALMIP
- 从 https://github.com/yalmip/YALMIP 下载
- 添加到 MATLAB 路径
求解示例
% 求解相同问题n=2;C=[1,0;0,2];A1=eye(2);b1=1;A2=[0,1;1,0];b2=0.5;% 定义模型X=sdpvar(n,n,'symmetric');Constraints=[X>=0,...trace(A1*X)==b1,...trace(A2*X)==b2];Objective=trace(C*X);% 求解options=sdpsettings('solver','sedumi');% 选择求解器optimize(Constraints,Objective,options);% 获取结果X_opt=value(X);obj_val=value(Objective);disp('最优解:');disp(X_opt);disp(['最优值: ',num2str(obj_val)]);三、使用 SeDuMi 求解器(底层接口)
对于需要更高控制精度的场景,可直接调用 SeDuMi 求解器。
% 问题描述:% min C•X% s.t. A_i•X = b_i% X ≽ 0% 定义数据C=[1,0;0,2];% 目标矩阵A1=eye(2);b1=1;% 约束1A2=[0,1;1,0];b2=0.5;% 约束2% 组合约束矩阵A=[A1(:)'; A2(:)'];% 按列堆叠b=[b1;b2];% 调用 SeDuMiK.s=size(C,1);% 半定块维度options=sedumi(A,b,C,[],[],[],K);X_sol=full(options.x);% 解向量X_mat=reshape(X_sol,size(C));% 重构矩阵% 显示结果disp('最优解矩阵:');disp(X_mat);disp(['最优值: ',num2str(trace(C*X_mat))]);四、手动实现内点法(教育目的)
理解算法原理,可手动实现简化版内点法:
function[X,obj]=simple_sdp_solver(C,A_list,b_list,mu0,tol,max_iter)% 参数设置n=size(C,1);% 矩阵维度m=length(b_list);% 约束数量mu=mu0;% 初始障碍参数X=eye(n);% 初始解foriter=1:max_iter% 1. 计算梯度grad=C;fori=1:m grad=grad-(trace(A_list{i}*X)-b_list{i})*A_list{i};end% 2. 牛顿步长计算(简化版)% 实际实现需要求解牛顿方程:F'(X)[ΔX] = -F(X)% 这里使用简化更新dX=-grad/norm(grad,'fro');% 3. 线搜索alpha=0.1;new_X=X+alpha*dX;% 4. 投影到可行集(保持半正定)[U,S,V]=svd(new_X);S(S<0)=0;% 投影到半正定锥new_X=U*S*V';% 5. 更新障碍参数mu=0.1*mu;% 6. 检查收敛ifnorm(new_X-X,'fro')<tolbreak;endX=new_X;end% 计算目标值obj=trace(C*X);end% 使用示例C=[1,0;0,2];A_list={eye(2),[0,1;1,0]};b_list=[1;0.5];[X,obj]=simple_sdp_solver(C,A_list,b_list,10,1e-5,100);disp('手动求解结果:');disp(X);disp(['目标值: ',num2str(obj)]);参考代码 求解半定规划的matlab代码www.youwenfan.com/contentcst/63203.html
五、常见问题与解决方案
问题不可行
cvx_begin sdp% ... 问题定义 ...cvx_endifstrfind(cvx_status,'Infeasible')disp('问题不可行!尝试放松约束');end数值稳定性问题
- 缩放数据使矩阵元素量级相近
- 使用
sdpsettings('verbose',1)查看求解细节 - 尝试不同求解器:
'sedumi'、'sdpt3'、'mosek'
大型问题求解
- 使用稀疏矩阵格式
- 考虑分解技术
- 使用专门的大规模SDP求解器
六、应用场景
- 组合优化:最大割、图着色、社区发现
- 控制系统:Lyapunov稳定性分析、鲁棒控制
- 信号处理:波束成形、传感器网络定位
- 量子信息:量子态层析、纠缠见证
- 金融工程:投资组合优化、风险管理
七、性能优化技巧
热启动:对相似问题使用上次解作为初始点
options=sdpsettings('solver','sedumi','usex0',1);optimize(Constraints,Objective,options);并行计算:对多个SDP问题使用
parforparfori=1:N result{i}=solve_sdp(problem{i});endGPU加速:使用支持GPU的求解器(如Mosek)
options=sdpsettings('solver','mosek','MOSEK.GPU',true);低秩近似:当解预期为低秩时
cvx_begin sdp variableX(n,n)semidefinite dual variable lambda;minimize(trace(C*X))subject to% ... 约束 ...cvx_end
总结
MATLAB 提供了多种求解半定规划的方法:
- CVX:最简便易用,适合大多数应用
- YALMIP:更灵活,支持更多求解器
- 直接调用求解器:SeDuMi、SDPT3、MOSEK 等
- 手动实现:有助于理解算法原理