遗传算法改进leach协议(附MATLAB代码)

news2024/10/6 6:45:34

LEACH(低能量自适应聚簇层次)协议是无线传感器网络中最早的、最具有影响力的分簇协议之一。它通过随机选举一些传感器节点作为簇头,其他节点加入其中一个簇头组成一个簇,然后簇头负责汇聚数据并将数据发送给基站,从而达到减少能耗、提高网络寿命的目的。然而,LEACH协议的簇头选举过程随机性较强,可能导致簇头的能耗过快,进而影响网络性能。

为解决这个问题,可以采用遗传算法优化LEACH协议。遗传算法是一种模拟自然选择和遗传机制的全局搜索优化算法,具有优良的全局搜索能力和并行性。遗传算法可以用来优化簇头的选举和数据传输过程,以达到降低能耗、延长网络寿命的效果。

首先,构建初始种群,每个个体表示一种可能的簇头选举和数据传输方案。然后,对每个个体进行评价,得到适应度值,适应度函数可以设计为簇头的能耗和数据传输距离的函数。接着,根据适应度,采用遗传算子(选择、交叉、变异)产生新的种群。重复上述过程,种群将逐步向最优解区域进化。

通过遗传算法优化后的LEACH协议,可以有效地平衡簇头的能耗,保证簇内节点的能量消耗均衡,从而提高整个网络的能量效率,延长网络寿命。同时,遗传算法的并行性使得它可以在大规模网络中高效地寻找优化解,具有很高的实用价值和广阔的应用前景。

代码如下:

clear all;close all;clc;%清除内存变量
%% 遗传算法-多跳路由改进leach协议主程序


%% 输入参数列表
% BorderLength------------正方形区域的边长,单位:km
% NodeAmount--------------网络节点的个数
% Alpha-------------------网络特征参数,Alpha越大,短边相对长边的比例越大
% Beta--------------------网络特征参数,Beta越大,边的密度越大
% PlotIf------------------是否画网络拓扑图,如果为1则画图,否则不画图
% EdgeCostDUB-------------链路费用的控制参数,1×2,存储链路费用的下界和上界
% EdgeBandWideDUB---------链路带宽的控制参数,1×2,存储下界和上界
% VertexCostDUB-----------节点费用的控制参数,1×2,存储节点费用的下界和上界
% VertexDelayDUB----------节点时延的控制参数,1×2,存储节点时延的下界和上界
% VertexDelayJitterDUB----节点时延抖动的控制参数,1×2,存储节点时延抖动的下界和上界
% VertexPacketLossDUB-----节点丢包率的控制参数,1×2,存储节点丢包率的下界和上界
%% 输出参数列表
% Sxy---------------------3×N的矩阵,各列分别用于存储节点的序号,横坐标,纵坐标的矩阵
% AM----------------------01存储的邻接矩阵,AM(i,j)=1表示存在由i到j的有向边,N×N
% EdgeCost----------------链路费用矩阵,N×N
% EdgeDelay---------------链路时延矩阵,N×N
% EdgeBandWide------------链路带宽矩阵,N×N
% VertexCost--------------节点费用向量,1×N
% VertexDelay-------------节点时延向量,1×N
% VertexDelayJitter-------节点时延抖动向量,1×N
% VertexPacketLoss--------节点丢包率向量,1×N
% DisTabel----------------节点距离矩阵,N×N

BorderLength=1000;                   %正方形区域的边长,单位:km
NodeAmount=100;                       %网络节点的个数
Alpha=100000000;                     %网络特征参数,Alpha越大,短边相对长边的比例越大
Beta=200000000000;                   %网络特征参数,Beta越大,边的密度越大
PlotIf=0;                            %是否画网络拓扑图,如果为1则画图,否则不画图
EdgeCostDUB=[5,5];                   %链路费用的下界和上界
EdgeBandWideDUB=[30,1000];           %链路带宽的下界和上界
VertexCostDUB=[3,3];                 %节点费用的下界和上界
VertexDelayDUB=1e-4*[5,20];          %节点时延的下界和上界
VertexDelayJitterDUB=1e-4*[3,8];     %节点时延抖动的下界和上界
VertexPacketLossDUB=1e-4*[0,500];    %节点丢包率的下界和上界
% figure;
[Sxy,AM,EdgeCost,EdgeDelay,EdgeBandWide,VertexCost,VertexDelay,VertexDelayJitter,VertexPacketLoss,DisTabel]=...
    NetCreateNew2(BorderLength,NodeAmount,Alpha,Beta,PlotIf,EdgeCostDUB,EdgeBandWideDUB,VertexCostDUB,VertexDelayDUB,VertexDelayJitterDUB,VertexPacketLossDUB);
