LEACH-C协议

LEACH-C协议Matlab源码,将三部分代码复制粘贴到一个matlab文件中执行即可。(还有LEACH版本,有需要的可以私聊我)(若代码有不足的地方,还请各位批评指正)

运行结果

主体代码(包含控制能耗和传输能耗)

% close all;
clear
clc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1.一阶无线电能耗模型(First Order Radio Model)%%%%%%%%%%%%%%%%%%%
for zh=1:1
    N=100;%节点个数
    sinkx=50;sinky=175;%基站位置
    xm=100;ym=100;%监测范围
    p=0.05;%簇头节点比例
    Eo=0.2;%初始能量
    Eelec=50*10^(-9);%电路能耗(Joules/bit)
    ETx=50*10^(-9);%传送能耗(Joules/bit)
    ERx=50*10^(-9);%接收能耗(Joules/bit)
    Efs=10*10^(-12);%自由空间模型能耗系数
    Emp=0.0013*10^(-12);%多径衰落模型能耗系数
    d0=sqrt(Efs/Emp);%临界值
    EDA=5*10^(-9);%数据聚合能耗
    Lc=100;%控制包大小(bit)
    Ld=4000;%数据包大小(bit)
    AD_Range=sqrt(xm^2+ym^2);%广播范围
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2.网络初始化 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for zh=1:1
%     load location.mat;%载入位置
    for i=1:N
        node(i).energy=Eo;%剩余能量
        node(i).location=[rand*xm rand*ym];%节点位置
