このページの翻訳は最新ではありません。ここをクリックして,英語の最新版を参照してください。
この例では,収益からコストを引いた後の利益を最大化するよう,2台のガス火力発電機の最適な運転スケジュールを設定する方法を示します。必ずしも現実的な例ではありませんが,判定のタイミングに応じて変動するコストを考慮する方法が説明されています。
この問題に対するソルバーベースのアプローチについては,発電機の最適な運転スケジュール:ソルバーベースを参照してください。
電力市場の価格は,一日の間にその時間帯によって変動します。発電機を運転する場合、価格が高い時間帯に稼働するようスケジュールを設定することで、この価格の変動を有利に利用することができます。たとえば、2 台の発電機を管理していると仮定します。各発電機にオフ、低、高の 3 つの稼働レベルがあり、そのレベルごとに各発電機の燃料消費と電力生産量が決まっています。発電機がオフのときの燃料消費量は 0 になります。
1日につき30分ごとの間隔(つまり24時間に48回)で,各発電機に稼働レベルを割り当てることができます。過去の記録から,この各時間枠におけるメガワット時(MWh)あたりの収益がわかっているとします。この例のデータは澳大利亚能源市场运营商提供によるhttps://www.nemweb.com.au/REPORTS/CURRENT/
2013年中期レポートから引用したもので,同社の利用条件https: /
/
www。
aemo。
com。
非盟/
privacy-and-legal-notices /
copyright-permissions
のもとに使用されています。
负载dispatchPrice;% Get poolPrice,这是每MWh的收入栏(poolPrice。5)xlim([5, 48.5])包含(“每个时期每兆瓦时的价格”)
発電機をいったんオフにした後で運転を再開するには,コストがかかります。さらに1日の最大燃料消費量の制約も適用されます。この制約があるのは,燃料は前日に購入し,購入しただけの分しか使用できないためです。
このスケジュール設定問題は,0 - 1整数計画問題として定式化できます。インデックス我
、j
およびk
と2値のスケジュール設定ベクトルy
を,次のように定義します。
nPeriods
=期間数(ここでは48)。
我
= 1 期間、1 <=我
<= 48。
j
=発電機インデックス,ここでは1 < =j
<= 2。
期間我
に発電機j
がレベルk
で稼働している場合,y (i, j, k) = 1
となります。ここで低稼働レベルをk = 1
とし,高稼働レベルをk = 2
とします。Sum_k y(i,j,k) = 0
の場合,発電機はオフになっています。
オフにした発電機について,運転をいつ再開するかを判断します。そのため,期間我
に発電機j
の運転開始にコストがかかるかどうかを示す補助2値変数z (i, j)
を定義します。
発電機j
が期間我
にオフで,期間我+ 1
にオンの場合はz (i, j) = 1
。それ以外の場合はz (i, j) = 0
。言い換えれば,Sum_k y(i,j,k) = 0
かつSum_k y(i+1,j,k) = 1
のときにz (i, j) = 1
となります。
ここで,y
の設定に基づいてz
を自動的に設定する方法が必要になります。この設定は,次の線形制約によって処理します。
上記のほかに,コスト,各発電機の電力生産レベル,消費レベルおよび使用できる燃料を表すパラメーターも必要です。
poolPrice(我)
-- 期間我
におけるMWhあたりの収益(ドル単位)
创(j, k)
-- 発電機j
によって稼働レベルk
で生産される兆瓦数
燃料(j, k)
-- 発電機j
によって稼働レベルk
で消費される燃料
totalFuel
——1日に使用できる燃料
startCost
——いったんオフにした発電機を再稼働させるためのコスト(ドル単位)
fuelPrice
——燃料の単位あたりコスト
poolPrice
は加载dispatchPrice;
の実行時に計算済みです。その他のパラメーターは次のように設定します。
fuelPrice = 3;totalFuel = 3.95 e4;nPeriods =长度(poolPrice);% 48期ngen = 2;%两个发电机创= (61152;50150);%发电机1低= 61 MW,高= 152 MW燃料= (427806;325765);%发电机2的燃料消耗低= 325,高= 765startCost = 1 e4;%发电机关闭后启动的成本
2つの稼働点における,2台の発電機の効率性を調べます。
效率= /燃料将军;计算单位燃料耗电量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-by-nGens-by-2
の配列,z
はnPeriods-by-nGens
の配列です。変数はすべて2 値です。
y = optimvar (“y”nPeriods ngen, {“低”,“高”},“类型”,“整数”,下界的0,...“UpperBound”1);z = optimvar (“z”nPeriods ngen,“类型”,“整数”,下界的0,...“UpperBound”1);
稼働レベルに1に等しい成分が複数指定されないように,線形不等式制約を設定します。
powercons = y (:,:“低”) + y (:,:“高”) < = 1;
1期間あたりの運転費が,その期間の燃料コストです。発電機j
がレベルk
で稼働している場合,コストはfuelPrice *燃料(j, k)
となります。
消費されるすべての燃料を考慮した式fuelUsed
を作成します。
yFuel = 0 (nPeriods ngen 2);yFuel(:, - 1, - 1) =燃料(1,1);%发电机1在低设定时的燃料消耗量yFuel(:, 1, 2) =燃料(1、2);%发电机1在高设定时的燃料消耗量yFuel(: 2 1) =燃料(2,1);%发电机2在低设定时的燃料消耗量yFuel(: 2 2) =燃料(2,2);%发电机2在高设定时的燃料消耗量fuelUsed =总和(总和(sum (y。* yFuel)));
制約は,消費される燃料が使用できる燃料以下であることです。
fuelcons = fuelUsed <= totalFuel;
変数y
のオンとオフの期間に応じてソルバーが変数z
を自動的に設定できるようにするには,次のようにします。条件z (i, j) = 1
が厳密にSum_k y(i,j,k) = 0
とSum_k y(i+1,j,k) = 1
という条件下において満たされる必要がある点に注意します。
z (i, j) = 1
が厳密に満たされる場合に,Sum_k (- y(i,j,k) + y(i+1,j,k)) > 0
となることがわかります。
したがって,問題の定式化に次の線形不等式制約を含めます。
Sum_k (- y(i,j,k) + y(i+1,j,k)) - z(i,j) < = 0
.
また,目的関数のコストに変数z
を含めます。目的関数内の変数z
に対し,ソルバーはその値を低くしようとします。つまり,ソルバーはすべての値を0に等しく設定しようとします。しかし,発電機がオンになっている期間では,線形不等式によってz (i, j)
が1に等しくなるよう強制されます。
y (i + 1 j k) - y (i, j, k)
を表す補助変数w
を作成します。w
に関して発電機の運転開始時の不等式を表します。
w = optimexpr (nPeriods ngen);%分配widx = 1:(nPeriods-1);w (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 = 0(大小(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;
利益 = 収益-
合計燃料コスト-
運転開始コストです。
利润= sum(sum(sum(revenue)) - fuelCost - sum(sum(startingCost));
最適化問題を作成し,目的と制約を含めます。
调度= optimproblem (“ObjectiveSense”,“最大化”);调度。目标=利润;dispatch.Constraints.switchcons = switchcons;dispatch.Constraints.fuelcons = fuelcons;dispatch.Constraints.powercons = powercons;
スペースを節約するため,反復表示を抑制します。
选择= optimoptions (“intlinprog”,“显示”,“最后一次”);
問題を解きます。
[dispatchsol, fval exitflag、输出]=解决(调度,“选项”、选择);
使用intlinprog解决问题。找到最优解。Intlinprog停止是因为客观值在最优值选项的间隙公差范围内。AbsoluteGapTolerance = 0(默认值)。intcon变量是在公差选项内的整数。IntegerTolerance = 1e-05(默认值)。
解を時間の関数としてプロットします。
次要情节(1,1)栏(dispatchsol.y(:, 1, 1) *创(1,1)+ dispatchsol.y(:, 1, 2) *创(1、2),5,‘g’) xlim ([5, 48.5]) ylabel (“MWh”)标题(“发电机1最佳调度”,“FontWeight”,“大胆”次要情节(3、1、2)酒吧(dispatchsol.y(:, 2, 1) *创(1,1)+ dispatchsol.y(:, 2, 2) *创(1、2),5,“c”)标题(“发电机2最佳调度”,“FontWeight”,“大胆”) xlim ([5, 48.5]) ylabel (“MWh”) subplot(3,1,3) bar(poolPrice,.5) xlim([.5,48.5]) title(能源价格的,“FontWeight”,“大胆”)包含(“时间”) ylabel (“美元/千瓦时”)
発電機2は発電機1より長い時間稼働します。これは発電機2の方が効率性が高いことから容易に予想できます。発電機2が稼働するときは,常に最高のレベルで稼働します。発電機1 は主に高レベルで稼働しますが、1 期間に限り低レベルに落として稼働します。各発電機は毎日連続した期間にわたって稼働するため、運転開始コストが発生するのは毎日 1 度だけです。
発電機が運転を開始する期間のz
変数が1であることを確認してください。
Starttimes = find(round(dispatchsol.z) == 1);%对于非整数结果使用round(年度变化平均数低于thegenerator] = ind2sub(大小(dispatchsol.z),开始时间)
年度变化平均数低于=2×123日16
thegenerator =2×11 2
発電機がオンになる期間は,プロットに一致しています。
startCost
の値を小さくすると,解で複数の電力生産期間が使用されます。
startCost = 500;选择一个较低的惩罚启动发电机startingCost z = * startCost;利润= sum(sum(sum(revenue)) - fuelCost - sum(sum(startingCost));调度。目标=利润;[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”) subplot(3,1,3) bar(poolPrice,.5) xlim([.5,48.5]) title(能源价格的,“FontWeight”,“大胆”)包含(“时间”) ylabel (“美元/千瓦时”)
Starttimes = find(round(dispatchsolnew.z) == 1);%对于非整数结果使用round(年度变化平均数低于thegenerator] = ind2sub(大小(dispatchsolnew.z),开始时间)
年度变化平均数低于=3×122日16 45
thegenerator =3×11 2 2