⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 auction.m

📁 电力系统计算软件
💻 M
字号:
function [co, cb] = auction(offers, bids, auction_type, limit_prc, gtee_prc)%AUCTION  Clear auction based on OPF results (qty's and lambdas).%   [co, cb] = auction(offers, bids, auction_type, limit_prc, gtee_prc)%   Clears a set of bids and offers based on the results of an OPF, where the%   pricing is adjusted for network losses and binding constraints.%   The arguments offers and bids are structs with the following fields:%       qty       - m x n, offer/bid quantities, m offers/bids, n blocks%       prc       - m x n, offer/bid prices%       lam       - m x n, corresponding lambdas%       total_qty - m x 1, total quantity cleared for each offer/bid%%   There are 8 types of auctions implemented, specified by auction_type.%%      0 - discriminative pricing (price equal to offer or bid)%      1 - last accepted offer auction%      2 - first rejected offer auction%      3 - last accepted bid auction%      4 - first rejected bid auction%      5 - first price auction (marginal unit, offer or bid, sets the price)%      6 - second price auction (if offer is marginal, price set by%             min(FRO,LAB), else max(FRB,LAO)%      7 - split the difference pricing (set by last accepted offer & bid)%      8 - LAO sets seller price, LAB sets buyer price%%   Whether or not cleared offer (bid) prices are guaranteed to be greater%   (less) than or equal to the corresponding offer (bid) price is specified by%   a flag gtee_prc.offer (gtee_prc.bid). The default is value true.%   %   Offer/bid and cleared offer/bid min and max prices are specified in the%   limit_prc struct with the following fields:%       max_offer%       min_bid%       max_cleared_offer%       min_cleared_bid%   Offers (bids) above (below) max_offer (min_bid) are treated as withheld%   and cleared offer (bid) prices above (below) max_cleared_offer%   (min_cleared_bid) are clipped to max_cleared offer (min_cleared_bid) if%   given. All of these limit prices are ignored if the field is missing%   or is empty.%   MATPOWER%   $Id: auction.m,v 1.15 2005/10/17 22:21:01 ray Exp $%   by Ray Zimmerman, PSERC Cornell%   Copyright (c) 1996-2005 by Power System Engineering Research Center (PSERC)%   See http://www.pserc.cornell.edu/matpower/ for more info.%%-----  initialization  -----%% define named indices into data matrices[PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...    VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;[GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...    MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...    QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;[AREA_I, PRICE_REF_BUS] = idx_area;%% initialize some stuffif have_fcn('minopf')    zero_tol = 1e-5;else    zero_tol = 0.1;     %% fmincon is SO bad with prices that it isend                     %% NOT recommended for use with auction.mbig_num = 1e6;if isempty(bids)    bids = struct(  'qty', [], ...                    'prc', [], ...                    'lam', [], ...                    'total_qty', [] );endif nargin < 4 | isempty(limit_prc)    limit_prc = struct( 'max_offer', [], 'min_bid', [], ...                        'max_cleared_offer', [], 'min_cleared_bid', [] );else    if ~isfield(limit_prc, 'max_offer'),         limit_prc.max_offer = [];         end    if ~isfield(limit_prc, 'min_bid'),           limit_prc.min_bid = [];           end    if ~isfield(limit_prc, 'max_cleared_offer'), limit_prc.max_cleared_offer = []; end    if ~isfield(limit_prc, 'min_cleared_bid'),   limit_prc.min_cleared_bid = [];   endendif nargin < 5 | isempty(gtee_prc)    gtee_prc = struct(  'offer', 1, 'bid', 1    );else    if ~isfield(gtee_prc, 'offer'), gtee_prc.offer = 1; end    if ~isfield(gtee_prc, 'bid'),   gtee_prc.bid = 1;   endend[nro, nco] = size(offers.qty);[nrb, ncb] = size(bids.qty);%% determine cleared quantitiesif isempty(limit_prc.max_offer)    [co.qty, o.on, o.off] = clear_qty(offers.qty, offers.total_qty);else    mask = offers.prc <= limit_prc.max_offer;    [co.qty, o.on, o.off] = clear_qty(offers.qty, offers.total_qty, mask);endif isempty(limit_prc.min_bid)    [cb.qty, b.on, b.off] = clear_qty(bids.qty, bids.total_qty);else    mask = bids.prc <= limit_prc.min_bid;    [cb.qty, b.on, b.off] = clear_qty(bids.qty, bids.total_qty, mask);end%% initialize cleared pricesco.prc  = zeros(nro, nco);              %% cleared offer pricescb.prc  = zeros(nrb, ncb);              %% cleared bid prices%%-----  compute shift values to add to lam to get desired pricing  -----%% The locationally adjusted offer/bid price, when normalized to an arbitrary%% reference location where lambda is equal to ref_lam, is:%%      norm_prc = prc + (ref_lam - lam)%% Then we can define the difference between the normalized offer/bid prices%% and the ref_lam as:%%      diff = norm_prc - ref_lam = prc - lam%% This diff represents the gap between the marginal unit (setting lambda)%% and the offer/bid price in question.offer_diff = offers.prc - offers.lam;bid_diff   = bids.prc   - bids.lam;%% shift.LAO + lambda is equal to the last accepted offershift.LAO = o.on .* offer_diff - o.off * big_num;shift.LAO( find(shift.LAO(:) > zero_tol) ) = -big_num;  %% don't let gens @ Pmin set priceshift.LAO = max( shift.LAO(:) );%% shift.FRO + lambda is equal to the first rejected offershift.FRO = o.off .* offer_diff + o.on * big_num;shift.FRO = min( shift.FRO(:) );if nrb    %% shift.LAB + lambda is equal to the last accepted bid    shift.LAB = b.on .* bid_diff + b.off * big_num;    shift.LAB = min( shift.LAB(:) );        %% shift.FRB + lambda is equal to the first rejected bid    shift.FRB = b.off .* bid_diff - b.on * big_num;    shift.FRB = max( shift.FRB(:) );else    shift.LAB = big_num;    shift.FRB = shift.LAB;end%% cleared offer/bid prices for different auction typesif auction_type == 0        %% discriminative    co.prc = offers.prc;    cb.prc = bids.prc;elseif auction_type == 1    %% LAO    co.prc = offers.lam + shift.LAO;    cb.prc = bids.lam   + shift.LAO;elseif auction_type == 2    %% FRO    co.prc = offers.lam + shift.FRO;    cb.prc = bids.lam   + shift.FRO;elseif auction_type == 3    %% LAB    co.prc = offers.lam + shift.LAB;    cb.prc = bids.lam   + shift.LAB;elseif auction_type == 4    %% FRB    co.prc = offers.lam + shift.FRB;    cb.prc = bids.lam   + shift.FRB;elseif auction_type == 5    %% 1st price    co.prc = offers.lam;    cb.prc = bids.lam;elseif auction_type == 6    %% 2nd price    if abs(shift.LAO) < zero_tol        co.prc = offers.lam + min(shift.FRO,shift.LAB);        cb.prc = bids.lam   + min(shift.FRO,shift.LAB);    else        co.prc = offers.lam + max(shift.LAO,shift.FRB);        cb.prc = bids.lam   + max(shift.LAO,shift.FRB);    endelseif auction_type == 7    %% split the difference    co.prc = offers.lam + (shift.LAO + shift.LAB) / 2;    cb.prc = bids.lam   + (shift.LAO + shift.LAB) / 2;elseif auction_type == 8    %% LAO seller, LAB buyer    co.prc = offers.lam + shift.LAO;    cb.prc = bids.lam   + shift.LAB;end%% guarantee that cleared offer prices are >= offersif gtee_prc.offer    clip = o.on .* (offers.prc - co.prc);    co.prc = co.prc + (clip > zero_tol) .* clip;end%% guarantee that cleared bid prices are >= bidsif gtee_prc.bid    clip = b.on .* (bids.prc - cb.prc);    cb.prc = cb.prc + (clip < -zero_tol) .* clip;end%% clip cleared offer prices by limit_prc.max_cleared_offerif ~isempty(limit_prc.max_cleared_offer)    co.prc = co.prc + (co.prc > limit_prc.max_cleared_offer) .* ...        (limit_prc.max_cleared_offer - co.prc);end%% clip cleared bid prices by limit_prc.min_cleared_bidif ~isempty(limit_prc.min_cleared_bid)    cb.prc = cb.prc + (cb.prc < limit_prc.min_cleared_bid) .* ...        (limit_prc.min_cleared_bid - co.prc);end%% make prices uniform after clipping (except for discrim auction)%% since clipping may only affect a single block of a multi-block generatorif auction_type ~= 0    %% equal to largest price in row    if nco > 1        co.prc = diag(max(co.prc')) * ones(nro,nco);    end    if ncb > 1        cb.prc = diag(min(cb.prc')) * ones(nrb,ncb);    endendreturn;function [cqty, on, off] = clear_qty(qty, total_cqty, mask)%CLEAR_QTY  Computed cleared offer/bid quantities from totals.%  Inputs:%   qty        - m x n, offer/bid quantities, m offers/bids, n blocks%   total_cqty - m x 1, total cleared quantity for each offer/bid%   mask       - m x n, boolean indicating which offers/bids are valid (not withheld)%  Outputs:%   cqty       - m x n, cleared offer/bid quantities, m offers/bids, n blocks%   on         - m x n, 1 if partially or fully accepted, 0 if rejected%   off        - m x n, 1 if rejected, 0 if partially or fully accepted[nr, nc] = size(qty);accept  = zeros(nr,nc);cqty    = zeros(nr,nc);for i = 1:nr            %% offer/bid i    for j = 1:nc        %% block j        if qty(i, j)    %% ignore zero quantity offers/bids            %% compute fraction of the block accepted ...            accept(i, j) = (total_cqty(i) - sum(qty(i, 1:j-1))) / qty(i, j);            %% ... clipped to the range [0, 1]  (i.e. 0-100%)            if accept(i, j) > 1                accept(i, j) = 1;            elseif accept(i, j) < 1.0e-5                accept(i, j) = 0;            end            cqty(i, j) = qty(i, j) * accept(i, j);        end    endendif nargin == 3    accept = mask .* accept;endon  = (accept  > 0);off = (accept == 0);return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -