这个例子说明了如何调度两个燃气发电机优化,这意味着获得最大收入减去成本。虽然例子并不完全切合实际,但是它展示了如何考虑到,取决于决策时机帐户费用。
对于基于求解的方法解决这个问题,请参阅发电优化调度:求解基于.
电力市场在不同时间有不同的价格。如果您有发电机提供电力,可以通过安排当价格高时,通过安排发电机来利用这种可变定价。假设您控制了两个生成器。每个发电机具有三个功率电平(关闭,低,高)。每个发电机在每个功率水平上具有指定的燃料消耗和电力生产速率。当发电机关闭时,燃料消耗为0。
可以在一天内分配的功率电平到每个发生器为每个半小时的时间间隔(24小时,所以48米的间隔)。根据历史记载,假设你知道每兆瓦时(MWh)的收入,你在每个时间间隔接收。这个例子中的数据是从澳大利亚能源市场运营https://www.nemweb.com.au/REPORTS/CURRENT/
在2013年年中,并且在他们的条款下使用https:/
/
万维网。
aemo。
com。
非盟/
隐私和法律通知/
版权权限
.
加载dispatchPrice;% Get poolPrice,这是每MWh的收入栏(poolPrice。5)xlim([5, 48.5])包含(“每个时期每兆瓦时的价格”)
有启动发电机就已经关闭后的代价。此外,对当天的最大燃料使用的约束。这种约束存在,因为你买了你的燃料提前一天的时间,所以你可以使用你刚刚买了只什么。
您可以制订调度问题作为二进制整数规划问题。定义索引一世
那j
,K.
和二元调度矢量y
, 如下:
nPeriods
=时间段的数量,在本例中为48。
一世
= a time period, 1 <=一世
<= 48。
j
=生成索引,1 <=j
本例中<= 2。
Y(I,J,K)= 1
当时间一世
、发电机j
在功率水平运行K.
.让低功率是k = 1
和高功率k = 2
.发电机熄灭时Sum_k y(i,j,k) = 0
.
确定发生在关闭后的生成器何时开始。为此,请定义辅助二进制变量Z(i,j)
指示是否为开启发电机充电j
在一段时间内一世
.
z (i, j) = 1
当发电机j
在期间关闭一世
,但在期间是开着的I + 1
.z (i, j) = 0
除此以外。换句话说,z (i, j) = 1
当Sum_k y(i,j,k) = 0
和sum_k y(i + 1,j,k)= 1
.
你需要一种设置方法Z.
自动根据的设置y
.下面的线性约束处理这个设置。
您还需要费用,每个发电机发电水平,发电机的消费水平问题的参数和燃料可用。
poolPrice(我)
—以美元/兆瓦时为单位的收入一世
根(J,K)
- 发电机产生的MWj
在功率K.
燃料(J,K)
——发电机使用的燃料j
在功率K.
totalFuel
- 燃油在一天内可
startCost
——发电机关闭后启动的美元成本
fuelPrice
- 成本为燃料的单元
你得到了poolprice.
当你执行加载dispatchPrice;
.其他参数如下所示。
fuelPrice = 3;totalFuel = 3.95 e4;nPeriods =长度(poolPrice);% 48期nGens = 2;%两个发电机创= (61152;50150);%发电机1低= 61兆瓦,高= 152兆瓦燃料= (427806;325765);对于发电机2%的燃料消耗低= 325,高= 765startCost = 1E4;%发电机关闭后启动的成本
在两个操作点检查两个发电机的效率。
效率= /燃料将军;计算单位燃料耗电量RR =效率';%的策划h =酒吧(rr);h(1)。FaceColor =‘g’;H(2)= .FaceColor“c”;传说(H,发电机1的那《发电机2》那“位置”那'NorthEastOutside') ax = gca;斧子。XTick = [1, 2];斧子。XTickLabel = {“低”那'高的'};ylim([。1,.2])Ylabel('效率')
注意,生成器2比发电机1更有效地在其相应的工作点(低和高),但发电机1在其高的工作点中的位为比发电机2在其低操作点更有效。
要设置问题,需要进行编码所有问题的形式问题的数据和约束。变量y(i,j,k)
代表问题的解决方案,以及辅助变量Z(i,j)
指示是否为开启发电机充电。y
是一个nPeriods逐nGens×2
数组,并Z.
是一个nperiods-by-ngens
数组中。所有变量都是二进制的。
y = Optimvar('Y'nPeriods ngen, {“低”那'高的'},'类型'那'整数'那下界的,0,…“上界”1);z = optimvar (“z”,nperiods,ngens,'类型'那'整数'那下界的,0,…“上界”1);
为了确保功率电平没有超过一个等于1的组件,请设置线性不等式约束。
powercons = Y(:,:,“低”)+ Y(:,:,'高的') < = 1;
每个时期的运行成本是该时期的燃料成本。为发电机j
在操作层面K.
,成本是fuelPrice *燃料(J,K)
.
创建一个表达式fuelUsed
这占所有使用的燃料。
yFuel =零(nPeriods,nGens,2);yFuel(:,1,1)=燃料(1,1);在低设定值%燃料利用发电机1的yfuel(:,1,2)=燃料(1,2);%发电机1在高设定时的燃料消耗量yFuel(: 2 1) =燃料(2,1);在低设定值%燃料利用发电机2的yFuel(: 2 2) =燃料(2,2);%燃料在高设置中使用发电机2fuelUsed =总和(求和(总和(Y * yFuel))。);
约束是所使用的燃料是不超过燃料可用。
燃料=燃料<= totalfuel;
如何让解算器设置Z.
变量自动匹配匹配的活动/关闭期y
变量?回想一下,要满足的条件是z (i, j) = 1
什么时候Sum_k y(i,j,k) = 0
和sum_k y(i + 1,j,k)= 1
.
请注意,sum_k( - y(i,j,k)+ y(i + 1,j,k))> 0
正好在你想要的时候z (i, j) = 1
.
因此,在问题的表述中包含这些线性不等式约束。
sum_k( - Y(I,J,K)+ Y(I + 1,J,K)) - Z(I,J)<= 0
.
此外,包括Z.
目标函数成本中的变量。与之Z.
在目标函数中的变量,解算器试图降低其值,这意味着它试图将它们全部设置为等于0。但是,对于那些间隔上时的发电机转动时,线性不等式的力Z(i,j)
为等于1。
创建一个辅助变量W.
这代表着Y(I + 1,J,K) - Y(I,J,K)
.代表发电机启动不平等条款W.
.
W = optimexpr(nPeriods,nGens);%分配wIDX = 1:(nPeriods-1);瓦特(IDX,:) = Y(IDX + 1,:,“低”) - Y(IDX,:,“低”)+ Y(IDX + 1,:,'高的') - Y(IDX,:,'高的');w(nperiods,:) = y(1,:,“低”) - Y(nPeriods,:,“低”)+ Y(1,:,'高的') - Y(nPeriods,:,'高的');Switchcons = w - z <= 0;
目标函数包括运行发电机的燃料成本,运行发电机的收入,以及启动发电机的成本。
generatorlevel =零(大小(yFuel));generatorlevel(:,1,1)=根(1,1);在级别%填充generatorlevel(:,1,2)=根(1,2);generatorlevel(:,2,1)=根(2,1);generatorlevel(:,2,2)=根(2,2);
来收入= y。* GeneratorLevel。* PoolPrice
.
收入= optimexpr(大小(y));为了2 = 1: nPeriods收入(ii):,:) = poolPrice (ii) * y (ii):,:)。* generatorlevel (ii):,:);结尾
总燃料成本=fuelUsed * fuelPrice
.
fuelCost = fuelUsed * fuelPrice;
发电机启动成本=Z * startCost
.
startingCost z = * startCost;
利润=收入-
燃料总成本-
启动成本。
利润=总和(求和(总和(收入))) - fuelCost - 总和(总和(startingCost));
创建优化问题并包括目标和约束。
调度= optimproblem (“ObjectiveSense”那'最大化');dispatch.objective =利润;dispatch.constraints.switchcons = switchcons;dispatch.constraints.fuelcons =燃料;dispatch.constraints.powercons = Powercons;
要保存空间,请抑制迭代显示。
选项= Optimoptions(“intlinprog”那'展示'那'最终的');
解决这个问题。
[dispatchsol, fval exitflag、输出]=解决(调度,'选项',选项);
使用intlinprog解决问题。找到最优解。Intlinprog停止是因为客观值在最优值选项的间隙公差范围内。AbsoluteGapTolerance = 0(默认值)。intcon变量是在公差选项内的整数。IntegerTolerance = 1e-05(默认值)。
绘制的溶液,作为时间的函数。
子图(3,1,1)栏(Dispatchsol.y(:,1,1)* Gen(1,1)+ Dispatchsol.y(:,1,2)* Gen(1,2),5,‘g’) xlim ([5, 48.5]) ylabel (“MWh”) 标题(“发电机1最优调度”那'fontWeight设置'那“大胆”)子图(3,1,2)栏(Dispatchsol.y(:,2,1)* Gen(1,1)+ Dispatchsol.y(:,2,2)* Gen(1,2),5,“c”) 标题(“发电机2最佳调度”那'fontWeight设置'那“大胆”) xlim ([5, 48.5]) ylabel (“MWh”)副区(3,1,3)巴(poolPrice,0.5)XLIM([。5,48.5])标题('能源价格'那'fontWeight设置'那“大胆”)包含(“时间”) ylabel ('$ /兆瓦时')
生成器2比生成器1运行的时间更长,这是您所期望的,因为它更高效。发电机2运行在它的高功率水平时,它是开着的。发电机1主要运行在它的高功率水平,但下降到低功率的一个时间单位。每个发电机每天运行一组连续的周期,因此,每天只产生一次启动成本。
检查Z.
变量为1表示生成器启动时的周期。
Starttimes = find(round(dispatchsol.z) == 1);%用途一轮非整数结果[theperiod,thegenerator] = ind2sub(大小(dispatchsol.z),starttimes)
theperiod =2×123日16
thegenerator =2×11 2
期间当发电机开始匹配的地块。
如果指定一个较低的值startCost
的解决方案涉及多代周期。
startCost = 500;%选择一个较低的惩罚启动发电机startingCost z = * startCost;利润= sum(sum(sum(revenue)) - fuelCost - sum(sum(startingCost));dispatch.objective =利润;[dispatchsolnew, fvalnew exitflagnew outputnew] =解决(调度,'选项',选项);
使用intlinprog解决问题。找到最优解。Intlinprog停止是因为客观值在最优值选项的间隙公差范围内。AbsoluteGapTolerance = 0(默认值)。intcon变量是在公差选项内的整数。IntegerTolerance = 1e-05(默认值)。
次要情节(1,1)栏(dispatchsolnew.y(:, 1, 1) *创(1,1)+ dispatchsolnew.y(:, 1, 2) *创(1、2),5,‘g’) xlim ([5, 48.5]) ylabel (“MWh”) 标题(“发电机1最优调度”那'fontWeight设置'那“大胆”次要情节(3、1、2)酒吧(dispatchsolnew.y(:, 2, 1) *创(1,1)+ dispatchsolnew.y(:, 2, 2) *创(1、2),5,“c”) 标题(“发电机2最佳调度”那'fontWeight设置'那“大胆”) xlim ([5, 48.5]) ylabel (“MWh”)副区(3,1,3)巴(poolPrice,0.5)XLIM([。5,48.5])标题('能源价格'那'fontWeight设置'那“大胆”)包含(“时间”) ylabel ('$ /兆瓦时')
Starttimes = find(round(dispatchsolnew.z) == 1);%用途一轮非整数结果[Period,TheGenerator] = Ind2Sub(大小(Dispatchsolnew.z),starttifs)
theperiod =3×122 16 45
thegenerator =3×11 2 2