% title('网络拓扑(满足带宽)');
xm=BorderLength;%x轴范围
ym=BorderLength;%y轴范围

sink.x=0.5*xm;%基站x轴
sink.y=0.5*ym;%基站y轴

n=NodeAmount;%节点总数

p=0.1;%簇头概率

E0=0.02;%初始能量
ETX=50*0.000000000001;%传输能量,每bit
ERX=50*0.000000000001;%接收能量,每bit
Efs=10*0.000000000001;%耗散能量,每bit
EDA=5*0.000000000001;%融合能耗,每bit

cc=0.6;%融合率

rmax=8;%总轮数

CM=32;%控制信息大小
DM=4000;%数据信息大小

figure(1);%显示图片

%% 设置数据
for i=1:1:n
    S(i).xd=Sxy(2,i);
    S(i).yd=Sxy(3,i);
    S(i).G=0;%每一周期结束此变量为0
    S(i).E=E0;%设置初始能量为E0
    S(i).type='N';%节点类型为普通
    
    plot(S(i).xd,S(i).yd,'o');
    hold on;%保持所画的图像
end%为每个节点随机分配坐标,并设置初始能量为E0,节点类型为普通

S(n+1).xd=sink.x;
S(n+1).yd=sink.y;
plot(S(n+1).xd,S(n+1).yd,'x');%绘制基站节点


flag_first_dead=0;%第一个死亡节点的标志变量

