摘要:很多同学都碰到模型中含有两个变量乘积,在采用matlab进行求解时,会因为非线性而求解失败,本次分享三类编程实例,帮助理解如何实现乘积线性化。
一、两个变量均是连续性变量
这种问题是最复杂的,应用yalmip+求解器直接进行求解不可行,举个电力专业的例子,以购电成本最低为目标,购电成本是电价和购电量的乘积(这里假定电价只有上下限约束),编程实例如下:
clc;clear all; cost=sdpvar(1,24,'full');%电价变量 p=sdpvar(1,24,'full');%电量变量 %约束 Constraints=[]; Constraints=[Constraints,sum(p)==300];%总电量 Constraints=[Constraints,0<=p<=30];%单个时刻电量 Constraints=[Constraints,0.9<=cost<=1.1];%电价范围约束 objective=sum(cost.*p); ops=sdpsettings('verbose', 1, 'solver', 'cplex'); sol=optimize(Constraints,objective,ops); %分析错误标志 if sol.problem == 0 disp('succcessful solved'); else disp('error'); yalmiperror(sol.problem) end
毫不意外,这样是求解不出来的,出现下图的报错信息。
这种情况如何求解详见第三部分。
二、一个是离散型变量一个是连续变量
这种问题可以通过模型转化的方式进行求解,还是举上面的例子,电价作为离散型变量,一般按照峰谷平的分时电价方式,这种方式更符合实际情况,假设用电客户可以根据需要自行设定每个时段电价,但是要满足峰谷平电价分别对应的小时数,具体模型目标为:
上式中,cost代表电价,为1*T的向量,P代表购电量,为T*1的向量,能够看出来,通过矩阵相乘就得到购电成本这一目标函数。
下面进行模型转换,定义3*T的01变量ucost,代表电价选择的状态变量,第一行到第三行分别代表选择谷平峰电价,如某列(某时刻)第一行为1,其他行为0,则代表选择谷时电价。
定义离散型电价costi=[0.9 1.05 1.1]为离散型电价常数,则上述目标模型可转化为:
这样转化之后就得到了01变量和连续性变量的乘积形式了,可以采用求解器进行求解或者采用如下线性化方式进行再次转化。
实例:用电客户存在灵活性调度负荷和基础负荷两部分,综合考虑整体购电成本,编程如下:
clc;clear all; FH1=[2084,1933,1782,1657,1564,1612,1982,2189,2412,2729,2905,3096,3189,3073,3000,2917,3149,3355,3526,3620,3715,3276,2911,2309]; ucost=binvar(3,24,'full');%电价变量 p=sdpvar(1,24,'full');%灵活性负荷变量 %约束 cost=[0.9 1.05 1.1]; Constraints=[]; Constraints=[Constraints,sum(p)==500];%总可转移电量 Constraints=[Constraints,0<=p<=50];%单个时段灵活性负荷约束 Constraints=[Constraints,sum(ucost)==1];%每个时刻只能选择一种电价 Constraints=[Constraints,sum(ucost(1,:))==6];%谷时电价小时数 Constraints=[Constraints,sum(ucost(2,:))==10];%平时电价小时数 Constraints=[Constraints,sum(ucost(3,:))==8];%峰时电价小时数 objective=sum(cost*ucost*(FH1+p)'); ops=sdpsettings('verbose', 1, 'solver', 'cplex'); sol=optimize(Constraints,objective,ops); %分析错误标志 if sol.problem == 0 disp('succcessful solved'); else disp('error'); yalmiperror(sol.problem) end %结果 figure; plot(value(cost*ucost),'m-','LineWidth',1.2) grid on ylim([0.8 1.2]) xlabel('时间'); ylabel('电价'); figure; plot(FH1+value(p),'r-','LineWidth',1.2); hold on plot(FH1,'b-*','LineWidth',1.2); legend('优化后负荷','基础负荷'); grid on
得到如下的运行结果:
可见灵活性调度负荷均叠加在谷时和平时电价时段,优化结果合理。
三、难以转化的乘积处理
对于难以线性化转化的乘积,可以通过将策略显性处理,而不是一味追求求解器的应用方法,下面这个文献采用非合作博弈方式就很值得借鉴。
该文献通过提前将策略部分进行分析,然后得到不同功率区间的电价方案,从而方便实现求解,而且这些分析过程增加了模型工作量和亮点,更加有助于最终成效。
其他模型也可以考虑类似的策略显性过程,通过提前将优化过程捋清楚,然后再进行编程就容易的多。
视频讲解:
乘积线性化问题探析