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

📄 fm_annealing.m

📁 这是一个很适合研究和学习用的电力系统仿真软件
💻 M
字号:
function [nu,nl,pmu_test, I_idx, pseudoi, ok] = fm_annealing(rangoH,ntest,pmu_test,nu,nl,hdl_nob,zeroinj)
% FM_ANNEALING define the Simulated  Aneealing method for
%              PMU placement
%
% (...) = FM_ANNEALING(...)
%
% This function is generally called by FM_PMULOC
%
%Author:    Federico Milano
%Date:      11-Nov-2002
%Version:   1.0.0
%
%E-mail:    fmilano@thunderbox.uwaterloo.ca
%Web-site:  http://thunderbox.uwaterloo.ca/~fmilano
%
% Copyright (C) 2002-2006 Federico Milano

global Bus Line Fig

if nu == 1; ok = 1; return; end

E = Bus.n - rangoH;
T = 15;
a = 0.0002;
if Bus.n < 20, a = 0.002; end
M = min(5000, round(a*nchoosek(Bus.n,ntest)));
if M == 0; M = 1; end

for qwerty = 1:40
  for ytrewq = 1:M
    pmusel = randperm(ntest);
    selected_pmu = pmu_test(pmusel(1));
    pmu_test_new = pmu_test(find(pmu_test ~= selected_pmu));

    bus_mis = Bus.int(pmu_test);
    n_mis = length(pmu_test);
    bus_cal = Bus.int(Bus.con(:,1));
    cal_con = Bus.con(:,1);
    a = [];
    for ii = 1:length(pmu_test)
      a = [a; find(bus_cal == bus_mis(ii))];
    end
    if ~isempty(a)
      bus_cal(a) = [];
      cal_con(a) = [];
    end
    n_cal = length(bus_cal);

    while 1
      nonpmusel = randperm(n_cal);
      selected_non_pmu = cal_con(nonpmusel(1));
      i_idx = fm_iidx(selected_non_pmu,Line.con);
      if length(i_idx(:,1)) > 1
        pmu_test_new = [pmu_test_new; selected_non_pmu];
        break;
      end
    end

    linee = Line.con(:,[1 2]);
    I_idx = [];
    nodi = [];
    pseudoi = 0;

    for ijk = 1:ntest
      i_idx = fm_iidx(pmu_test_new(ijk),linee);
      I_idx = [I_idx; i_idx];
      % nodi osservabili dal primo PMU
      nodi_oss = [i_idx(:,4);pmu_test_new(ijk)];
      nodi = [nodi; nodi_oss];
      %linee(i_idx(:,2),[1 2]) = zeros(length(nodi_oss)-1,2);
    end

    % determinazione delle pseudo-correnti  determinate con la
    % legge di Kirchhoff per le correnti
    % ed eliminazione dei nodi di cui si può determinare la
    % tensione con la legge di Ohm
    % determinazione delle pseudo-correnti nelle linee ai cui
    % estremi sono note le tensioni
    for ii = 1:length(nodi)
      I_idx_from = find(linee(:,1) == nodi(ii));
      if ~isempty(I_idx_from)
        I_idx_to = [];
        for jj = 1:length(I_idx_from)
          if ~isempty(find(nodi == linee(I_idx_from(jj),2)))
            I_idx_to = [I_idx_to; I_idx_from(jj)];
          end
        end
        if ~isempty(I_idx_to);
          n_current = length(I_idx_to);
          api = [[1:n_current]', I_idx_to];
          bpi = linee(I_idx_to,[1 2]);
          cpi = ones(length(I_idx_to),1);
          pi_idx = [api, bpi, cpi];
          linee(pi_idx(:,2),[1 2]) = zeros(length(pi_idx(:,1)),2);
          I_idx = [I_idx; pi_idx];
          pseudoi = pseudoi + length(pi_idx(:,1));
        end
      end
    end

    count = 1;
    while count < length(nodi)

      if zeroinj(Bus.int(nodi(count))) == 0
        I_idx_from = find(linee(:,1) == nodi(count));
        I_idx_to = find(linee(:,2) == nodi(count));
        ncfrom = length(I_idx_from);
        ncto = length(I_idx_to);
        nc = ncfrom + ncto;
        if nc == 1
          if ncfrom == 1
            ki_idx = [1, I_idx_from, linee(I_idx_from,[1 2]), 1];
          else
            ki_idx = [1, I_idx_to, linee(I_idx_to,[2 1]), -1];
          end
          linee(ki_idx(2),[1 2]) = zeros(length(ki_idx(1)),2);
          I_idx = [I_idx; ki_idx];
          pseudoi = pseudoi + length(ki_idx(1));
          nodi_oss = [nodi_oss; ki_idx(4)];
          nodi = [ki_idx(4); nodi];

          % dopo l'aggiunta di un nuovo nodo misurato bisogna
          % ricontrollare tutti i nodi
          count = 1;

          % ricerca di pseudo-correnti che possono essere
          % misurate con il nodo aggiunto
          for ii = 1:length(nodi)
            I_idx_from = find(linee(:,1) == nodi(ii));
            if ~isempty(I_idx_from)
              I_idx_to = [];
              for jj = 1:length(I_idx_from)
                if ~isempty(find(nodi == linee(I_idx_from(jj),2)))
                  I_idx_to = [I_idx_to; I_idx_from(jj)];
                end
              end
              if ~isempty(I_idx_to);
                n_current = length(I_idx_to);
                api = [[1:n_current]', I_idx_to];
                bpi = linee(I_idx_to,[1 2]);
                cpi = ones(length(I_idx_to),1);
                pi_idx = [api, bpi, cpi];
                linee(pi_idx(:,2),[1 2]) = zeros(length(pi_idx(:,1)),2);
                I_idx = [I_idx; pi_idx];
                pseudoi = pseudoi + length(pi_idx(:,1));
              end
            end
          end

        else
          count = count + 1;
        end
      else
        count = count + 1;
      end
    end

    nodi_ord = sort(nodi);
    num_nodi = length(nodi);
    nodi_el = [];
    for jjj = 1:num_nodi
      nodi_el = [nodi_el; jjj+find(nodi_ord([jjj+1:num_nodi]) == ...
                                   nodi_ord(jjj))];
    end
    nodi_ord(nodi_el) = [];


    if length(nodi_ord) == Bus.n
      I_idx(:,1) = [1:length(I_idx(:,1))]';
      [Vest, angest, rangoH] = fm_lssest(pmu_test_new, I_idx,0);
      Enew = Bus.n - rangoH;
    else
      Enew = Bus.n - length(nodi_ord);
    end
    if Fig.pmu
      set(hdl_nob,'String',int2str(Enew));
      drawnow
    end
    if Enew == 0;
      nu = ntest;
      pmu_test = pmu_test_new;
      ok = 1;
      return
    end
    deltaE = Enew - E;
    if deltaE > 0
      probE = exp(-deltaE/T);
      %nprobE = 1-probE;
      %pE = [ones(1,round(probE*1e5)), zeros(1,round(nprobE*1e5))];
      %p = randperm(length(pE));
      %pE = pE(p);
      %if pE(1)
      if rand <= probE
        pmu_test = pmu_test_new;
        E = Enew;
      end
    else
      pmu_test = pmu_test_new;
      E = Enew;
    end

  end
  T = 0.879*T;
end
nl = ntest;
ok = 0;

⌨️ 快捷键说明

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