一、应用
线性规划只能解决一组线性约束条件下一个目标的max和min问题,但实际决策中通常要考虑多个目标,这些目标有主有次,有定性有定量,有对立有补充,此时就要用到多目标规划。
二、思路
一句话概括就是将多目标模型->单目标模型
在目标规划中不提最优解的概念, 只提满意解的概念, 即寻求能够照顾到各个目标, 并使决策者感到满意的解, 由决策者来确定选取哪一个解。缺点是满意解的数目太多而难以将其一一求出。
1、加权系数法
给每个目标赋权
2、优先等级法
给每个目标不同的优先等级
3、主要目标法(常用)
将一个目标选为主要目标,将其他目标转换为约束条件。即主要目标作为优化目标函数,将次要目标的约束条件添加到优化模型中。
三、相关概念
1、正负偏差变量
①正偏差变量:决策值超过目标值的部分
②负偏差变量:决策值未达到目标值的部分
2、绝对约束(硬、刚性)
必须严格满足的等式和不等式的约束
3、目标约束(软、柔性)
目标规划特有的,约束右端是要追求的目标值,允许发生正负偏差
>>>注意
可将绝对约束通过添加正负偏差变量的方式转换为柔性约束
四、具体实现matlab
1、fgoalattain
>>>核心宗旨
将正负偏差引入目标函数,在用户给定goal的前提下尽量减少偏差(即使得严格的不等式约束尽可能小的被突破),用人话说就是给定约束条件下尽量接近或达到指定的目标值。
(1)基本用法
[x, fval, exitflag] = fgoalattain(fun, x0, goals, weights, A, b, lb, ub)
①参数
fun:目标函数
x0:变量的初始猜测值
goals:目标值向量(每个目标函数应该达到的值)
weights:目标函数的权重
A,b:线性约束条件
lb,ub:变量的下、上界
②返回值
x:使目标函数达到或接近目标值时的变量向量
fval:目标函数值
exitflag:求解器的推出标志
(2)示例
fun = @(x) [x(1)^2 + x(2)^2, (x(1) - 1)^2 + x(2)^2];
x0 = [0, 0];
goals = [0, 0]; % 目标值向量
weights = [1, 1]; % 权重向量,均衡重要性
A = [];
b = [];
lb = [-5, -5];
ub = [5, 5];
[x_goal, fval_goal, exitflag_goal] = fgoalattain(fun, x0, goals, weights, A, b, lb, ub);
2、paretosearch
>>>核心宗旨
在优化问题具有多个独立的、相互竞争的目标的情况下找到一组非支配解集合(Pareto最优解)
(1)基本用法
[x, fval, exitflag, output, solutions] = paretosearch(problem)
①参数
problem:结构体,包含
->objective:目标函数
->nvars:变量个数
->lb,ub:变量的下、上界
②返回值
->x:矩阵,每一行是一个非支配解
->fval:矩阵,每一行对应x中的目标函数值
->exitflag:求解状态信息
->output:搜索过程的详细信息
->solutions:求解过程的详细信息
(2)示例
仍然求解1、中的问题
% 定义目标函数
objective = @(x) [x(:,1).^2 + x(:,2).^2, (x(:,1) - 1).^2 + x(:,2).^2];
% 定义变量个数和范围
nvars = 2;
lb = [-5, -5];
ub = [5, 5];
% 构造问题结构体
problem.objective = objective;
problem.nvars = nvars;
problem.lb = lb;
problem.ub = ub;
% 求解多目标优化问题
[x, fval, exitflag, output, solutions] = paretosearch(problem);
% 显示结果
disp('Pareto optimal solutions:');
disp(x);
disp('Corresponding objective function values:');
disp(fval);
3、比较选择
- 需要找到多个相互竞争的最优解=>paretosearch
- 更关注目标达成和接近指定目标值=>fgoalattain
五、解决实际问题
>>>代码实现
% 参数定义
w1 = 1; % 目标一级的权重
w2 = 1; % 目标二级的权重
w3 = 1; % 目标三级的权重
% 定义目标函数
% fun 返回一个包含三个目标值的向量
fun = @(x)[w1*x(3), ... % 第一个目标:w1*x3
w2*(x(4) + x(5)), ... % 第二个目标:w2*(x4 + x5)
w3*(3*x(6) + 3*x(7) + x(8))]; % 第三个目标:w3*(3*x6 + 3*x7 + x8)
% 包含目标到达问题的目标和权重
goal = [0, 0, 0]; % 目标向量,表示希望目标函数的目标值为 [0, 0, 0]
weight = [1, 1, 1]; % 权重向量,表示每个目标的相对重要性,均设为 1
% 定义不等式约束条件
A = [2 2 0 0 0 0 0 0 0; % 2*x1 + 2*x2 <= 12
-2 -1 0 0 0 0 0 0 0]; % -2*x1 - x2 <= 0
b = [12; 0]; % 不等式约束向量
% 定义等式约束条件
Aeq = [200 300 1 -1 0 0 0 0 0; % 200*x1 + 300*x2 + d1^- - d1^+ = 1500
2 -1 0 0 1 1 0 0 0; % 2*x1 - x2 + d2^- + d2^+ = 0
4 0 0 0 0 0 1 -1 0; %
0 0 0 0 0 0 0 0 1]; % 5*x2 + d4^- + d4^+ = 15
beq = [1500; 0; 16; 15]; % 等式约束向量
lb = zeros(1, 9); % 变量下界,所有变量均为非负
% 初始点
x0 = ones(1, 9); % 初始化点,全 '1' 向量
% 使用 fgoalattain 求解问题
options = optimoptions('fgoalattain', 'Display', 'iter');
[x, fval] = fgoalattain(fun, x0, goal, weight, A, b, Aeq, beq, lb, [], [], options);
% 显示结果
disp('优化结果:')
disp(x)
disp('目标函数值:')
disp(fval)