LEACH路由协议仿真(基于MATLAB)

一、实验仿真数据信息

在这里插入图片描述

说明:关于无线传感器路由协议,仿真数据均可以参考以上数据

二、传感器节点包含功能

在这里插入图片描述

说明:这里的节点相关是关乎编程的,路由包含簇头的产生、簇的形成和簇的路由,但是程序实现的时候不是这样分步去实现的,因为簇头的一部分功能是要在知道自己的簇成员之后才能实现的,这里的节点相关就是该功能要在知道自己的簇成员之后才能编写的功能。距离相关是说明只要发送就要判断与接收目标的距离d,d与d0的关系不同,能耗公式不同。

所以:编程时,簇头的产生包含的功能有:广播、基站

       簇的形成包含的功能有:除了广播、基站以外的功能

三、现实中的功能运作顺序图

在这里插入图片描述

说明:实验仿真并不是按照以上顺序实现的,也没必要。

四、算法说明

在这里插入图片描述

LEACH算法的精华就是这个公式,其中:p是簇头占所有节点的百分比,即节点当选簇头的概率;r是目前循环进行的轮数;G是最近1∕p轮中还未当选过簇头的节点集合.从T(n)我们可以看出,当选过簇头的节点在接下p来的1∕p轮循环中将不能成为簇头,剩节点当选簇头的阈值T(n)增大,节点产生小于T(n)的随机数的概率随之增大,所以节点当选簇头的概率增大。

注意:这个r必须是从0开始的,因为每个历元最后一轮的阈值T是等于1的,这时候必定所有节点都当选了一次簇头,随便举个例子,节点数n = 1000,簇头当选概率p = 0.05,每轮平均选np=50个簇头,进行1/p=20轮,r就是在0~19之间变化的,当r = 19时,会有T = 0.05/(1-0.05x(19mod20))=0.05/0.05=1。

五、仿真代码

%% 清空环境变量
clear;clc;
close all;
%% 1、初始参数设定模块
%现场尺寸-x和y最大值(单位:米)
xm = 100;
ym = 100;

%基站的坐标
sink.x = 0.5 * xm;
sink.y = 0.5 * ym;

%场地中的节点数
n = 100;

packetLength = 4000;%数据包长度 
ctrPacketLength = 100;%控制包长度

%能量模型(所有值均以焦耳为单位)
Eo = 0.5;%初始能量
ETX = 50*0.000000001;%耗传输能耗
ERX = 50*0.000000001;%接收能
EDA = 5*0.000000001;%数据聚合能量

%发射放大器类型
Efs = 10*0.000000000001;%小于do
Emp = 0.0013*0.000000000001;%大于do

do = sqrt(Efs/Emp);

%最大轮数
rmax = 2000;
p=0.1;%最佳簇头概率(根据最优簇头公式得来)

%% 2、无线传感器网络模型产生模块
figure;
%构建无线传感器网络,在区域内均匀投放100个节点,并画出图形
for i = 1:n
    S(i).xd = rand(1,1)*xm;%坐标
    S(i).yd = rand(1,1)*ym;
    S(i).G = 0;
    S(i).type = 'N';%普通节点 
    S(i).E = Eo;
    plot(S(i).xd,S(i).yd,'o');
    hold on;
end

S(n+1).xd = sink.x;
S(n+1).yd = sink.y;
plot(S(n+1).xd,S(n+1).yd,'p');
    
%% 3、网络运行模块

% 死亡节点数
dead = 0;
first_dead = 0;%第一个死亡节点
teenth_dead = 0;%10%的死亡节点
all_dead = 0;%节点都死亡
%标记
flag_first_dead = 0;
flag_teenth_dead = 0;
flag_all_dead = 0;

% 传输到基站和簇头的比特计数器
packets_TO_BS = 0;
packets_TO_CH = 0;
% 主循环 
for r = 0:rmax 
    %每过一轮周期,重置G
    if(mod(r, round(1/p) ) == 0)
        for i = 1:n
            S(i).G = 0;
        end
    end
    dead = 0;
    energy = 0;% 每轮节点剩余总能量
    for i = 1:n
        % 检查有无死亡节点
        if S(i).E <= 0
            dead = dead+1;
            % (3)第一个死亡节点的产生时间(用轮次表示)
            % 第一个节点死亡时间
            if dead == 1
                if flag_first_dead == 0
                    first_dead = r;
                    flag_first_dead = 1;
                end
            end
            % 10%的节点死亡时间
            if dead == 0.1*n
                if flag_teenth_dead ==0
                    teenth_dead = r;
                    flag_teenth_dead = 1;
                end
            end
            if dead == n
                if flag_all_dead == 0
                    all_dead = r;
                    flag_all_dead = 1;
                end
            end
        end
        if S(i).E > 0
            energy = energy + S(i).E;%统计每轮节点总能量和
            S(i).type = 'N';
        end
    end