%         node(i).location=location(i,:);%节点位置
        node(i).dtoBS=sqrt((node(i).location(1)-sinkx)^2+(node(i).location(2)-sinky)^2);%节点至基站距离
        node(i).status=0;%表明节点是否成为或成为过簇头:0为簇成员节点,1为簇头节点
        node(i).CH=0;% 表明节点的簇头
        node(i).CM=[];% 表明节点的簇成员
        node(i).CM_count=0;% 表明簇内的簇成员节点数
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3.网络运行  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for zh=1:1
    
    %%%%%%性能指标参数设置(包括存活节点数量、网络剩余能量、控制开销)%%%%%%
    for z=1:1
        r=0;%轮数
        number_AliveNodes=N;%存活节点数量
        residual_Energy=N*Eo;%网络剩余能量
        contorl_Overhead=0;%控制开销
        AliveNodes=1:1:N;%存活节点
        Throughput=0;%吞吐量
        %         figure(1)%画图
        %         for i=1:N
        %             plot(node(i).location(1),node(i).location(2),'bo','linewidth',1);
        %             hold on;
        %         end
        %         plot(sinkx,sinky,'rd','linewidth',2);hold on;
    end
    
    while number_AliveNodes>0%当节点存活数量>0时,网络正常运行
        %%%%%%%%%%%%%%%%%%%%%%%%%%% ①簇建立阶段 %%%%%%%%%%%%%%%%%%%%%%%%%%%%
        for z=1:1
            %%%%%%%%%节点将能量位置信息发送至基站(能量消耗)%%%%%%%%%
            for i=1:length(AliveNodes)
                d=sqrt((node(AliveNodes(i)).location(1)-sinkx)^2+((node(AliveNodes(i)).location(2)-sinky))^2);
                if d>d0
                    node(AliveNodes(i)).energy=node(AliveNodes(i)).energy-Lc*(Eelec+Emp*d^4);
                    contorl_Overhead=contorl_Overhead+Lc*(Eelec+Emp*d^4);%控制开销
                else
                    node(AliveNodes(i)).energy=node(AliveNodes(i)).energy-Lc*(Eelec+Efs*d^2);
                    contorl_Overhead=contorl_Overhead+Lc*(Eelec+Efs*d^2);%控制开销
                end
            end
            %%%%%%%%%基站使用模拟退火算法选择合适的簇头%%%%%%%%%
            for h=1:1
                CH=[];%簇头集合
                CM=[];%簇成员集合
                C_opt=round(number_AliveNodes*p);%最优簇头数量
                if C_opt==0
                    C_opt=1; %最小簇头数为1
                end
                %%%%%%%%%模拟退火算法(SMfunc1为计算适应度值的函数,SMfunc2为随机扰动的函数)%%%%%%%%%
                %%%%%%%%%参数%%%%%%%%%
                k=1;%迭代次数
                Niter=500;%最大迭代次数
                bounder=10;%边界
                %%%%%%%%%计算高于能量平均值的节点%%%%%%%%%
                Eavg=0;%平均能量
                count=0;%计数
                node_HE=[];%记录高能量的节点
                for i=1:length(AliveNodes)
                    Eavg=Eavg+node(AliveNodes(i)).energy;
                    count=count+1;
                end
                Eavg=Eavg/count;%平均能量
                for i=1:length(AliveNodes)
                    if node(AliveNodes(i)).energy>=Eavg
                        node_HE=[node_HE AliveNodes(i)];%记录高能量节点
                    end
                end
                
                %%%%%%%%%随机选点初值确定%%%%%%%%%
                if length(node_HE)<=C_opt
                    CH=node_HE;%记录簇头
                    count_CH=length(CH);%记录簇头个数
                else
                    CH=node_HE(randperm(length(node_HE),C_opt));%随机选取簇头
                    BestCH=CH;%记录最佳簇头
                    CM=AliveNodes(~ismember(AliveNodes,CH));%簇成员集合
                    Bestf=SMfunc_1(CM,CH,node);%记录最佳适应度值
                    CH_candidate=node_HE;%候选簇头成员集合(这里指高能量节点中的簇成员)
                    if isempty(CH_candidate)==1%如果候选簇头数为0,择直接确定簇头
                    else
                        %%%%%%%%%%每迭代一次退火一次(降温),知道满足迭代条件%%%%%%%
                        while k<=Niter
                            %%%%%%%%%%%%%%%%对节点随机扰动%%%%%%%%%%%%%%
                            CH_candidate=node_HE;%候选簇头成员集合(这里指高能量节点中的簇成员)
                            NextCH=SMfunc2(CH,CH_candidate,node,bounder,node_HE);%随机扰动生成新簇
                            %%%%%%%%%%%%%%%%是否全局最优解%%%%%%%%%%%%%%
                            CM=AliveNodes(~ismember(AliveNodes,CH));%簇成员集合
                            NextCM=AliveNodes(~ismember(AliveNodes,NextCH));%新簇成员集合
                            f=SMfunc_1(CM,CH,node);%记录原簇头集合适应度值
                            Nextf=SMfunc_1(NextCM,NextCH,node);%记录新簇头集合适应度值
                            if (Bestf>Nextf)
                                %%%%%%%%%%%%%%%%此为新的最优解%%%%%%%%%%%%%%
                                BestCH=NextCH;
                                Bestf=Nextf;
                                trace(k)=Bestf;
                                k=k+1;
                                continue;%直接进入下个循环
                            end
                            %%%%%%%%%%%%%%%%Metripolos过程%%%%%%%%%%%%%%
                            if (f>Nextf)
                                %%%%%%%%%%%%%%%%接收新解%%%%%%%%%%%%%%
                                CH=NextCH;
                                
                            else
                                a_k=1000*exp(-k/20);
                                changer=-1*(Nextf-f)/(a_k);
                                p1=exp(changer);
                                %%%%%%%%%%%%%%%%接收较差的解%%%%%%%%%%%%%%
                                if p1>rand
                                    CH=NextCH;
                                end
                            end
                            trace(k)=Bestf;
                            k=k+1;
                        end
                    end
                    %%%%%%%%%迭代适应度变化图%%%%%%%%%
                    %                 figure(1)
                    %                 plot(trace)
                    CH=BestCH;%记录簇头
                    count_CH=length(CH);%记录簇头个数
                end
            end
            
            
            %%%%%%%%%画图(簇头与簇成员节点连线)%%%%%%%%%
            CH=BestCH;CM=AliveNodes(~ismember(AliveNodes,CH));%簇成员集合
            figure(2)
            for i=1:length(CM)
                d_min=inf;
                for j=1:length(CH)
                    d=sqrt((node(CM(i)).location(1)-node(CH(j)).location(1))^2+((node(CM(i)).location(2)-node(CH(j)).location(2)))^2);
                    if d<d_min
                        d_min=d;
                        node(CM(i)).CH=CH(j);
                    end
                end
                plot([node(CM(i)).location(1),node(node(CM(i)).CH).location(1)],[node(CM(i)).location(2),node(node(CM(i)).CH).location(2)],'b');hold on
            end
            hold off;
            
            %%%%基站广播簇头表给节点(包含能量消耗)%%%%
            for i=1:length(AliveNodes)
                node(AliveNodes(i)).energy=node(AliveNodes(i)).energy-Lc*Eelec;
                contorl_Overhead=contorl_Overhead+Lc*Eelec;%控制开销
            end
            
            %%%%簇头广播信息消耗能量(包含能量消耗)%%%%
            for i=1:count_CH
                d=AD_Range;
                if d>d0
                    node(CH(i)).energy=node(CH(i)).energy-Lc*(Eelec+Emp*d^4);
                    contorl_Overhead=contorl_Overhead+Lc*(Eelec+Emp*d^4);%控制开销
                else
                    node(CH(i)).energy=node(CH(i)).energy-Lc*(Eelec+Efs*d^2);
                    contorl_Overhead=contorl_Overhead+Lc*(Eelec+Efs*d^2);%控制开销
                end
            end
            
            %%%%节点根据距离选择簇头加入(包含能量消耗)%%%%
            for i=1:length(AliveNodes)
                d_min=inf;%判断加入的条件
                F=find(CH==AliveNodes(i));
                if length(F)==0%如果节点不是是簇头
                    for j=1:count_CH
                        d=sqrt((node(AliveNodes(i)).location(1)-node(CH(j)).location(1))^2+(node(AliveNodes(i)).location(2)-node(CH(j)).location(2))^2);
                        if d<=AD_Range %如果节点在簇头广播范围内
                            node(AliveNodes(i)).energy=node(AliveNodes(i)).energy-Lc*Eelec;%节点接收信息的能耗
                            contorl_Overhead=contorl_Overhead+Lc*Eelec;%控制开销
                            if d<d_min %判断簇头和节点距离是否最近
                                d_min=d;
                                node(AliveNodes(i)).CH=CH(j);%为节点选择簇头
                            end
                        end
                    end
                    if  node(AliveNodes(i)).CH~=0 %如果节点拥有簇头
                        node(node(AliveNodes(i)).CH).CM=[node(node(AliveNodes(i)).CH).CM  AliveNodes(i)];% 将节点添加到簇头当中
                        node(node(AliveNodes(i)).CH).CM_count=node(node(AliveNodes(i)).CH).CM_count+1;% 对应簇头的簇成员数量+1
                        % 画图(簇头与簇成员节点连线) %
                        %                     plot([node(i).location(1),node(node(i).CH).location(1)],[node(i).location(2),node(node(i).CH).location(2)],'b');hold on
                    end
                end
            end
            
            %%%%节点返回注册信息(包含能量消耗) %%%%
            for i=1:length(AliveNodes)
                F=find(CH==AliveNodes(i));
                if length(F)==0 && node(AliveNodes(i)).CH~=0 %如果节点不是是簇头、拥有簇头
                    d=sqrt(((node(AliveNodes(i)).location(1)-node(node(AliveNodes(i)).CH).location(1)))^2+((node(AliveNodes(i)).location(2)-node(node(AliveNodes(i)).CH).location(2)))^2);
                    if d>d0
                        node(AliveNodes(i)).energy=node(AliveNodes(i)).energy-Lc*(Eelec+Emp*d^4);
                        contorl_Overhead=contorl_Overhead+Lc*(Eelec+Emp*d^4);%控制开销
                    else
                        node(AliveNodes(i)).energy=node(AliveNodes(i)).energy-Lc*(Eelec+Efs*d^2);
                        contorl_Overhead=contorl_Overhead+Lc*(Eelec+Efs*d^2);%控制开销
                    end
                end
            end
            
            %%%%簇头发送TDMA时间表(包含能量消耗)%%%%
            for i=1:count_CH%找到距离最远的节点,以此距离广播TDMA时间表
                d_Max=-inf;
                for j=1:node(CH(i)).CM_count%找到距离最远的节点
                    id=node(CH(i)).CM(j);
                    d=sqrt(((node(id).location(1)-node(CH(i)).location(1)))^2+((node(id).location(2)-node(CH(i)).location(2)))^2);
                    if d>d_Max
                        d_Max=d;
                    end
                end
                if node(CH(i)).CM_count>0%如果簇内只有簇头,则不广播
                    if d_Max>d0
                        node(CH(i)).energy=node(CH(i)).energy-Lc*(Eelec+Emp*d_Max^4);
                        contorl_Overhead=contorl_Overhead+Lc*(Eelec+Emp*d_Max^4);%控制开销
                    else
                        node(CH(i)).energy=node(CH(i)).energy-Lc*(Eelec+Efs*d_Max^2);
                        contorl_Overhead=contorl_Overhead+Lc*(Eelec+Efs*d_Max^2);%控制开销
                    end
                end
            end
            
            %%%%节点接收TDMA时间表(包含能量消耗)%%%%
            for i=1:length(AliveNodes)
                F=find(CH==AliveNodes(i));
                if length(F)==0  && node(AliveNodes(i)).CH~=0%如果节点不是簇头、能量大于0、拥有簇头
                    node(AliveNodes(i)).energy=node(AliveNodes(i)).energy-Lc*Eelec;
                    contorl_Overhead=contorl_Overhead+Lc*Eelec;%控制开销
                end
            end
            % 画图 %
            % for i=1:count_CH
            %     plot(node(CH(i)).location(1),node(CH(i)).location(2),'rx','linewidth',1);
            %     hold on;
            % end
        end
        
        %%%%%%%%%%%%%%%%%%%%%%% ②稳态数据传输阶段 %%%%%%%%%%%%%%%%%%%%%%%%%%%
        for z=1:1
            %%%%%%%%%%%% 数据传送(消耗能量) %%%%%%%%%%%%
            for i=1:count_CH
                for j=1:node(CH(i)).CM_count%簇内节点传送数据
                    %%%%%%%%%%%%对应节点发送数据消耗能量%%%%%%%%%%%%
                    id=node(CH(i)).CM(j);%节点序号
                    d=sqrt(((node(id).location(1)-node(CH(i)).location(1)))^2+((node(id).location(2)-node(CH(i)).location(2)))^2);
                    if d>d0
                        node(id).energy=node(id).energy-Ld*(Eelec+Emp*d^4);
                    else
                        node(id).energy=node(id).energy-Ld*(Eelec+Efs*d^2);
                    end
                    %%%%%%%%%%%%对应簇头接收数据能耗%%%%%%%%%%%%
                    node(CH(i)).energy=node(CH(i)).energy-Ld*Eelec;
                end
            end
            %%%%%%%%%%%%簇头将簇内数据融合并将数据送往基站(能量消耗)%%%%%%%%%%%%
            for i=1:count_CH
                node(CH(i)).energy=node(CH(i)).energy-node(CH(i)).CM_count*Ld*EDA;%数据融合
                d=sqrt((node(CH(i)).location(1)-sinkx)^2+((node(CH(i)).location(2)-sinky)^2));%将数据传送至基站
                if d>d0
                    node(CH(i)).energy=node(CH(i)).energy-Ld*(Eelec+Emp*d^4);
                else
                    node(CH(i)).energy=node(CH(i)).energy-Ld*(Eelec+Efs*d^2);
                end
            end
        end
        
        %%%%%%%%%%%%%%%%%%%%%%% ③更新参数 %%%%%%%%%%%%%%%%%%%%%%%
        for z=1:1
            %%%%%%%%%%%%更新节点参数%%%%%%%%%%%%
            for i=1:N
                node(i).CH=0;% 表明节点的簇头
                node(i).CM=[];% 表明节点的簇成员
                node(i).CM_count=0;% 表明簇内的簇成员节点数
            end
            
            %%%%%%%%%%%%更新性能指标参数%%%%%%%%%%%%
            r=r+1%轮数+1
            number_AliveNodes
            
            %%%吞吐量%%%
            Throughput=Throughput+count_CH*Ld;%吞吐量
            trace_Throughput(r)=Throughput;
            
            %%%网络生命周期%%%
            number_AliveNodes=N;
            AliveNodes=1:1:N;
            for i=1:N
                if node(i).energy<=0
                    number_AliveNodes=number_AliveNodes-1;%跟新节点数
                    AliveNodes=AliveNodes(~ismember(AliveNodes,i));%删除死亡节点
                end
            end
            network_Lifetime(r)=number_AliveNodes;%存活节点数量
            
            %%%网络剩余能量%%%
            E=0;
            for i=1:N
                if node(i).energy>0
                    E=E+node(i).energy;
                end
            end
            network_ResidualEnergy(r)=E;%网络剩余能量
            
            %%%网络时延%%%
            %             network_Delay(r)=delay;%网络时延
            
            %%%控制开销%%%
            network_Control_Overhead(r)=contorl_Overhead;%控制开销
            
            %%%簇头个数%%%
            network_CH_Count(r)=count_CH;%簇头个数
            
            %%%参数更新%%%
            %             delay=0;%网络时延初始化
            %             contorl_Overhead=0;%控制开销初始化
        end
    end
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 4.实验结果  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for zh=1:1
    figure(3)
    plot(network_Lifetime,'--k','linewidth',1.25) ;hold on
    figure(4)
    plot(network_ResidualEnergy,'--k','linewidth',1.25) ;hold on
    figure(5)
    plot(trace_Throughput,'--k','linewidth',1.25) ;hold on
    figure(6)
    plot(network_Control_Overhead,'--k','linewidth',1.25) ;hold on
