机组组合问题要求基于已知的系统数据,求解计划时间内机组决策变量的最优组合,使得系统总成本达到最小。该问题的决策变量由两类,一类是各时段机组的启停状态,为整数变量,0表示关停,1表示启动;另一类是各时段机组的出力,为连续变量。
机组组合问题属于规划问题,即要在决策变量的可行解空间里找到一组最优解,使得目标函数尽可能取得极值。对于混合整数规划,常用的方法有分支定界法,benders分解等。CPLEX提供了快速的MIP求解方法,对于数学模型已知的问题,只需要按照程序规范在MATLAB中编写程序化模型,调用CPLEX求解器,即可进行求解。
下文介绍机组组合优化的数学模型。
根据上述变量定义,建立含安全约束的机组最优组合(SCUC)模型如下:
1)目标函数
目标函数即为最小化成本,包括发电带来的煤耗成本和机组启停产生的开停机成本。
其中,机组的煤耗函数可用出力的二次函数表述:
2)等式约束
系统的功率平衡约束。
3)不等式约束条件
a) 热备用
b) 机组出力约束
c) 机组爬坡约束
d) 机组起停时间约束
e) 起停费用约束
f) 潮流安全约束
由上小节构建的机组组合优化模型,煤耗成本采用二次函数,当系统规模较大时(如节点数超过1000),求解起来将消耗大量时间。因此我们可以对原模型进行线性化处理。
将煤耗函数分段线性化,分为m段,将原模型的替换为:
校验程序的算例基于IEEE-30节点标准测试系统,系统接线图如图所示。系统包含30个节点,6台发电机组。要求确定系统最优机组组合,使得系统各机组总运行成本(煤耗成本+启停成本)最小化。
求解:机组组合结果,即机组各时段启停计划、机组各时段最优出力,以及内含的各时段的直流潮流等。
完整的程序及附件下载:基于CPLEX的IEEE-30节点机组组合优化(MATLAB实现)
下面列出部分代码:
clear
clc
yalmip;
Cplex;
%%系统参数
%所有参数均用有名值表示
branch_num=size(netpara);%网络中的支路
branch_num=branch_num(1,1);
PL_max=netpara(:,6);%线路最大负荷
PL_min=netpara(:,7);%线路最小负荷
limit=paragen(:,3:4);%机组出力上下限//limit(:,1)表示上限,limit(:,2)表示下限
para=paragen(:,5:7);%成本系数//para(:,1)表示系数a,para(:,2)表示系数b,para(:,3)表示系数c。
price=100;
para=price*para;%价格换算
lasttime=paragen(:,9);%持续时间
Rud=paragen(:,8);%上下爬坡速率//因题中简化上坡下坡速度相同
H=paragen(:,10);%启动成本
J=paragen(:,11);%关停成本
u0=[1 1 1 1 1 1];%初始状态
%% 规模变量
%机组数
gennum=size(paragen);
gennum=gennum(1,1);
%节点数
numnodes=size(loadcurve);
numnodes=numnodes(1,1)-1;
%时间范围
T=size(loadcurve);
T=T(1,2)-1;
%线性化分段数(按需要更改)
m=4;
%各时刻节点总负荷
PL=loadcurve(numnodes+1,2:T+1);
%%
%决策变量
u=binvar(gennum,T,'full');%状态变量
p=sdpvar(gennum,T,'full');%即各机组实时功率p(i,t)
Ps=sdpvar(gennum,T,m,'full');%分段出力
costH=sdpvar(gennum,T,'full');%启动成本
costJ=sdpvar(gennum,T,'full');%关停成本
sum_PowerGSDF=sdpvar(T,branch_num,numnodes,'full');%发电机的输出功率转移总和
%% 目标函数
totalcost=0;%机组费用成本最小
%线性化的最优成本目标
for i=1:gennum
for t=1:T
for s=1:m
totalcost=totalcost+K(i,s)*Ps(i,t,s);%线性化煤耗成本
end
totalcost=totalcost+u(i,t)*(para(i,2)*limit(i,2)+para(i,1)*limit(i,2)^2+para(i,3));%加上表示机组开机并以最小出力 运行产生的煤耗
totalcost=totalcost+costH(i,t)+costJ(i,t);%加上机组启停产生的开停机成本
end
end
%原二次函数式的最优成本目标
% for i=1:gennum
% for t=1:T
% totalcost=totalcost+para(i,1)*p(i,t).^2+para(i,2)*p(i,t)+para(i,3)*u(i,t); %煤耗成本
% totalcost=totalcost+costH(i,t); %启动成本
% totalcost=totalcost+costJ(i,t); %关停成本
% end
% end
%% 求解
ops=sdpsettings('solver', 'cplex');
result=solvesdp(st,totalcost);
double(totalcost)
subplot(1,2,1)
bar(value(p)','stack')%阶梯图
legend('Unit 1','Unit 2','Unit 3','Unit 4','Unit 5','Unit 6'); %在坐标轴上添加图例
subplot(1,2,2)
stairs(value(p)')
legend('Unit 1','Unit 2','Unit 3','Unit 4','Unit 5','Unit 6'); %在坐标轴上添加图例
xlswrite('机组组合问题求解结果',double(u),'机组各时段启停计划');
P=(sum(sum_PowerGSDF(:,:,:),3)-sum_nodeGSDF(:,:))';%各段支路的实时潮流
P_sp=zeros(numnodes,T);%各个节点的直流潮流功率
for i=1:numnodes
for k=1:branch_num
m=netpara(k,2);%首端节点
n=netpara(k,3);%末端节点
if m==i
P_sp(i,:)=P_sp(i,:)+P(k,:);
end
if n==i
P_sp(i,:)=P_sp(i,:)-P(k,:);
end
end
end
dot_theta=zeros(numnodes,T);
dot_theta=X*P_sp;
xlswrite('机组组合问题求解结果',double(P),'支路各时段的直流潮流');
xlswrite('机组组合问题求解结果',double(P_sp),'节点各时段的潮流功率');
xlswrite('机组组合问题求解结果',double(dot_theta),'节点各时段的潮流相角');
set(0,'ShowHiddenHandles','On')
set(gcf,'menubar','figure')