%     if flag_all_dead == 1
%         break;
%     end
    STATISTICS.DEAD(r+1) = dead;
    STATISTICS.alive(r+1) = n-dead;
    STATISTICS.energy(r+1) = energy;
    cluster = 0;%计数簇头数
    %次循环(选簇头)
    if energy > 0%这个判断可以很大程度优化程序,当网络没有能量时,后面的都不用再运行了
        for i=1:n
            if(S(i).E>0)
                temp_rand=rand;     
                if ( (S(i).G)<=0) %如果该节点在候选集合中
                    %选簇头
                    if( temp_rand <= (p/(1-p*mod(r,round(1/p)))))
                        cluster = cluster+1;
                        S(i).type = 'C';
                        S(i).G = round(1/p)-1;
                        C(cluster).xd = S(i).xd;
                        C(cluster).yd = S(i).yd;
                        distance=sqrt( (S(i).xd-(S(n+1).xd) )^2 + (S(i).yd-(S(n+1).yd) )^2 );%到sink的距离
                        C(cluster).distance = distance;
                        C(cluster).id = i;
                        distanceBroad = sqrt(xm^2+ym^2);
                        %全网广播自成为簇头,距离是distanceBroad
                        if (distanceBroad > do)
                            S(i).E = S(i).E- ( ETX * ctrPacketLength + Emp* ctrPacketLength*distanceBroad^4);
                        else
                            S(i).E = S(i).E- ( ETX * ctrPacketLength + Efs * ctrPacketLength*distanceBroad^2); 
                        end
                        %簇头向基站发送数据包能耗
                        if (distance > do)
                            S(i).E = S(i).E- ( (ETX+EDA)*packetLength + Emp * packetLength*distance^4);
                        else
                            S(i).E = S(i).E- ( (ETX+EDA)*packetLength + Efs * packetLength*distance^2); 
                        end
                        packets_TO_BS = packets_TO_BS + 1;
                    end     
                end
            end
        end 
    end
    STATISTICS.COUNTCHS(r+1) = cluster;
    %次循环(成簇)
    if energy > 0
        for i = 1:n
            if ( S(i).type=='N' && S(i).E>0 ) %普通节点
                if(cluster>= 1)%如果有簇头存在
                    length = zeros(cluster,1);
                    %加入最近的簇头
                    for c = 1:cluster
                        length(c) = sqrt( (S(i).xd - C(c).xd)^2 + (S(i).yd - C(c).yd)^2 );
                        %接收簇头发来的广播的消耗
                        S(i).E = S(i).E - ERX * ctrPacketLength;
                    end
                    [min_dis, min_dis_cluster] = min(length);%min_dis返回最短距离,min_dis_cluster返回最短距离对应的簇号
                    %向簇头发送加入消息、向簇头发送数据包
                    if (min_dis > do)
                        S(i).E = S(i).E - ( ETX*ctrPacketLength + Emp * ctrPacketLength*min_dis^4); %向簇头发送加入控制消息
                        S(i).E = S(i).E - ( ETX*packetLength + Emp*packetLength*min_dis^4); %向簇发送头数据包
                    else
                        S(i).E = S(i).E - ( ETX*ctrPacketLength + Efs*ctrPacketLength*min_dis^2); %向簇头发送加入控制消息
                        S(i).E = S(i).E - ( ETX*packetLength + Efs*packetLength*min_dis^2); %向簇头发送数据包
                    end
                    %接收簇头确认加入控制消息
                    S(i).E = S(i).E - ERX*ctrPacketLength;
                    %簇头接收簇成员的加入消息和数据包,簇头向簇成员发送确认加入的信息
                    if(min_dis > 0)
                        S(C(min_dis_cluster).id).E = S(C(min_dis_cluster).id).E - ERX *ctrPacketLength ;%接收加入消息
                        S(C(min_dis_cluster).id).E = S(C(min_dis_cluster).id).E - ( (ERX + EDA)*packetLength ); %接受簇成员发来的数据包
                        %簇头向簇成员发送确认加入的信息
                        if (min_dis > do)
                            S(C(min_dis_cluster).id).E = S(C(min_dis_cluster).id).E - ( ETX*ctrPacketLength + Emp * ctrPacketLength*min_dis^4);
                        else
                            S(C(min_dis_cluster).id).E = S(C(min_dis_cluster).id).E - ( ETX*ctrPacketLength + Efs * ctrPacketLength*min_dis^2);
                        end
                    end
                    S(i).min_dis = min_dis;
                    S(i).min_dis_cluster = min_dis_cluster;
                    packets_TO_CH = packets_TO_CH + 1;
                else%如果本轮没有簇头,则普通节点直接将数据直接发送给基站
                    min_dis = sqrt((S(i).xd-S(n+1).xd)^2 + (S(i).yd-S(n+1).yd)^2);
                    if min_dis > do
                        S(i).E = S(i).E- (ETX*packetLength + Emp*packetLength*min_dis^4);
                    else
                        S(i).E = S(i).E- (ETX*packetLength + Efs*packetLength*min_dis^2);
                    end
                    packets_TO_BS = packets_TO_BS+1;
                end
            end
        end
    end
    STATISTICS.PACKETS_TO_CH(r+1) = packets_TO_CH;
    STATISTICS.PACKETS_TO_BS(r+1) = packets_TO_BS;
end


%% 绘图显示
figure;
plot(0:rmax, STATISTICS.DEAD, 'r', 'LineWidth', 2);
xlabel('轮数'); ylabel('死亡节点数');
figure;
plot(0:rmax, STATISTICS.alive, 'b', 'LineWidth', 2);
xlabel('轮数'); ylabel('活动节点数');
figure;
plot(0:rmax, STATISTICS.PACKETS_TO_BS, 'm', 'LineWidth', 2);
xlabel('轮数'); ylabel('基站收到数据包数');
figure;
plot(0:rmax, STATISTICS.COUNTCHS, 'g', 'LineWidth', 2);
xlabel('轮数'); ylabel('簇头数');
figure;
plot(0:rmax, STATISTICS.energy, 'k', 'LineWidth', 2);
xlabel('轮数'); ylabel('剩余能量');

六、运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考文献

[1]Heinzelman, W. R., Chandrakasan, A., & Balakrishnan, H. (n.d.). Energy-efficient communication protocol for wireless microsensor networks. Proceedings of the 33rd Annual Hawaii International Conference on System Sciences.

  • 9
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

御息无

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值