Leach代码分析报告Word文档格式.docx
《Leach代码分析报告Word文档格式.docx》由会员分享,可在线阅读,更多相关《Leach代码分析报告Word文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
初始阶段,每个节点从0和1中随机产生一个数,如果这个数小于阀值T(n),该节点就成为当前轮的簇头。
其中,P是期望的簇头数在所有节点中占的百分比,r是选举轮数,rmod(1/p)代表这一轮循环中当选过簇头的节点个数,G是这一轮循环中未当选过簇头的节点集合。
每个节点自主选择是否成为当前轮的簇头并通过广播的形式报告给其他节点。
簇头通过CSMAMAC协议进行广播,所有的簇头以相同的传输能量进行广播。
簇头建立起来之后,每个非簇头节点要决定在当前轮中自己属于哪个簇头。
非簇头节点根据收到的广播信号强度决定加入哪个簇头。
非簇头节点决定了自己属于哪个簇头后,必须通知簇头节点它是该簇的成员。
非簇头节点同样通过CSMAMAC协议将自己加入该簇的信息报告给簇头节点。
簇头节点收到所有的非簇头节点加入的信息后,基于本簇加入的节点数目创建TDMA调度,通知每个节点什么时间可以传输数据。
在leach协议中,具体通过calculatePi()函数计算门限值thresh.
doubleLeachApp:
:
calculatePi()
{
registerintn=config_.numberNodes_;
//节点个数
registerintk=config_.desiredClusters_;
//期望簇头数
doublethresh;
//阀值
if(hasBeenClusterHead())
thresh=0;
//已经是簇头,本轮中不再成为簇头
elseif(n-k*round_<
1)
thresh=1;
//将节点设置为簇头
else
thresh=(double)k/(n-k*round_);
returnthresh;
}
(2)数据传输阶段:
一个簇的信息传输会影响相邻簇。
为了减少这种信号干扰,各个簇的信息交互通过不同的CDMA编码。
簇头可以决定本簇中节点所用的CDMA编码。
这个用于当前阶段的CDMA编码在广播簇头的时候发送给簇节点。
具体在advertiseClusterHead()中实现。
此外,簇头根据本簇的节点个数创建TDMA调度。
具体的,簇头在findBestCluster()函数中调用createSchedule(),而由createSchedule()函数具体创建TDMA调度。
当簇节点收到这个消息后,它们会在各自的时间槽发送数据。
簇头节点收到所有的数据后执行信号处理函数压缩数据为一个信号,并将这个合成的信号发给基站。
三、簇头建立算法流程图
簇头的建立是在decideClusterHead()函数实现。
具体流程图如图1
图1簇头建立算法流程图
四、难点解决
1.CDMA编码问题
Leach协议中不同簇用不同的CDMA编码,同一个簇采用同一个CDMA编码进行数据传输。
如果以各个簇头为结点,建立完全图。
为了使各个簇采用不同的编码,利用PCA边着色。
所谓PCA边着色问题,指在完全图中给节点的每条邻接边分配不同的码。
每个节点用一个码在其邻接边(即链路)上进行发送或接收数据。
以下,图2是PCA着色问题的一个示例。
图2PCA边着色示意图
如果记PCA需要的最大可用码数为:
#(PCA)
根据图论知识:
#(PCA)<
=2⊿-1,其中⊿指图中节点的最大度数
例如:
在图2中,节点的最大度数为6,故⊿为6
在leach协议中,假定期望的簇头数为n,再加上汇聚节点,所以,节点的最大度数⊿为(n+1)。
因此,
#(PCA)<
=2(n+1)-1=2n+1
在leachApp.cc程序中,簇头建立后,簇头决定本簇的CDMA编码。
这是在广播簇头时确定的,即advertiseClusterHead()函数中。
numCodesAvail=2*config_.spreading_-1;
//计算最大可用码
clusterCode=(mac_->
myADVnum()%numCodesAvail)+1;
//设置CDMA编码
在leachApp.cc程序中,structleachConfig中对desiredClusters_(期望的簇头数)和config_.spreading进行了定义。
在initializeConfig()函数中语句:
config_.spreading_=config_.desiredClusters_+1
在LeachApp的构造函数LeachApp(intnNodes,intnClusters,doublemaxDist)中语句:
config_.desiredClusters_=nClusters
在TCL脚本中
setval(n_common)10//普通节点个数可任意设置,此处设为10
setval(n_ch)0//簇头数初始值为0
setval(n_ch)[exprint($val(n_common)*2/10)]//对期望的簇头数进行了设置,为普通节点个数的20%(即上式中的2/10)
因此,可以计算得出numCodesAvail
在mac-sensor.h中,
intmyADVnum_;
//收到的广播消息,即邻近的簇头节点的个数
inlineint&
myADVnum(){returnmyADVnum_;
}
myADVnum()是在MAC层中计算求得。
启动运行后,计算每个簇头的邻近簇头发来的ADV。
因此,可求得clusterCode
2.TDMA调度
在findBestCluster()函数中,当判定节点是簇头节点时需要createScheduler。
在createScheduler函数中,如果簇节点不空,就需要创建TDMA时分复用帧。
frameTime表示该簇头节点分配的一个时间帧;
clusterNodes_.size()表示一个簇的节点个数
config_.ssSlotTime_表示一个时间帧的小的时隙
lstRndDelay表示缓冲时间
xmitTime_表示簇所有节点的数据发送时间
createScheduler函数主要语句如下:
frameTime_=(5+clusterNodes_.size())*config_.ssSlotTime_;
//计算时间帧
lstRndDelay_=Random:
uniform(0,0.01);
//随机选取缓冲时间
xmitTime_=config_.ssSlotTime_*(clusterNodes_.size())+lstRndDelay_;
Scheduler:
instance().schedule(
eventHandler_,
newLeachEvent(&
LeachApp:
sendDataToBS),
xmitTime_);
3.clearClusterChoices()
由于各个簇头形成和建立起来的时间不同,而簇头建立起来后需要广播ADV,通知其他节点加入。
簇头广播的ADV会被网络中的所有节点接收到,即簇头和普通节点都能收到先建立起来的簇头发来的ADV。
普通节点收到簇头发来的通知包后都会将该数据包加入自己的一个接收队列。
对后来建立起来的簇头来说,一旦自己成为簇头,就会删除其他簇头发来的广播包;
对没有成为簇头的普通节点来说,需要出接收的簇头队列中选出一个距离最近的簇头加入,然后删除接收队列中的广播包。
在decideClusterHead()函数中,当节点成为簇头后,需要执行clearClusterChoices(),函数clearClusterChoices()主要语句如下:
for(CHs:
iteratorit=clusterChoices_.begin();
it!
=clusterChoices_.end();
it++)
{
chadvelement=(chadv)*it;
if(element.object!
=NULL)
deleteelement.object;
而普通节点则需要在findBestCluster()中找到最优簇头(即距离最近的簇头)后,执行clearClusterChoices()
4.一些定义
(1)virtualdoubleTxTime(intn){returnn*8.0/1000000.0;
TxTime指以1Mbps的速度传输nbit数据所需要的时间
(2)doublelstRndDelay_;
//上次随机延迟时间
intcurrentCH_;
//当前簇头
intcurrentCHMAC_;
//当前簇头所用的MAC协议
boollistenADV_;
//是否收听ADV
boollistenJOINREQ_;
//是否监听加入请求
五、算法运行结果分析
1.场景介绍
用ns模拟每个节点向基站传输数据
BasicConfiguration:
图3BasicConfiguration配置图
AccessPoint:
图4AccessPoint配置图
CommonNode:
图5CommonNode配置图
输出得到TCL文件。
在ns环境下运行该TCL文件,得到trace文件。
2.trace
文件分析
trace的功能是详细记录模拟的过程,可以根据用户的需要记录模拟过程中的任何一个细节。
所有对模拟的分析是基于trace文件。
截取一部分文件代码如下:
s-t0.007580973-Hs1-Hd-2-Ni1-Nx48.64-Ny86.26-Nz0.00-Ne10.000000-NlAGT-Nw----Ma0-Md1000000-Ms0-Mt0-Is1.0-Id-1.0-Itrca-Il4-If0-Ii0-Iv32
r-t0.007580973-Hs1-Hd-2-Ni1-Nx48.64-Ny86.26-Nz0.00-Ne10.000000-NlRTR-Nw----Ma0-Md1000000-Ms0-Mt0-Is1.0-Id-1.0-Itrca-Il4-If0-Ii0-Iv32
s-t0.007580973-Hs1-Hd-2-Ni1-Nx48.64-Ny86.26-Nz0.00-Ne10.000000-NlRTR-Nw----Ma0-Md1000000-Ms0-Mt0-Is1.0-Id-1.0-Itrca-Il4-If0-Ii0-Iv32
在文件分析中主要用到t,Ni,Ne这几个数据。
其中,t后面的数字代表时间,Ni后面的数字代表节点ID,Ne后面的数字代表节点能量
使用语言gwak,绘图工具gnuplot.上述场景中生成的trace文件名为:
trace.tr
去掉所有以N开头的行数,该行为统计数据,得到文件trace1.tr
(1)单个节点能量变化统计:
以节点1为例,提取所有Ni等于1的节点的时间和相应能量,存入文件1.txt.
在gawk环境中,输入代码如下:
gawk‘$9==/1/{print$3,$17}’trace1.tr>
1.txt
得到统计数据如下:
0.00758097310.000000
0.00760597310.000000
2.4613463769.963363
2.4613713769.963363
3.5363729739.945803
3.5363979739.945803
在gnuplot环境中输入:
gnuplot‘1.txt’using1:
2
得到的能量变化图如下图所示:
图6节点1能量变化图
(2)工作节点能量统计:
从trace.tr文件中提取普通节点的数据。
gawk‘$1~/N/{print$3,$5,&
7}’trace.tr>
n.txt//第3列代表时间,第5列代表节点ID,第7列代表能量值
gawk‘$2!
=0{print$1,$3}’n.txt>
2.txt//去掉sink节点,sink节点ID为0
再从2.txt中进行能量统计,统计时间间隔为0.5秒
gawk‘{if($1<
0.5)sum+=$2};
END{printsum}’2.txt>
3.txt
gawk‘{if($1<
1.0)sum+=$2};
END{printsum}’2.txt>
>
2.5)sum+=$2};
3.0)sum+=$2};
3.5)sum+=$2};
4.0)sum+=$2};
4.5)sum+=$2};
得到文件3.txt的统计数据如下:
0.53918.84
1.02937.01
2.51395.12
3.04700.22
3.55194.79
4.03271.12
4.51132.38
全网间隔时间为0.5秒工作节点能量变化图:
图7工作节点能量变化图
3.全网所有节点能量和变化统计
在gawk环境下输入:
gawk‘$9!
=0{print$3,$9,$17}’trace1.tr>
4.txt//提取普通节点的时间,ID,能量
将以下程序写入文件1.awk
BEGIN{
FS="
"
unit=0.5;
ftime=0;
time=0;
for(i=1;
i<
=50;
i++)
{e[i]=10.0;
sum+=e[i];
printf"
%f,%f\n"
time,sum;
time+=unit;
{
if(ftime<
$1&
&
$1<
time)
{k=$2;
e[k]=$3;
}
END{
sum=0
sum+=e[i]
%f,%f\n"
在awk环境下,输入
awk–f1.awktrace1.tr>
5.txt
在5.txt文件中得到的是0到0.5秒之间全网的总能量。
再不断地将每个时间间隔为0.5秒的数据写入文件5.txt(只需在文件5.txt中不断追加统计数据)。
最后可以得到0到4.5秒之间全网在每0.5秒的时间间隔的总能量。
最后得到的5.txt统计数据如下:
0.000000,500.000000
0.500000,499.757217
1.000000,499.504800
1.500000,499.504800
2.000000,499.504800
2.500000,499.172733
3.000000,498.436798
3.500000,497.875816
4.000000,497.525730
4.500000,496.948944
在gnuplot环境下,输入命令:
gnuplot‘5.txt’using1:
2withlp
最后得到的全网能量变化情况如下图所示:
图8全网能量统计图
4.生成的簇头和簇节点统计
设置普通节点个数50,AP节点1个,仿真时间10秒,普通节点位置随机产生。
生成TCL文件,运行该TCL文件将结果输出到2.tr文件中。
在gawk环境中,输入下列命令:
gawk‘($1==”On”)&
($7==”at”){print$0}’2.tr>
3.tr
gawk‘BEGIN{FS=”“};
{print$10,$11,$12,$13,$14,$15,$16}’3.tr>
3.txt
在3.txt文件中得到以下数据:
ClusterHead11,ClusterNode:
47
ClusterHead23,ClusterNode:
10281635
ClusterHead9,ClusterNode:
3326
ClusterHead25,ClusterNode:
4921946
ClusterHead24,ClusterNode:
412936721
ClusterHead37,ClusterNode:
8
ClusterHead50,ClusterNode:
ClusterHead15,ClusterNode:
6348
ClusterHead39,ClusterNode:
452234315
ClusterHead18,ClusterNode:
30
ClusterHead40,ClusterNode:
44
ClusterHead42,ClusterNode:
321714
ClusterHead13,ClusterNode:
382741220
ClusterHead43,ClusterNode:
1
5.生成的nam图
图9nam图
参考文献
[1]《DistributedcodeassignmentsforCDMApacketradionetworks》(FTP:
10.10.138.1)
[2]《heinzelman_PhDthesis_Application-SpecificProtocolArchitecturesforWirelessNetworks》(FTP:
[3]《Leach_PPT》(FTP:
[4]《NS与网络模拟》(徐雷鸣,庞博,耀编著,人民邮电)