天天看點

固定簇半徑的分簇協定HEED matlab代碼

文章目錄

  • 一、理論基礎
  • 二、分簇過程
  • 三、MATLAB程式實作
  • 四、參考文獻
固定簇半徑的分簇協定HEED matlab代碼
固定簇半徑的分簇協定HEED matlab代碼
%% 清空環境變量
clear;
clc;
% 傳感器節點區域100×100
xm = 100;
ym = 100;
% 基站坐标
sink.x = 0.5*xm;
sink.y = 0.5*ym;
% 節點總數100
NodeNums = 100;
% 節點成為簇頭的初始機率和機率門檻值
Cprob = 0.05;
pmin = 0.04;
packetLength = 4000;      % 資料包長度
ctrPacketLength = 100;    % 控制包長度
% 初始能量(最大能量) 0.3J
Eo = 0.3;
% 發送能耗RTX = 接收能耗ERX = 50nJ/bit
ETX=50*10^(-9);
ERX=50*10^(-9);
% 發射放大器類型
Efs=10*10^(-12);
Emp=0.0013*10^(-12);
% 資料聚合能量
EDA=5*10^(-9);
% 最大輪數
rmax = 5;
% the time of round
Tr=20;
distanceBroad = sqrt(Tr^2+Tr^2);
% 臨界距離
do = sqrt(Efs/Emp);
% 節點類型
NON_CH = 0;         % 普通節點
TENT_CH = 1;        % 臨時簇頭
FINAL_CH = 2;       % 最終簇頭

figure(1);
%% 傳感器節點的随機分布
for i = 1:NodeNums
    Node(i).xd = rand(1,1)*xm;
    Node(i).yd = rand(1,1)*ym;
    Node(i).RE = Eo;                  % 節點能量
    Node(i).NumNbr = 0;               % 鄰居節點數
    Node(i).AMRP = Node(i).NumNbr;    % 平均可達能級
    Node(i).CH = 0;                   % 簇頭
    Node(i).role = NON_CH;            % 節點角色
    plot(Node(i).xd, Node(i).yd, 'o', sink.x, sink.y, '*r');
    hold on;
    title 'Wireless Sensor Network';
    xlabel 'X-coordinates';
    ylabel 'Y-coordinates';
    legend('節點', '基站');
end
hold off;
%% 計算每個節點的鄰居節點集
for i = 1:NodeNums
    count = 0;  % 計數器:用于統計每個節點的鄰居節點總數
    for j = 1:NodeNums
        if j ~= i
            dist = sqrt((Node(i).xd-Node(j).xd).^2 + (Node(i).yd-Node(j).yd).^2);   % 節點i與節點j距離的平方
            if dist < distanceBroad  % 如果此距離小于廣播半徑,則可認為j是i的鄰居節點
                count = count +1;
                Node(i).Nbr(count) = j; % j是i的一個鄰居節點
            end
        end
        if j == NodeNums % 說明循環到了最後一個節點
            Node(i).NumNbr = count;     % 節點i的鄰居節點個數count
        end
    end
end