for r=1:1:rmax%开始每轮循环
    
    if(mod(r,round(1/p))==0)
        for i=1:1:n
            S(i).G=0;
        end
    end%如何轮数正好是一个周期的整数倍,则设置S(i).G为0
    
    hold off;%每轮图片重新绘制
    cluster=0;%初始簇头数为0
    dead=0;%初始死亡节点数为0
    
    figure(1);
    
    for i=1:1:n
        if(S(i).E<=0)
            plot(S(i).xd,S(i).yd,'red .');
            dead=dead+1;%将能量小于等于0的节点绘制成红色,并将死亡节点数增加1
            
            if(dead==1)
                if(flag_first_dead==0)
                    first_dead=r; %第一个节点的死亡轮数
                    save ltest, first_dead;
                    flag_first_dead=1;
                end
            end%将能量小于等于0的节点绘制成红色,并将死亡节点数增加1
            
            hold on;
        else
            S(i).type='N';
            plot(S(i).xd,S(i).yd,'o');%绘制其他节点
            hold on;
        end
        
        
    end
    
    plot(S(n+1).xd,S(n+1).yd,'x');%绘制基站
    
    Dead(r+1)=dead; %每轮有死亡节点数
    save ltest, Dead(r+1);%将此数据存入ltest文件
    %% ---------------------选举簇头部分开始---------------
    %不考虑簇头处理能力
    %(1)计算簇头数cluster
    nodeSET=[];
    for i=1:1:n%对每个节点循环
        if(S(i).E>0)%判断节点能量
            nodeSET=[nodeSET i];%加入可用节点集
            if(S(i).G<=0)
                temp_rand=rand;%取一个随机数
                if(temp_rand<=(p/(1-p*mod(r,round(1/p)))))%如果随机数小于等于
                    cluster=cluster+1;%簇头数加1
                end
            end
        end
    end%for i=1:1:n
    %% 遗传算法
    % (2)先找可用于选举的节点
    popsize=20; %个体数目
    MAXGEN=10;%最大遗传代数
    GGAP=1;%代沟
    crossp=0.9;%交叉率
    mutionp=0.9;%变异率
    trace1=[];
    Chrom=genchrom01(nodeSET,cluster,popsize);%产生初始种群
    gen=0;
    bestchrom=cell(MAXGEN,1);
    while gen<=MAXGEN
        Value=DecodeLeachChrom(Chrom,S,nodeSET,cluster); %计算目标函数值
        FitnV1=ranking(Value);%分配适应度值
        Chrom=select('sus',Chrom,FitnV1,GGAP);%选择
        Chrom=mutationLeach(Chrom,cluster,mutionp);%变异
        Chrom=crossLeach(Chrom,crossp);%交叉
        Value=DecodeLeachChrom(Chrom,S,nodeSET,cluster); %计算目标函数值
        gen=gen+1;
        [trace1(gen,1),index1]=min(Value);%记录最小值
        bestchrom{gen,1}=Chrom(index1,:);
        trace1(gen,2)=sum(Value)/popsize;%记录均值
    end
    temp01=bestchrom{gen,1};%最佳分簇方案
    cluster_set=cell(cluster,1);
    cluster_node=zeros(cluster,1);
    packet_To_BS=zeros(cluster,1);
    for k0001=1:cluster
        [v01,index2]=find(temp01==k0001);
        cluster_set{k0001,1}=nodeSET(index2);%分簇
        %% ------------簇头选举开始:不考虑周期----------------------
        temp02=cluster_set{k0001,1};
        if ~isempty(temp02)
            % 计算簇平均能量
            E01=zeros(1,length(temp02));
            for k0002=1:length(temp02)
                E01(1,k0002)=S(temp02(k0002)).E;
            end
            distance01=calfitnessfun2(temp02,S);%到基站距离
            %最终目标
            OE1=1./E01.^2;
            %             fitness01=distance01.*OE1;
            fitness01=distance01;
            [v03,index3]=min(fitness01);
            selectnode=temp02(index3);
            cluster_node(k0001,1)=selectnode;
            S(selectnode).type='C';%此节点为此轮簇头
            S(selectnode).G=round(1/p)-1;%S(i).G设置为大于0,此周期不能再被选择为簇头
            C(k0001).xd=S(selectnode).xd;
            C(k0001).yd=S(selectnode).yd;%将此节点标志为簇头
            plot(S(selectnode).xd,S(selectnode).yd,'k*');%绘制此簇头
            distance=sqrt((S(selectnode).xd-(S(n+1).xd))^2+(S(selectnode).yd-(S(n+1).yd))^2);%簇头到基站的距离
            C(k0001).distance=distance;%标志为此簇头的距离
            C(k0001).id=selectnode; %此簇头的节点id
            packet_To_BS(k0001)=1;%发送到基站的数据包数为1
        end
        %% ------------簇选举结束----------------------
    end%for k0001=1:cluster
    %% ---------------------选举簇头部分结束---------------
    Delay01=0;%时延
    DelayJitter01=0;%时延抖动
    PacketLoss01=0;%丢包率
    for c=1:1:cluster%各个簇头
        cluster_set001=cluster_set{c,1};%节点集
        [Ttable02,AM1]=topo_table23(AM,cluster_set001);
        if ~isempty(cluster_set001)
            number_dem=C(c).id;%得到簇头作为源节点
            E=cluster_set001(cluster_set001~=number_dem);%目的节点
            ChromRoute=zeros(length(E),length(cluster_set001));%路径记录
            for w01=1:length(E)
                number_source=E(w01);
                %计算距离
                distance_s2d=DisTabel(number_source,number_dem);%距离初始化
                route=[number_source];%路径初始化
                Ttable01=Ttable02;%临时拓扑赋值,防止搞坏原始拓扑集
                %% GPRS主函数
                state001=0;
                while distance_s2d~=0
                    %% 判断死链
                    if isempty(route)
                        disp('无法产生路由路径');
                        break;
                    end
                    curr_node=route(end);%路径当前最后一个节点
                    curr_topolopy=Ttable01(curr_node).topolopy;%获取当前拓扑相邻集合
                    %% -------------判断终止开始---------------
                    if ~isempty(curr_topolopy)%拓扑相邻集合非空就找下
                        curr_distance1=DisTabel(curr_topolopy,number_dem);%获取当前拓扑相邻集合与目的地节点距离集合
                        distance01=DisTabel(number_dem,curr_node);%当前节点和目的节点距离
                        setindex01=curr_topolopy(curr_distance1<distance01);%比当前节点更靠近目的的邻近节点集
                        if isempty(setindex01)%就当前节点最近,那么直接结束
                            route=[route number_dem];
                            break;
                        else%如果不是空的,要继续判断
                            curr_distance3=DisTabel(setindex01,curr_node);%获取当前拓扑相邻集合与邻近节点距离集合
                            setindex02=setindex01(curr_distance3<distance01);
                            if isempty(setindex02)%即使距离目的近,但两者距离远过distance01,那么直接结束
                                route=[route number_dem];
                                break;
                            else%
                                
                            end
                        end
                    end
                    %% -------------判断终止结束---------------
                    %% ------------------删除curr_topolopy中属于route的节点开始-----
                    n001=length(route);%计算route长度
                    for k=1:n001
                        v01=find(curr_topolopy==route(k));%route(k)是不是curr_topolopy的成员
                        if numel(v01)>0%是成员
                            curr_topolopy(v01)=[];%删除该元素
                        end
                    end
                    %% ------------------删除curr_topolopy中属于route的节点结束-----
                    if ~isempty(curr_topolopy)%拓扑相邻集合非空就找下
                        curr_distance1=DisTabel(curr_topolopy,number_dem);%获取当前拓扑相邻集合与目的地节点距离集合
                        distance01=DisTabel(number_dem,curr_node);%当前节点和目的节点距离
                        setindex01=curr_topolopy(curr_distance1<distance01);%比当前节点更靠近目的的邻近节点集
                        if isempty(setindex01)%就当前节点最近,那么直接结束
                            route=[route number_dem];
                            break;
                        else%如果不是空的,要继续判断
                            curr_distance3=DisTabel(setindex01,curr_node);%获取当前拓扑相邻集合与邻近节点距离集合
                            setindex02=setindex01(curr_distance3<distance01);
                            if isempty(setindex02)%即使距离目的近,但两者距离远过distance01,那么直接结束
                                route=[route number_dem];
                                break;
                            else%
                                [vt01,index01]=min(curr_distance3(curr_distance3<distance01));
                                route=[route setindex02(index01)];
                            end
                        end
                    end%if ~isempty(curr_topolopy)%拓扑相邻集合非空就找下
                end%while distance_s2d~=0
                ChromRoute(w01,1:length(route))=route;%输出路径
            end%for w01=1:length(E)
            % 画簇路由树
            drawgoodroute23(Sxy,ChromRoute);
            
        end%if ~isempty(cluster_set001)
        %         ChromRoute=zeros(length(E),length(cluster_set001));%路径记录
        cset01=[];
        als01=zeros(1,length(E));
        for w009=1:length(E)
            temp009=ChromRoute(w009,:);
            temp009=temp009(temp009>0);
            cset01=[cset01 temp009(end-1)];
            als01(1,w009)=length(temp009);
        end
        [v02,index02]=sort(als01);
        index02=fliplr(index02);
        index03=index02(1:length(unique(cset01)));%前几个最长的
        for w009=1:length(index03)
            routenew01=ChromRoute(index03(w009),:);
            routenew01=routenew01(routenew01>0);
            Delay01=Delay01+sum(VertexDelay(routenew01));%节点时延
            DelayJitter01=DelayJitter01+sum(VertexDelayJitter(routenew01));%节点时延抖动
            PacketLoss01=PacketLoss01+sum(VertexPacketLoss(routenew01));%丢包率
            for w010=1:length(routenew01)-1
                %                 EdgeDelay,EdgeBandWide,VertexCost,VertexDelay,VertexDelayJitter,VertexPacketLoss
                Delay01=Delay01+EdgeDelay(routenew01(w010),routenew01(w010+1));%路径时延
                min_dis=norm([S(routenew01(w010)).xd,S(routenew01(w010)).yd]-[S(routenew01(w010+1)).xd,S(routenew01(w010+1)).yd]);
                Er1=ERX*CM*(0+1);%此节点接收各个簇头的控制信息
                %此节点加入的簇的簇头时隙控制信息的总接收能耗
                Et1=ETX*(CM+DM)+Efs*(CM+DM)*min_dis*min_dis;%此节点发送加入信息和发送数据信息
                %到簇头的能耗
                S(routenew01(w010)).E=S(routenew01(w010)).E-Er1-Et1;%此轮后的剩余能量
            end
        end
        
        
        
        packet_To_BS(c)=length(unique(cset01));%簇头需发送到基站的数据包个数
        if  packet_To_BS(c)~=0
            CEr1=ERX*CM*(packet_To_BS(c)-1);%收到此簇各个节点加入信息的能耗
            CEr2=ERX*DM*(packet_To_BS(c)-1);%收到此簇各个节点数据信息的能耗
            CEt1=ETX*CM+Efs*CM*(sqrt(xm*ym))*(sqrt(xm*ym));%此簇头广播成簇信息的能耗
            CEt2=(ETX+EDA)*DM*cc*packet_To_BS(c)+Efs*DM*cc*packet_To_BS(c)*C(c).distance*C(c).distance;%簇头将所以数据融合后发往基站的能耗
            S(C(c).id).E=S(C(c).id).E-CEr1-CEr2-CEt1-CEt2;%此轮后簇头的剩余能量
        end
        
    end
    CH_Num(r+1)=cluster; %每轮的簇头数
    save ltest,CH_Num(r+1);%保存每轮簇头数到ltest
    %保存数据
    Delay02(r)=Delay01;%第r轮节点时延
    DelayJitter02(r)=DelayJitter01;%第r轮时延抖动
    PacketLoss02(r)=PacketLoss01;%第r轮丢包率
    
    count002=0;
    for i=1:1:n
        R(r+1,i)=S(i).E;  %每轮每节点的剩余能量
        if S(i).E<=0
            count002=count002+1;
        end
    end
    if count002==n
        break;
    end
    hold on;
    
end
title('遗传算法-多跳路由改进leach协议变化');
figure;
plot(Dead);
title('遗传算法-多跳路由改进leach协议死亡节点数');
figure;
plot(Delay02);
title('遗传算法-多跳路由改进leach协议每轮总时延');
figure;
plot(DelayJitter02);
title('遗传算法-多跳路由改进leach协议每轮总时延抖动');
figure;
plot(PacketLoss02);
title('遗传算法-多跳路由改进leach协议每轮总丢包率');

clear all;

BorderLength=1000;                   %正方形区域的边长,单位:km
NodeAmount=100;                       %网络节点的个数
Alpha=100000000;                     %网络特征参数,Alpha越大,短边相对长边的比例越大
Beta=200000000000;                   %网络特征参数,Beta越大,边的密度越大
PlotIf=0;                            %是否画网络拓扑图,如果为1则画图,否则不画图
EdgeCostDUB=[5,5];                   %链路费用的下界和上界
EdgeBandWideDUB=[30,1000];           %链路带宽的下界和上界
VertexCostDUB=[3,3];                 %节点费用的下界和上界
VertexDelayDUB=1e-4*[5,20];          %节点时延的下界和上界
VertexDelayJitterDUB=1e-4*[3,8];     %节点时延抖动的下界和上界
VertexPacketLossDUB=1e-4*[0,500];    %节点丢包率的下界和上界

[Sxy,AM,EdgeCost,EdgeDelay,EdgeBandWide,VertexCost,VertexDelay,VertexDelayJitter,VertexPacketLoss]=...
    NetCreateNew2(BorderLength,NodeAmount,Alpha,Beta,PlotIf,EdgeCostDUB,EdgeBandWideDUB,VertexCostDUB,VertexDelayDUB,VertexDelayJitterDUB,VertexPacketLossDUB);


xm=BorderLength;%x轴范围
ym=BorderLength;%y轴范围

sink.x=0.5*xm;%基站x轴
sink.y=0.5*ym;%基站y轴

n=NodeAmount;%节点总数

p=0.1;%簇头概率

E0=0.02;%初始能量
ETX=50*0.000000000001;%传输能量,每bit
ERX=50*0.000000000001;%接收能量,每bit
Efs=10*0.000000000001;%耗散能量,每bit
EDA=5*0.000000000001;%融合能耗,每bit

cc=0.6;%融合率

rmax=8;%总轮数

CM=32;%控制信息大小
DM=4000;%数据信息大小

figure(1);%显示图片

%% 设置数据
for i=1:1:n
    S(i).xd=Sxy(2,i);
    S(i).yd=Sxy(3,i);
    S(i).G=0;%每一周期结束此变量为0
    S(i).E=E0;%设置初始能量为E0
    S(i).type='N';%节点类型为普通
    
    plot(S(i).xd,S(i).yd,'o');
    hold on;%保持所画的图像
end%为每个节点随机分配坐标,并设置初始能量为E0,节点类型为普通

S(n+1).xd=sink.x;
S(n+1).yd=sink.y;
plot(S(n+1).xd,S(n+1).yd,'x');%绘制基站节点

flag_first_dead=0;%第一个死亡节点的标志变量

