双层优化入门(1)—基本原理与求解方法(附matlab代码)

1.介绍

        双层优化问题(Bilevel Programming Problems),也被称为双层规划,最早由Stackelberg与1934年在经济学相关研究中提出,因此也被称为Stackelberg问题。

        双层规划问题一般具有层次性、独立性、冲突性、优先性和自主性等特点:

        1)层次性

        优化时是分层管理的形式,下层优化服从上层优化,但下层优化有相对的自主权。

        2)独立性

        各层决策者各自控制一部分决策变量,以优化各自的目标。

        3)冲突性

        各层决策者有目标函数各不相同,且这些目标往往是相互矛盾的。

        4)优先性

        上层决策者优先做出决策,下层决策者在选择策略时,不能改变上层的决策。
        5)自主性

        上层的决策可能影响下层的行为,因而部分地影响下层目标的实现,但上层不能完全控制下层的选择行为,在上层决策允许范围内,下层有自主决策权。
        按照上下层优化的形式不同又可以分为线性双层优化以及非线性双层优化问题。当双层优化问题中所有目标函数和约束条件均为线性时,即为线性双层优化,否则就是非线性双层优化问题。其中双层优化的基本形式可描述为:

        其中,x和y是上层优化的决策变量,但x在下层优化中是参数。所以,双层优化模型是一个优化问题受制于另一个优化问题的模型。

2.问题分析

        下面是一个简单的线性双层优化问题:

        上下层优化的目标函数和约束条件均为线性,该问题为线性双层优化问题,
        为说明原理,按照上下层优化迭代的方式进行求解。
        1)第一次迭代
        首先不考虑下层优化的决策,上层优化求出最优解为 x1*=6 y1=8 ,上层最优目标函数为-22 ,将 x1*=6 带入下层优化中,求出 y1*=12 ,下层最优目标函数为-12
        2)第二次迭代
        将 y1*=12 带入上层优化中,此时上层优化的两个约束条件互相冲突,上层优化无最优解。 迭代无法收敛,是否意味着这个双层优化问题无解?很明显不是的,实际上这个问题存在最优解 x=8 y=6 ,上层优化最优目标函数值为 -20

matlab代码:

%% 清空
clc
clear
close all
warning off
%% 采用迭代方法进行求解
x=sdpvar(1);
y=sdpvar(1);
Constraints1=[2*x-3*y >= -12 , x+y <= 14 , x>=0 , y>=0];
objective1=-x-2*y;
objective2=-y;
ops=sdpsettings('verbose', 0 , 'solver', 'cplex');
result=optimize(Constraints1,objective1,ops);
if result.problem==0
    disp(['第一次迭代最优解:x=',num2str(value(x)),',y=',num2str(value(y))])
    disp(['第一次迭代最优函数值=',num2str(value(objective1))])
end
x_dot=zeros(1,100);
y_dot=zeros(1,100);
x_dot(1)=value(x);
for k=1:10
    Constraints2=[-3*x+y <= -3 , 3*x+y <= 30 , x==x_dot(k) , x>=0 , y>=0];
    result=optimize(Constraints2,objective2,ops);
    y_dot(k)=value(y);
    Constraints1=[2*x-3*y >= -12 , x+y <= 14 , y==y_dot(k) , x>=0 , y>=0];
    result1=optimize(Constraints1,objective1,ops);
    x_dot(k+1)=value(x);
    if result1.problem || result.problem
        disp('迭代无法收敛')
        break
    end
end

        运行结果:

 3.双层优化求解方法

        上面的问题是一个小规模线性双层优化问题,通过迭代也无法求出问题的解,实际我们要解决的问题一般都不会这么简单,通常规模比较大,或者模型中存在非线性,一般来说很难通过简单的迭代法进行求解,需要考虑其他方法。实际上,双层优化问题是一个 NP 难问题,通常采用的方式是利用 KKT(Karush-Kuhn-Tucker) 条件将双层优化转换为单层优化问题。假设一个优化问题是如下的形式:

定义拉格朗日函数为:

        其中,λ j g j( x ) = 0 对应的拉格朗日乘数,  uk是hk(x)<=0   对应的拉格朗日乘数,那么该优化问题取得最优解的必要条件( 也就是 KKT 条件 ) 为:

以上面提到的线性双层优化问题为例,其下层优化的拉格朗日函数为: 

KKT 方程组如下:

将下层优化的 KKT 条件添加到上层优化问题中,就将双层优化问题转换为了单层优化问题:

        对于该问题,可以分三种情况讨论:

        1) u1 =0,模型可以简化为:

        2) u1∈(0,1)(1,+∞),模型可以简化为:

         3) u1=1,模型可以简化为:

matlab代码: 

%% 清空
clc
clear
close all
warning off
%% u1=0
x=sdpvar(1);
y=sdpvar(1);
Constraints1=[2*x-3*y >= -12 , x+y <= 14 , x>=0 , y>=0 , -3*x+y <= -3 , 3*x+y == 30 ,];
objective=-x-2*y;
ops=sdpsettings('verbose', 0 , 'solver', 'cplex');
result1=optimize(Constraints1,objective,ops);
disp('***********u1=0时的最优解和最优函数值************')
if result1.problem==0
    disp(['最优解:x=',num2str(value(x)),',y=',num2str(value(y))])
    disp(['最优函数值=',num2str(value(objective))])
else
    disp('无最优解')
end

%% u1∈(0,1)∪(1,+∞)
x=sdpvar(1);
y=sdpvar(1);
Constraints1=[2*x-3*y >= -12 , x+y <= 14 , x>=0 , y>=0 , -3*x+y == -3 , 3*x+y == 30 ,];
objective=-x-2*y;
ops=sdpsettings('verbose', 0 , 'solver', 'cplex');
result2=optimize(Constraints1,objective,ops);
disp('****u1∈(0,1)∪(1,+∞)时的最优解和最优函数值*****')
if result2.problem==0
    disp(['最优解:x=',num2str(value(x)),',y=',num2str(value(y))])
    disp(['最优函数值=',num2str(value(objective))])
else
    disp('无最优解')
end

%% u1=1
x=sdpvar(1);
y=sdpvar(1);
Constraints1=[2*x-3*y >= -12 , x+y <= 14 , x>=0 , y>=0 , -3*x+y == -3 , 3*x+y <= 30 ,];
objective=-x-2*y;
ops=sdpsettings('verbose', 0 , 'solver', 'cplex');
result2=optimize(Constraints1,objective,ops);
disp('***********u1=1时的最优解和最优函数值************')
if result2.problem==0
    disp(['最优解:x=',num2str(value(x)),',y=',num2str(value(y))])
    disp(['最优函数值=',num2str(value(objective))])
else
    disp('无最优解')
end

运行结果:

        这样就完成了对上述简单线性双层优化问题的求解。通过下层优化的KKT条件将双层优化转换为单层优化是最常用的方法,但不是唯一的方法,后面我将继续更新这个系列,和大家一起学习双层优化问题。

参考文献:

[1] Bilevel Programming Problems

完整代码和相应资料可以从这里下载:

双层优化入门资料-基本原理和求解方法

### 双层优化基本原理 双层优化问题涉及两个层次的决策者,上层和下层。每个层次都有自己的目标函数和约束条件。这类问题的特点在于上下两层之间存在相互依赖关系:上层变量的选择会影响下层最优解的结果;而下层的反应又会反馈给上层作为其优化的一部分[^1]。 具体来说,在标准形式中,双层规划可以表示为: - **上层问题**:最小化/最大化某个关于上层变量的目标函数F(x, y),其中x代表上层控制变量; - **下层问题**:对于固定的x值,找到使g(x,y)达到极小化的y*,即满足特定条件下使得f(x,y*)尽可能小(或大),这里y是下层可调参数。 这种结构广泛应用于经济学、工程设计等领域,因为很多现实世界里的多阶段决策过程都可以建模成此类模型[^2]。 ### 求解方法 由于双层优化属于NP难类问题,直接求得全局最优解往往非常困难甚至不可能实现。因此,实践中常采用间接策略来简化处理流程。最常见的一种方式就是借助于KKT(Karush-Kuhn-Tucker)必要性定理将原问题转化为更易于计算的形式——即将带有嵌套性质的双层框架转变为单一层面的数学表达式[^3]。 #### 利用KKT条件转化 当假设下层问题是凸优化时,则可以通过引入拉格朗日乘子λ关联上下两级之间的联系,并构建增强型Lagrangian函数H(x,y; λ)= F(x)+∑_i λ_i * g_i(y|x), 进一步得到等价的一阶导数方程组以及互补松弛条件。最终形成扩展后的单级非线性规划问题,从而能够运用常规数值算法进行近似求解。 ```matlab % MATLAB代码展示如何设置并求解经由KKT变换后的单层优化问题 function [solution,status]=solveBilevelViaKKT() % 定义符号变量... % 构造增广拉格朗日函数 H % 应用一阶导数法则获得必要的KKT条件 % 解决由此产生的NLP问题 end ```
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

配电网和matlab

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值