MATLAB编程-最优解数学建模


1. linprog(线性规划)

问题描述

完整代码与注释

% 1. 求解部分
c = [-2; -3];           % 目标函数系数 (min -2x1 -3x2)
A = [1 2; 4 0; 0 4];    % 不等式约束左侧系数矩阵
b = [8; 16; 12];        % 不等式约束右侧向量
lb = [0; 0];            % 变量下界 (x1,x2 >= 0)
[x, fval] = linprog(c, A, b, [], [], lb); % 执行求解

% 2. 可视化绘图
[X1, X2] = meshgrid(0:0.1:5, 0:0.1:5);
Z = c(1)*X1 + c(2)*X2; % 计算目标函数值平面
contour(X1, X2, Z, 20); hold on; grid on; % 绘制等高线

% 绘制三条约束直线
fplot(@(x) (8-x)/2, [0 5], 'r', 'LineWidth', 2); % x1 + 2x2 = 8
line([4 4], [0 5], 'Color', 'g', 'LineWidth', 2); % 4x1 = 16
line([0 5], [3 3], 'Color', 'b', 'LineWidth', 2); % 4x2 = 12

% 标记最优解
plot(x(1), x(2), 'kp', 'MarkerSize', 15, 'MarkerFaceColor', 'y');
title('线性规划:可行域边界与最优解点');
legend('目标等高线', 'x1+2x2=8', '4x1=16', '4x2=12', '最优解点');


2. quadprog(二次规划)

问题描述

完整代码与注释

% 1. 求解部分
G = [1 0; 0 2];         % 二次项系数矩阵 (1/2 x'Gx)
c = [-2; -6];           % 一次项系数向量
A = [1 1; -1 2];        % 不等式约束系数
b = [2; 2];             % 不等式约束右端项
lb = [0; 0];
[x, fval] = quadprog(G, c, A, b, [], [], lb);

% 2. 可视化绘图
[X1, X2] = meshgrid(0:0.05:2.5, 0:0.05:2.5);
Z = 0.5*(G(1,1)*X1.^2 + G(2,2)*X2.^2) + c(1)*X1 + c(2)*X2;
contour(X1, X2, Z, 30); hold on;

% 绘制约束线
fplot(@(x) 2-x, [0 2.5], 'r', 'LineWidth', 2);   % x1 + x2 = 2
fplot(@(x) (2+x)/2, [0 2.5], 'g', 'LineWidth', 2); % -x1 + 2x2 = 2
plot(x(1), x(2), 'kp', 'MarkerSize', 15, 'MarkerFaceColor', 'y');
title('二次规划:椭圆等高线与约束边界');
legend('目标等高线', 'x1+x2=2', '-x1+2x2=2', '最优解');


3. fminunc(无约束非线性优化)

问题描述

完整代码与注释

% 1. 求解部分
f = @(x) x(1)^2 + x(2)^2 + x(1)*x(2); 
x0 = [1; 1];            % 初始搜索点
[x, fval] = fminunc(f, x0);

% 2. 可视化绘图 (3D表面 + 底面等高线)
subplot(1,2,1);
fsurf(@(x1, x2) x1^2 + x2^2 + x1*x2, [-1.5 1.5]); hold on;
plot3(x(1), x(2), fval, 'rp', 'MarkerSize', 15, 'MarkerFaceColor', 'r');
title('3D 目标函数表面');

subplot(1,2,2);
fcontour(@(x1, x2) x1^2 + x2^2 + x1*x2, [-1.5 1.5]); hold on;
plot(x(1), x(2), 'rp', 'MarkerSize', 15, 'MarkerFaceColor', 'r');
title('2D 等高线与极小值点');


4. fmincon(约束非线性优化)

问题描述: 满足 且变量非负。

完整代码与注释

% 1. 求解部分
f = @(x) x(1)^2 + x(2)^2; 
x0 = [0.1; 0.1];        % 初始点不能太靠近0,否则可能导致搜索方向不明显
A = [-1 -1];            % 将 x1 + x2 >= 1 转换为 -x1 - x2 <= -1
b = [-1];
lb = [0; 0];
[x, fval] = fmincon(f, x0, A, b, [], [], lb);

% 2. 可视化绘图
fcontour(@(x1, x2) x1.^2 + x2.^2, [0 1.2 0 1.2]); hold on;
fplot(@(x) 1-x, [0 1.2], 'r', 'LineWidth', 2); % 约束边界线
% 填充不可行区域(仅为示意)
fill([0 1 0], [0 0 1], 'r', 'FaceAlpha', 0.1); 
plot(x(1), x(2), 'kp', 'MarkerSize', 15, 'MarkerFaceColor', 'y');
title('有约束非线性:最优解落在约束边界上');


5. fminimax(极小极大问题)

问题描述:最小化两个函数中较大的那一个值。

完整代码与注释

% 1. 求解部分
% f 是一个函数组,算法会设法降低 max(f1, f2)
f = @(x) [x(1)^2 + x(2)^2; (x(1)-1)^2 + x(2)^2]; 
x0 = [0; 0];
[x, fval] = fminimax(f, x0);

% 2. 可视化绘图
[X1, X2] = meshgrid(-0.5:0.05:1.5, -1:0.05:1);
F1 = X1.^2 + X2.^2;
F2 = (X1-1).^2 + X2.^2;
Fmax = max(F1, F2);     % 取两者中的极大值形成新的曲面
surf(X1, X2, Fmax, 'EdgeColor', 'none', 'FaceAlpha', 0.8); hold on;
plot3(x(1), x(2), max(f(x)), 'kp', 'MarkerSize', 15, 'MarkerFaceColor', 'y');
view(45, 30);
title('极小极大:寻找两个“碗”交界处的最低点');


6. intlinprog(整数线性规划)

问题描述:在线性规划基础上,要求变量必须为整数。

完整代码与注释

% 1. 求解部分
c = [-1; -2];           % 目标函数系数
intcon = [1, 2];        % 强制 x1 和 x2 必须是整数
A = [1 1; 1 0; 0 1]; b = [4; 3; 3]; lb = [0; 0];
[x, fval] = intlinprog(c, intcon, A, b, [], [], lb);

% 2. 可视化绘图
% 绘制连续情况下的可行域(浅蓝色阴影)
fill([0 1 3 3 0], [3 3 1 0 0], 'c', 'FaceAlpha', 0.2); hold on;
% 绘制所有可能的整数格点
[GX, GY] = meshgrid(0:3, 0:3);
scatter(GX(:), GY(:), 'k.'); 
% 筛选并突出显示符合约束的整数点
valid = (GX+GY <= 4);
scatter(GX(valid), GY(valid), 80, 'b', 'filled');
% 标注最终选定的最优整数点
plot(x(1), x(2), 'rp', 'MarkerSize', 15, 'MarkerFaceColor', 'r');
title('整数规划:离散点中的抉择');
legend('连续可行域', '无效整数点', '有效整数点', '最优整数解');


💡 核心总结:

  • 注释:所有的 Ab 都要严格遵守 Ax <= b。如果题目给的是 >=,请务必在系数前加负号翻转方向。
  • 绘图
  • contour(等高线)能帮你理解目标函数的“坡度”。
  • fplotline 能帮你勾勒出“围墙”(约束)。
  • intlinprog 的核心就在于最优解只能在蓝色的“实心点”里选,而不能选阴影里的任意位置。
posted @ 2026-02-01 00:48  kkman2000  阅读(2)  评论(0)    收藏  举报