for r=1:1:rmax%开始每轮循环
    r+1;%显示轮数
    if(mod(r,round(1/p))==0)
        for i=1:1:n
            S(i).G=0;
        end
    end%如何轮数正好是一个周期的整数倍,则设置S(i).G为0
    
    hold off;%每轮图片重新绘制
    cluster=0;%初始簇头数为0
    dead=0;%初始死亡节点数为0
    
    figure(1);
    
    for i=1:1:n
        if(S(i).E<=0)
            plot(S(i).xd,S(i).yd,'red .');
            dead=dead+1;%将能量小于等于0的节点绘制成红色,并将死亡节点数增加1
            
            if(dead==1)
                if(flag_first_dead==0)
                    first_dead=r %第一个节点的死亡轮数
                    save ltest, first_dead;
                    flag_first_dead=1;
                end
            end%将能量小于等于0的节点绘制成红色,并将死亡节点数增加1
            
            hold on;
        else
            S(i).type='N';
            plot(S(i).xd,S(i).yd,'o');%绘制其他节点
            hold on;
        end
        
        
    end
    
    plot(S(n+1).xd,S(n+1).yd,'x');%绘制基站
    
    Dead(r+1)=dead; %每轮有死亡节点数
    save ltest, Dead(r+1);%将此数据存入ltest文件
    
    for i=1:1:n
        if(S(i).E>0)
            if(S(i).G<=0)
                temp_rand=rand;%取一个随机数
                if(temp_rand<=(p/(1-p*mod(r,round(1/p)))))%如果随机数小于等于
                    S(i).type='C';%此节点为此轮簇头
                    S(i).G=round(1/p)-1;%S(i).G设置为大于0,此周期不能再被选择为簇头
                    cluster=cluster+1;%簇头数加1
                    C(cluster).xd=S(i).xd;
                    C(cluster).yd=S(i).yd;%将此节点标志为簇头
                    plot(S(i).xd,S(i).yd,'k*');%绘制此簇头
                    
                    distance=sqrt((S(i).xd-(S(n+1).xd))^2+(S(i).yd-(S(n+1).yd))^2);%簇头到基站的距离
                    C(cluster).distance=distance;%标志为此簇头的距离
                    C(cluster).id=i; %此簇头的节点id
                    
                    packet_To_BS(cluster)=1;%发送到基站的数据包数为1
                end
            end
        end
    end
    
    CH_Num(r+1)=cluster; %每轮的簇头数
    save ltest,CH_Num(r+1);%保存每轮簇头数到ltest
    
    Delay01=0;%时延
    DelayJitter01=0;%时延抖动
    PacketLoss01=0;%丢包率
    for i=1:1:n
        if(S(i).type=='N'&&S(i).E>0)%对每个能量大于0且非簇头节点
            min_dis=sqrt((S(i).xd-(C(1).xd))^2+(S(i).yd-(C(1).yd))^2);%计算此节点到簇头1的距离
            min_dis_cluster=1;
            for c=2:1:cluster
                temp=sqrt((S(i).xd-(C(c).xd))^2+(S(i).yd-(C(c).yd))^2);
                if(temp<min_dis)
                    min_dis=temp;
                    min_dis_cluster=c;
                end
            end%选择此几点到哪个簇头的距离最小
            packet_To_BS(min_dis_cluster)=packet_To_BS(min_dis_cluster)+1;%将此节点加入的簇
            %头节点数据包数加1
            %             EdgeDelay,EdgeBandWide,VertexCost,VertexDelay,VertexDelayJitter,VertexPacketLoss
            Delay01=Delay01+VertexDelay(i)+VertexDelay(C(min_dis_cluster).id)+EdgeDelay(i,C(min_dis_cluster).id);%时延
            DelayJitter01=DelayJitter01+VertexDelayJitter(i)+VertexDelayJitter(C(min_dis_cluster).id);%时延抖动
            PacketLoss01=PacketLoss01+VertexPacketLoss(i)+VertexPacketLoss(C(min_dis_cluster).id);%丢包率
            Er1=ERX*CM*(cluster+1);%此节点接收各个簇头的控制信息
            %此节点加入的簇的簇头时隙控制信息的总接收能耗
            Et1=ETX*(CM+DM)+Efs*(CM+DM)*min_dis*min_dis;%此节点发送加入信息和发送数据信息
            %到簇头的能耗
            S(i).E=S(i).E-Er1-Et1;%此轮后的剩余能量
        end
    end
    for c=1:1:cluster%各个簇头
        packet_To_BS(c);%簇头需发送到基站的数据包个数
        CEr1=ERX*CM*(packet_To_BS(c)-1);%收到此簇各个节点加入信息的能耗
        CEr2=ERX*DM*(packet_To_BS(c)-1);%收到此簇各个节点数据信息的能耗
        CEt1=ETX*CM+Efs*CM*(sqrt(xm*ym))*(sqrt(xm*ym));%此簇头广播成簇信息的能耗
        CEt2=(ETX+EDA)*DM*cc*packet_To_BS(c)+Efs*DM*cc*packet_To_BS(c)*C(c).distance*C(c).distance;%簇头将所以数据融合后发往基站的能耗
        S(C(c).id).E=S(C(c).id).E-CEr1-CEr2-CEt1-CEt2;%此轮后簇头的剩余能量
    end
    
    
    %保存数据
    Delay02(r)=Delay01;%第r轮节点时延
    DelayJitter02(r)=DelayJitter01;%第r轮时延抖动
    PacketLoss02(r)=PacketLoss01;%第r轮丢包率
    
    for i=1:1:n
        R(r+1,i)=S(i).E;  %每轮每节点的剩余能量
        % save ltest,R(r+1,i);%保存此数据到ltest
    end
    
    hold on;
    