%% 分簇階段
for r = 1:rmax
%     % 死亡節點總數
%     dead = 0;
%     % 計算節點死亡數目
%     for i = 1:NodeNums
%         if Node(i).RE <= 0  % 統計節點死亡數目
%             dead = dead + 1;
%         end
%     end
%     if dead == NodeNums  % 節點全部死亡退出循環
%         break;
%     end
    s = 0;
    % 第一步:初始化
    for i = 1:NodeNums
        Node(i).RE = Eo;
        Node(i).CHprob = max(Cprob*(Node(i).RE/Eo), pmin);
        Node(i).AMRP = Node(i).NumNbr;    % 平均可達能級
        Node(i).CH = 0;
        Node(i).role = NON_CH;                     % 節點角色
        Node(i).stop = 1;
        s = s + Node(i).stop;
    end
    % 第二步:疊代,直至節點機率為1或節點死亡(能量耗盡)
    while s ~= 0
        s = 0;
        for i = 1:NodeNums
            Node(i).CHprob = max(Cprob*(Node(i).RE/Eo), pmin);
        end
        for i = 1:NodeNums
            if Node(i).RE > 0 && Node(i).CHprob <= 1
                flag0 = 0;
                flag1 = 0;
                for j = 1:Node(i).NumNbr
                    neighbor = Node(i).Nbr(j);
                    if Node(neighbor).role == TENT_CH
                        flag0 = 1;
                        if Node(i).AMRP > Node(neighbor).AMRP
                            flag1 = 1;
                        end
                    end
                end
                % 自身是臨時簇頭
                if Node(i).role == TENT_CH
                    if flag0 == 1 && flag1 == 0  % 周圍有臨時簇頭且自身的AMRP值最小
                        if Node(i).CHprob == 1      % 機率為1
                            Node(i).CH = -1;
                            Node(i).RE = Node(i).RE-(ETX*ctrPacketLength+Efs*ctrPacketLength*distanceBroad^2);
                            % 鄰居節點接收消息
                            for j = 1:Node(i).NumNbr
                                neighbor = Node(i).Nbr(j);
                                Node(neighbor).RE = Node(neighbor).RE-ERX*ctrPacketLength;
                            end
                        end
                    end
                end
                % 鄰居節點無臨時簇頭
                if flag0 == 0
                    if rand <= Node(i).CHprob
                        Node(i).role = TENT_CH;
                        Node(i).RE = Node(i).RE-(ETX*ctrPacketLength+Efs*ctrPacketLength*distanceBroad^2);
                        % 鄰居節點接收消息
                        for j = 1:Node(i).NumNbr
                            neighbor = Node(i).Nbr(j);
                            Node(neighbor).RE = Node(neighbor).RE-ERX*ctrPacketLength;
                        end
                    end
                end
                % 備選簇頭狀态
                if Node(i).CHprob < 1
                    Node(i).role = TENT_CH;
                    Node(i).RE = Node(i).RE-(ETX*ctrPacketLength+Efs*ctrPacketLength*distanceBroad^2);
                    x = Node(i).AMRP;
                    for j = 1:Node(i).NumNbr
                        neighbor = Node(i).Nbr(j);
                        Node(neighbor).RE = Node(neighbor).RE-ERX*ctrPacketLength;
                        if Node(neighbor).role ~= NON_CH    % 簇頭節點
                            if Node(i).AMRP > Node(neighbor).AMRP   % AMRP值更小
                                Node(i).role = NON_CH;      % 改為普通節點
                                Node(i).CH = neighbor;       % 加入該候選簇頭
                                Node(i).AMRP = Node(neighbor).AMRP;
                            end
                        end
                    end
                    Node(i).AMRP = x;
                else    % 最終簇頭狀态
                    Node(i).role = FINAL_CH;
                    Node(i).CH = -1;
                    Node(i).RE = Node(i).RE-(ETX*ctrPacketLength+Efs*ctrPacketLength*distanceBroad^2);
                    for j = 1:Node(i).NumNbr
                        neighbor = Node(i).Nbr(j);
                        Node(neighbor).RE = Node(neighbor).RE-ERX*ctrPacketLength;
                    end
                end
            else
                Node(i).stop = 0;
            end
            s = s+Node(i).stop;
            Node(i).CHprob = min(Node(i).CHprob * 2, 1);
        end
    end
    %% 第三,處理孤兒節點
    for i = 1:NodeNums
        if Node(i).RE > 0
            if Node(i).role ~= FINAL_CH
                flag = 0;
                for j = 1:Node(i).NumNbr
                    neighbor = Node(i).Nbr(j);
                    if Node(neighbor).role ~= NON_CH    % 簇頭節點
                        flag = 1;
                        y = Node(i).AMRP;
                        if Node(i).AMRP > Node(neighbor).AMRP   % AMRP值更小
                            Node(i).role = NON_CH;      % 改為普通節點
                            Node(i).CH = neighbor;       % 加入該候選簇頭
                            Node(i).AMRP = Node(neighbor).AMRP;
                        end
                    end
                end
                if flag == 0
                    Node(i).CH = -1;
                    Node(i).role = FINAL_CH;
                else
                    Node(i).AMRP = y;
                end
            end
        end
    end
    figure(r+1)
    %% 畫出分簇圖
    for i = 1:NodeNums
        if Node(i).role ~= NON_CH
            plot(Node(i).xd, Node(i).yd, '*'); % 簇頭節點以*标記
            hold on
            text(Node(i).xd, Node(i).yd, num2str(i));
        else
            plot(Node(i).xd, Node(i).yd, 'o');   %普通節點以o标記
            text(Node(i).xd, Node(i).yd, num2str(i));
            hold on
            plot([Node(Node(i).CH).xd; Node(i).xd], [Node(Node(i).CH).yd; Node(i).yd]);  % 将節點與簇頭連起來,即加入簇頭集合
            hold on
        end
    end
end

      

繼續閱讀