end

SMfunc_1代码(适应度函数)

function result=SMfunc_1(CM,CH,node)

     %%%%%% 簇内距离因子 %%%%%% 
     f2=0;%簇内距离因子
     for i=1:length(CM)
         d_min=inf;
         for j=1:length(CH)
             d=sqrt((node(CM(i)).location(1)-node(CH(j)).location(1))^2+((node(CM(i)).location(2)-node(CH(j)).location(2)))^2);
             if d<d_min
                d_min=d; 
             end
         end
         f2=f2+d_min^2;%记录最佳适应度值
     end
    
     %%%%%% 适应度函数 %%%%%%
     F=f2;
     result=F;
     
end

SMfunc2代码(簇头随机扰动)

function result = SMfunc2(CH,CH_candidate,node,bounder,node_HE)
     for i=1:length(CH)%随机扰动
         Next_CH_location(i,1)=node(CH(i)).location(1)+(-bounder)+rand*(2*bounder);
         Next_CH_location(i,2)=node(CH(i)).location(2)+(-bounder)+rand*(2*bounder);
     end
     for i=1:length(CH)%选择近距离节点
         d_min=inf;
         for j=1:length(CH_candidate)
             d=sqrt((Next_CH_location(i,1)-node(CH_candidate(j)).location(1))^2+(Next_CH_location(i,2)-node(CH_candidate(j)).location(2))^2);
             if d_min>d
                d_min=d;
                NextCH(i)=CH_candidate(j);
             end
         end
     end
     if length(unique(NextCH))~=length(NextCH)%避免重复的簇头,若有重复簇头,则从高能量节点中随机挑选簇头补上
        UniqueCH=unique(NextCH);
        CH_candidate=node_HE(~ismember(node_HE,UniqueCH));
        count=(length(NextCH)-length(UniqueCH));
        RandSet=randperm(length(CH_candidate),count);
        UniqueCH=[UniqueCH CH_candidate(RandSet)];
        NextCH=UniqueCH;
     end
     result=NextCH;%输出结果
end
 

参数设置的参考文献为:


 [1] Heinzelman  WB.  Application-specific  protocol  architectures  for  wireless  networks[D]:  [Ph.D. dissertation]. Department of Electrical Engineering and Computer Science,Massachusetts Institute of  Technology, Cambridge, MA, USA, 2000. 

 [2] Zhang J, Yan R. Centralized Energy-Efficient Clustering Routing Protocol for Mobile Nodes in Wireless Sensor Networks[J]. IEEE Communications Letters, 2019, 23(7): 1215-1218.

有什么问题可以私聊我

qq:1514643733

邮箱:p1007zh@163.com


 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值