end
title('基础leach协议');
figure;
plot(Dead);
title('基础leach协议死亡节点数');
figure;
plot(Delay02);
title('基础leach协议每轮总时延');
figure;
plot(DelayJitter02);
title('基础leach协议每轮总时延抖动');
figure;
plot(PacketLoss02);
title('基础leach协议每轮总丢包率');

程序结果如下:

完整代码见: https://download.csdn.net/download/corn1949/88792075

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1418477.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UE4运用C++和框架开发坦克大战教程笔记(十五)(第46~48集)

UE4运用C和框架开发坦克大战教程笔记&#xff08;十五&#xff09;&#xff08;第46~48集&#xff09; 46. 批量加载 UClass 功能测试批量加载多个同类 UClass 资源 47. 创建单个资源对象测试加载并创建单个 UClass 资源对象 48. 创建同类资源对象 46. 批量加载 UClass 功能 逻…

【HTML 基础】元素和标签

文章目录 1. <p> - 段落标签2. <h1> - <h6> - 标题标签3. <a> - 超链接标签4. <img> - 图片标签5. <ul>, <ol>, <li> - 列表标签无序列表有序列表 总结 HTML&#xff08;Hypertext Markup Language&#xff09;是构建 Web 页面…

Prometheus 监控系统的初步了解与系统搭建

目录 目录 目录 前言 Prometheus的相关知识 Prometheus特点 Prometheus的存储引擎&#xff1a;TSDB Prometheus的组件 1.核心组件&#xff1a;prometheus server Prometheus server又分为三个部分&#xff1a; 2.exports 3.client Library 4.cadvisor 5.blackbox-ex…

二维数组的学习

前言 在前面我们学习了一维数组&#xff0c;但是有的问题需要用二位数组来解决。 二维数组常称为矩阵&#xff0c;把二维数组写成行和列的排列形式&#xff0c;可以有助于形象化的理解二维数组的逻辑结构。 一、二维数组的定义 二维数组定义的一般格式&#xff1a; 数据类型 数…

【前端web入门第二天】03 表单-下拉菜单 文本域 label标签 按钮 【附注册信息综合案例】

文章目录: 1. 下拉菜单 2. 文本域3.label标签 4.按钮- button 4.1 reset重置按钮结合form表单区域使用 5.无语义的布局标签 6.字符实体 注册信息综合案例 表单第二节 1. 下拉菜单 标签: select嵌套option,select是下拉菜单整体&#xff0c;option是下拉菜单的每一项。 代码…

自媒体必备,这10个免费素材网站,一定要收藏~

自媒体必备素材库&#xff0c;视频、图片、音效、各种类型BGM&#xff0c;这10个网站都能找到&#xff0c;免费下载可商用&#xff0c;朋友们赶紧收藏一波~ 视频素材 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库虽然是个设计素材网站&#xff0c;但…

文物预防性保护新高度:守护历史,个性化定制保护方案

一、西安市研究院宣布西安长安曹家堡村发现2823座古代遗迹 深藏于西安长安曹家堡村地下的2823座古代遗迹&#xff0c;在西安文物维护考古研究院的用心调研下&#xff0c;逐渐揭开了神秘面纱。其中&#xff0c;已有1088座陵墓重见天日&#xff0c;出土的文物琳琅满目&#xff0…

如何实现Win系统ssh连接Ubuntu使用vscode远程敲代码

最近&#xff0c;我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念&#xff0c;而且内容风趣幽默。我觉得它对大家可能会有所帮助&#xff0c;所以我在此分享。点击这里跳转到网站。 文章目录 前言1、安装OpenSSH2、vscode配置ssh3. 局域网测试连接…

【.NET Core】深入理解C#中的特殊字符

【.NET Core】深入理解C#中的特殊字符 文章目录 【.NET Core】深入理解C#中的特殊字符一、概述二、$-- 字符串内插2.1 内插字符串的结构2.2 内插原始字符串字面量2.3 特殊字符2.4 内插字符串编译 三、-- 逐字字符串标识符四、“”“--原始字符串文本 一、概述 特殊字符是预定义…

Vite+Electron快速构建一个VUE3桌面应用(一)

一. 简介 首先&#xff0c;介绍下vite和Electron。 Vite是一种新型前端构建工具&#xff0c;能够显著提升前端开发体验。Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入Chromium和Node.js到二进制的 Electron 允许您保持一个 JavaScript 代码代码…

elementui-table组件列表中的tooltip内容过长超出屏幕换行显示

elementui-table组件列表中的tooltip内容过长超出屏幕换行显示 el-table列属性中带的有show-overflow-tooltip&#xff0c;可以设置内容超出列宽度显示为…&#xff0c;并且有tooltip提示&#xff0c;但是内容过多时&#xff0c;提示会超出屏幕&#xff1a; 但是el-table组件…

cad设计绘图 -- AutoCAD 2024 中文

AutoCAD 2024是一款全球领先的CAD软件&#xff0c;广泛应用于建筑、机械、电子等领域。相比其他CAD软件&#xff0c;它具有以下优势&#xff1a;首先&#xff0c;AutoCAD 2024提供了丰富的绘图和设计工具&#xff0c;满足各种工作需求&#xff1b;其次&#xff0c;其界面直观、…

数据结构.队列的顺序表示

一、队列的定义 二、队列的顺序实现 #include<iostream> using namespace std; const int N 10; typedef struct {int data[N];int front,rear; }SqQueue;void Init(SqQueue& Q)//初始化 {Q.front Q.rear0;} 三、入队 bool Push(SqQueue& Q, int x)//入队 {if …

ThinkPhp3.2(qidian)部署文档

宝塔环境部署 申请域名以及域名解析 具体配置&#xff0c;可百度之 在宝塔面板中创建网站 上传代码导入数据配置运行目录 注意&#xff1a;&#xff08;如果版本&#xff1a;thinkphp3.2 &#xff09;配置 运行目录要特别注意&#xff1a;运行目录要选择根目录“/”&#xff…

Java基础数据结构之反射

一.定义 Java的反射机制是在运行状态中的&#xff0c;对于任意一个类都能知道这个类的所有属性和方法&#xff1b;对于任意一个对象&#xff0c;都能够调用它的任意方法及属性。既然能拿到&#xff0c;我们就可以修改部分类型信息。这种动态获取信息以及动态调用对象方法的功能…

什么是正向代理?为什么要使用它?

在计算机网络中&#xff0c;代理服务器&#xff08;Proxy Server&#xff09;是一种充当客户端和目标服务器之间的中间人的计算机或应用程序。代理服务器可以用于多种目的&#xff0c;其中之一就是正向代理。 正向代理的定义 正向代理是一种代理服务器配置方式&#xff0c;它…

【网络】:网络基础

网络基础 一.总体概述二.认识Mac地址三.数据跨网络传输 一.总体概述 1.协议是什么 1.从概念上说&#xff1a;为了保证不同厂家生产出来的不同型号的电脑能够互相通信&#xff0c;而制定的标准——协议。 2.从技术上说&#xff1a;简单粗暴的理解——是操作系统里的结构体。 2.…

Flink的SQL开发

概叙 Flink有关FlinkSQL的官网: https://nightlies.apache.org/flink/flink-docs-release-1.13/zh/docs/dev/table/sql/overview/ 阿里云有关FlinkSQL的官网: https://help.aliyun.com/zh/flink/developer-reference/overview-5?spma2c4g.11186623.0.0.3f55bbc6H3LVyo Ta…

Windows系统本地安装Everything搜索神器并结合内网穿透实现远程访问

文章目录 前言1.软件安装完成后&#xff0c;打开Everything2.登录cpolar官网 设置空白数据隧道3.将空白数据隧道与本地Everything软件结合起来总结 前言 要搭建一个在线资料库&#xff0c;我们需要两个软件的支持&#xff0c;分别是cpolar&#xff08;用于搭建内网穿透数据隧道…

金融OCR领域实习日志(一)——OCR技术从0到1全面调研

一、OCR基础 任务要求&#xff1a; 工作原理 OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;是指电子设备&#xff08;例如扫描仪或数码相&#xff09;检查纸上打印的字符&#xff0c;经过检测暗、亮的模式肯定其形状&#xff0c;而后用…