MATLAB-無線傳感器網絡泛洪(Flooding)協議仿真
總結
- 我選取所需鄰居節點的思想是從所有鄰居節點中隨機選取所需的節點數,在一定方面上,這種選取的方法是有一定不足的,性能也沒有很好。應該要經過運用某種距離算法,在已知所有鄰居節點中擇優選取最佳的鄰居節點。在我目前能力不足,只能實現這種方法:在已知的所有鄰居節點中隨機選取5個鄰居節點。
- 在運行時間對比上,我只選取了10個點,其實這種做法也是不足的,應該選取至少100多個點去比較性能,纔能有更大的說服力。
- 代碼還有很多地方想要改進,如果你有更好的想法與實現方案,歡迎來交流啊!分享一下自己的經驗與心得。
參考文檔鏈接
1.無線傳感器網絡flooding路由協議的MATLAB仿真論文
2.原代碼出處_MATLAB實現洪泛路由的模擬
注
若複製的代碼不能運行,聯繫我;
或在這個鏈接裏自行下載
鏈接:https://pan.baidu.com/s/1bXKE7QWY5JNycOWpiBfa7g
提取碼:zkrt
一.界面介紹
1.主窗口:含五個按鈕:開始繪圖按鈕、所有鄰居節點的Flooding按鈕、5個鄰居節點的Flooding按鈕、3個鄰居節點的Flooding按鈕、點擊運行效率對比按鈕
2.繪圖窗口
3.繪製路線窗口,點上標的76543210代表跳數,空心點代表尋找過的鄰居節點
所有鄰居節點的Flooding
5個鄰居節點的Flooding
3個鄰居節點的Flooding
4.查找路線節點運行效率曲線對比窗口
二、 Flooding算法工作流程圖
三、 .m文件
flooding.m
%% 界面介紹
% 1.主窗口:含五個按鈕:開始繪圖按鈕、所有鄰居節點的Flooding按鈕、
% 5個鄰居節點的Flooding按鈕、3個鄰居節點的Flooding按鈕、點擊運行效率對比按鈕
% 2.繪圖窗口
% 3.繪製路線窗口,點上標的76543210代表跳數
% 4.查找路線節點運行效率曲線對比窗口
%% 操作說明:
% 1.首先點擊開始繪圖按鈕,創建圖像;
% 2.點擊所有鄰居節點的Flooding按鈕,繪製路線,線段顏色爲紅色;
% 3.點擊5個鄰居節點的Flooding按鈕,繪製路線,線段顏色爲綠色;
% 4.點擊3個鄰居節點的Flooding按鈕,繪製路線,線段顏色爲藍色;
% 5.經過以上的步驟,我們已經得到了三個算法的一條路線及一個查找路線節點的時間,後即可關閉繪製的窗口,
% 重新繪製新的路線、計算新的查找路線節點的時間,重複1、2、3、4步驟10次,獲取每個算法10個不同的查找路線節點的時間
% (因爲在運行效率對比按鈕那我用了10個數據點去繪製對比曲線,所以,當某一個算法的數據點不足10個或大於10個時,
%
都無法繪製曲線成功)
% (命令行窗口會有節點序號、查找路線節點的時間的記錄反饋);
% (當數據點不足10個時,接着畫;大於10個時,只能關閉程序,重新畫了(因爲我沒有提供刪除時間的功能));
% 6.當集滿三個算法的時間後,即可點擊運行效率對比按鈕,查看三個算法的查找路線節點時間曲線對比圖。
% (注:有時候沒有返回值,是因爲沒有找到路線,關掉窗口,重新繪製個圖,重新找)
%% 主程序
function flooding
%用於存放三個算法的運行事件
global flooding1;
global flooding5;
global flooding3;
flooding1=[];
flooding5=[];
flooding3=[];
%用於標記鄰居節點數,0代表所有個,5代表5個,3代表3個
num1=0;
num2=5;
num3=3;
%創建窗口
fig = uifigure;
% 創建按鈕
%所有制鄰居節點的Flooding按鈕
btn1 = uibutton(fig,'push',...
'Position',[120, 330, 200,
34],...
'Text', '所有制鄰居節點的Flooding',...
'ButtonPushedFcn', @(btn1,event)
plotButtonPushed1(btn1,num1));
%5個鄰居節點的Flooding按鈕
btn2 = uibutton(fig,'push',...
'Position',[120, 230, 200,
34],...
'Text', '5個鄰居節點的Flooding',...
'ButtonPushedFcn', @(btn2,event)
plotButtonPushed2(btn2,num2));
%5個鄰居節點的Flooding按鈕
btn3 = uibutton(fig,'push',...
'Position',[120, 130, 200,
34],...
'Text', '3個限制鄰居節點的Flooding',...
'ButtonPushedFcn', @(btn3,event)
plotButtonPushed3(btn3,num3));
%三個算法的運行效率對比
btn4 = uibutton(fig,'push',...
'Position',[230, 30, 200,
34],...
'Text', '運行效率對比',...
'ButtonPushedFcn', @(btn4,event)
plotButtonPushed4(btn4));
%開始繪圖按鈕
btn5 = uibutton(fig,'push',...
'Position',[20, 30, 200,
34],...
'Text', '開始繪圖',...
'ButtonPushedFcn', @(btn5,event)
plotButtonPushed5(btn5));
end
function plotButtonPushed1(btn1,num1)
global flooding1;
global srcx;
global destx;
global xLocation;
global yLocation;
global route;%記錄傳輸路徑
global radius;%作用範圍
global distMatrix;
global numOfNodes;
global success;%標記是否成功訪問到目的節點
success=0;
global visited;%標記節點是否被訪問過
visited=zeros(1,100);%初始時都未被訪問
route=[];
global neighborNodes;%記錄傳輸路徑
neighborNodes=[];
%% 建立距離矩陣
distMatrix = zeros(numOfNodes);
for i=1:numOfNodes
for j=i+1:numOfNodes
distMatrix(i,j)=distance([xLocation(i),yLocation(i)],[xLocation(j),yLocation(j)]);
end
distMatrix(i,i)=10;%排除自身節點
end
distMatrix = distMatrix+distMatrix';
%% 開始查找
% clock用於計算查找節點的時間,ttl是條數
ttl=7;
t1=clock;
DFS_num(srcx,ttl,num1);
t2=clock;
%將記錄下來的時間放入flooding1
i=length(flooding1)+1;
flooding1(i)=etime(t2,t1);
disp('所有鄰居節點查找路線節點所需的時間爲:');
disp(flooding1);
%% 畫出傳輸路徑圖
if(ismember(destx,route))
disp('傳輸成功')
j=length(route);
while(j~=1)
for i=1:j-1
if(distMatrix(route(i),route(j))<=radius&&i~=j-1)
route(i+1:1:j-1)=[];
break;
end
end
j=i;
end
else
route=[];
disp('傳輸失敗');
end
%繪製路線
plot(xLocation(route),yLocation(route),'o-r','Markerfacecolor','r','MarkerSize',3);
disp('所有鄰居節點路線上的節點序號爲:');
disp(route)
end
% Create the function for the
ButtonPushedFcn callback
function plotButtonPushed2(btn2,num2)
global flooding5;
global srcx;
global destx;
global xLocation;
global yLocation;
global route;%記錄傳輸路徑
global numOfNodes;
global distMatrix;
global radius;%作用範圍
global success;%標記是否成功訪問到目的節點
success=0;
global visited;%標記節點是否被訪問過
visited=zeros(1,100);%初始時都未被訪問
route=[];
global neighborNodes;%記錄傳輸路徑
neighborNodes=[];
%% 建立距離矩陣
distMatrix = zeros(numOfNodes);
for i=1:numOfNodes
for j=i+1:numOfNodes
distMatrix(i,j)=distance([xLocation(i),yLocation(i)],[xLocation(j),yLocation(j)]);
end
distMatrix(i,i)=10;%排除自身節點
end
distMatrix = distMatrix+distMatrix';
%% 開始查找
% clock用於計算查找節點的時間,ttl是條數
t11=clock;
num=5;
ttl=7;
DFS_num(srcx,ttl,num2);
%將記錄下來的時間放入flooding5
t22=clock;
i=length(flooding5)+1;
flooding5(i)=etime(t22,t11);
disp('5個鄰居節點查找路線節點所需的時間爲:');
disp(flooding5);
%% 畫出傳輸路徑圖
if(ismember(destx,route))
disp('傳輸成功')
j=length(route);
while(j~=1)
for i=1:j-1
if(distMatrix(route(i),route(j))<=radius&&i~=j-1)
route(i+1:1:j-1)=[];
break;
end
end
j=i;
end
else
route=[];
disp('傳輸失敗');
end
%繪製路線圖
plot(xLocation(route),yLocation(route),'.-g','Markerfacecolor','r','MarkerSize',3);
disp('5個鄰居節點路線上的節點序號爲:');
disp(route)
end
function plotButtonPushed3(btn3,num3)
global flooding3;
global srcx;
global destx;
global xLocation;
global yLocation;
global route;%記錄傳輸路徑
global numOfNodes;
global distMatrix;
global radius;%作用範圍
global success;%標記是否成功訪問到目的節點
success=0;
global visited;%標記節點是否被訪問過
visited=zeros(1,100);%初始時都未被訪問
route=[];
global neighborNodes;%記錄傳輸路徑
neighborNodes=[];
%% 建立距離矩陣
distMatrix = zeros(numOfNodes);
for i=1:numOfNodes
for j=i+1:numOfNodes
distMatrix(i,j)=distance([xLocation(i),yLocation(i)],[xLocation(j),yLocation(j)]);
end
distMatrix(i,i)=10;%排除自身節點
end
distMatrix = distMatrix+distMatrix';
%% 開始查找
% clock用於計算查找節點的時間,ttl是條數
t111=clock;
num=3;
ttl=7;
DFS_num(srcx,ttl,num3);
%將記錄下來的時間放入flooding3
t222=clock;
i=length(flooding3)+1;
flooding3(i)=etime(t222,t111);
disp('3個鄰居節點查找路線節點所需的時間爲:');
disp(flooding3);
%% 畫出傳輸路徑圖
if(ismember(destx,route))
disp('傳輸成功')
j=length(route);
while(j~=1)
for i=1:j-1
if(distMatrix(route(i),route(j))<=radius&&i~=j-1)
route(i+1:1:j-1)=[];
break;
end
end
j=i;
end
else
route=[];
disp('傳輸失敗');
end
%繪製路線圖
plot(xLocation(route),yLocation(route),'>-b','Markerfacecolor','r','MarkerSize',3);
disp('3個鄰居節點路線上的節點序號爲:');
disp(route)
end
function plotButtonPushed4(btn4)
global flooding1;
global flooding5;
global flooding3;
%記錄10條算法的時間,
Ay=flooding1;%所有鄰居節點的
Ax=[1,2,3,4,5,6,7,8,9,10];
By=flooding5;%5個鄰居節點的
Bx=[1,2,3,4,5,6,7,8,9,10];
Cy=flooding3;%3個鄰居節點的
Cx=[1,2,3,4,5,6,7,8,9,10];
%繪製時間對比曲線圖,注!必須有10條記錄了才能繪製(因爲x有10個點,y也得有10個點)
plot(Ax,Ay,'o-r',Bx,By,'.-g',Cx,Cy,'>-b');
legend('所有鄰居節點','5個鄰居節點','3個鄰居節點');
%顯示線段上的備註
for i=1:10
str1=sprintf('%2.4f',Ay(i));
str2=sprintf('%2.4f',By(i));
str3=sprintf('%2.4f',Cy(i));
text(Ax(i),Ay(i),str1);
text(Bx(i),By(i),str2);
text(Cx(i),Cy(i),str3);
end
disp('所有鄰居節點查找路線節點所需的時間爲:');
disp(Ay);
disp('5個鄰居節點查找路線節點所需的時間爲:');
disp(By);
disp('3個鄰居節點查找路線節點所需的時間爲:');
disp(Cy);
end
function plotButtonPushed5(btn5)
% Create a figure window
global flooding1;
global flooding5;
global flooding3;
%global ttl;
%ttl=7;%設置最大傳輸跳數爲7
%% 初始化無線傳感網示意圖
%.傳感器節點區域界限
envSize=10;
%區域內傳感器數量
global numOfNodes;
numOfNodes=100;
global radius;%作用範圍
radius=5;
global xLocation;
global yLocation;
xLocation = rand(numOfNodes,1) * envSize;
yLocation = rand(numOfNodes,1) *
envSize; %x,y座標
global srcx;
global destx;
srcx = floor(0.1345 * numOfNodes)+1; %第srcx個節點作爲源節點
destx = floor(0.5126 * numOfNodes)+1;%第destx個節點作爲目的節點
global success;%標記是否成功訪問到目的節點
success=0;
global visited;%標記節點是否被訪問過
visited=zeros(1,100);%初始時都未被訪問
global route;%記錄傳輸路徑
route=[];
global neighborNodes;%記錄傳輸路徑
neighborNodes=[];
%% 畫圖
figure(1);
hold on;
plot(xLocation, yLocation, '.');
plot(xLocation(srcx),yLocation(srcx),'ko','Markerfacecolor','k','MarkerSize',3);
plot(xLocation(destx),yLocation(destx),'ko','Markerfacecolor','k','MarkerSize',3);
text(xLocation(srcx),yLocation(srcx), '源節點');
text(xLocation(destx),yLocation(destx), '目的節點');%標記源節點和目的節點
src=[xLocation(srcx),yLocation(srcx)];
dest=[xLocation(destx),yLocation(destx)];
legend('紅線所有鄰居節點','綠線5個鄰居節點','藍線3個鄰居節點');
end
DFS_num.m(DFS數據傳輸階段)
function [] = DFS_num(r,ttl,num)% r:源節點
TTL:生存週期 num:鄰居節點數
%%
global success;
global visited;%標記節點是否被訪問過
global distMatrix;%節點間的距離矩陣
global destx;%目的節點
global radius;%作用範圍
global route;%記錄傳輸路徑
global neighborNodes1;%記錄所有鄰居節點數
global xLocation;
global yLocation;
global neighborNodes;%記錄所需鄰居節點數
visited(r)=1;
if(success==1||ttl<0)
return;
end
if(~ismember(r,route))
route=[route,r];
else
temp=find(route==r);
route=[route,r];
route(temp+1:1:end)=[];
end
neighborNodes1=find(distMatrix(r,:)<=radius);%查找在作用範圍內的鄰節點,選取目標節點與所有區域的距離且小於規定範圍的節點
neighborNodes1=intersect(neighborNodes1,
find(visited(:) == 0));%找到可訪問的 neighborNodes是列向量
%所有鄰居節點
if(num==0)
neighborNodes=neighborNodes1;
end
%5個鄰居節點,從所有鄰居節點中選取5個
if(num==5)
neighborNodes=zeros(num,1);
for i=1:num
neighborNodes(i)=neighborNodes1(int32(1+(length(neighborNodes1)-1)*rand));
end
end
%3個鄰居節點,從所有鄰居節點中選取5個
if(num==3)
neighborNodes=zeros(num,1);
for i=1:num
neighborNodes(i)=neighborNodes1(int32(1+(length(neighborNodes1)-1)*rand));
end
end
if(ismember(destx,neighborNodes))%如果鄰節點中含有目的節點
success=1;
route=[route destx];
str=sprintf('%2.0f',ttl); % 2位小數的浮點型text
text(xLocation(destx),yLocation(destx),str);
return;
end
%% 遞歸程序的出口
if (isempty(neighborNodes))%鄰節點爲空
route(end)=[];%刪除當前源節點,返回上一層
%畫出尋找過的鄰居節點,並顯示是在第幾跳查找到的
plot(xLocation(neighborNodes(k)),yLocation(neighborNodes(k)),'ro-','Markerfacecolor','y','MarkerSize',3)
str=sprintf('%2.0f',ttl); % 2位小數的浮點型text
text(xLocation(neighborNodes(k)),yLocation(neighborNodes(k)),str);
return;
end
%% 遞歸--當前節點的鄰節點中不含有目的節點,從其鄰節點開始查找
ttl=ttl-1;
for k = 1:length(neighborNodes)
%
if (visited(neighborNodes(k)) == 0)
if(neighborNodes(k)==destx)%當傳給中心點時結束
success=1;
%畫出尋找過的鄰居節點,並顯示是在第幾跳查找到的
plot(xLocation(neighborNodes(k)),yLocation(neighborNodes(k)),'ro-','Markerfacecolor','y','MarkerSize',3)
str=sprintf('%2.0f',ttl+1); % 2位小數的浮點型text
text(xLocation(neighborNodes(k)),yLocation(neighborNodes(k)),str);
break;
end;
%畫出尋找過的鄰居節點,並顯示是在第幾跳查找到的
plot(xLocation(neighborNodes(k)),yLocation(neighborNodes(k)),'ro-','Markerfacecolor','y','MarkerSize',3)
str=sprintf('%2.0f',ttl+1); % 2位小數的浮點型text
text(xLocation(neighborNodes(k)),yLocation(neighborNodes(k)),str);
DFS_num(neighborNodes(k),ttl,num);
%end;
end;
distance.m
這是一個函數文件,建立腳本是選擇函數腳本
%% 求兩個節點之間的距離
function dis = distance(A,B)
dis = sqrt((A(1)-B(1))^2+(A(2)-B(2))^2);
end
四、效果展示
- 運行flooding.m
- 主窗口效果
- 繪圖窗口效果
- 繪製路線效果
- 查找路線節點運行時間對比曲線圖
五、代碼講解
1.操作說明:
1.首先點擊開始繪圖按鈕,創建圖像;
2.點擊所有鄰居節點的Flooding按鈕,繪製路線,線段顏色爲紅色;
3.點擊5個鄰居節點的Flooding按鈕,繪製路線,線段顏色爲綠色;
4.點擊3個鄰居節點的Flooding按鈕,繪製路線,線段顏色爲藍色;
5.經過以上的步驟,我們已經得到了三個算法的一條路線及一個查找路線節點的時間,後即可關閉繪製的窗口,重新繪製新的路線、計算新的查找路線節點的時間,重複1、2、3、4步驟10次,獲取每個算法10個不同的查找路線節點的時間
(注:因爲在運行效率對比按鈕那我用了10個數據點去繪製對比曲線,所以,當某一個算法的數據點不足10個或大於10個時,都無法繪製曲線成功)
(注:命令行窗口會有節點序號、查找路線節點的時間的記錄反饋);
(注:當數據點不足10個時,接着畫;大於10個時,只能關閉程序,重新畫了(因爲我沒有提供刪除時間的功能));
6.當集滿三個算法的時間後,即可點擊運行效率對比按鈕,查看三個算法的查找路線節點時間曲線對比圖。
(注:有時候沒有返回值,是因爲沒有找到路線,關掉窗口,重新繪製個圖,重新找)
2.關於鄰居節點的選取
- 選取的方法:在所有鄰居節點中隨機選取自己想要的個數,用num這個全局變量裏設置。
- num變量在flooding.m中的function flooding定義,在按鈕啓動事件函數plotButtonPushed(btn,num)中調用給DFS_num.m進行選取。
flooding.m相關的代碼
function flooding
%用於標記鄰居節點數,0代表所有個,5代表5個,3代表3個
num1=0;
num2=5;
num3=3;
%所有制鄰居節點的Flooding按鈕
btn1 = uibutton(fig,'push',...
'Position',[120, 330, 200,
34],...
'Text', '所有制鄰居節點的Flooding',...
'ButtonPushedFcn', @(btn1,event)
plotButtonPushed1(btn1,num1));
%5個鄰居節點的Flooding按鈕
btn2 = uibutton(fig,'push',...
'Position',[120, 230, 200,
34],...
'Text', '5個鄰居節點的Flooding',...
'ButtonPushedFcn', @(btn2,event)
plotButtonPushed2(btn2,num2));
%5個鄰居節點的Flooding按鈕
btn3 = uibutton(fig,'push',...
'Position',[120, 130, 200,
34],...
'Text', '3個限制鄰居節點的Flooding',...
'ButtonPushedFcn', @(btn3,event)
plotButtonPushed3(btn3,num3));
end
function plotButtonPushed1(btn1,num1)
%% 開始查找
DFS_num(srcx,ttl,num1);
End
function plotButtonPushed2(btn2,num2)
%% 開始查找
DFS_num(srcx,ttl,num2);
end
function plotButtonPushed3(btn3,num3)
%% 開始查找
DFS_num(srcx,ttl,num3);
end
DFS_num
function [] = DFS_num(r,ttl,num)% r:源節點
TTL:生存週期 num:鄰居節點數
global neighborNodes1;%記錄所有鄰居節點數
global neighborNodes;%記錄所需鄰居節點數
neighborNodes1=find(distMatrix(r,:)<=radius);%查找在作用範圍內的鄰節點,選取目標節點與所有區域的距離且小於規定範圍的節點
neighborNodes1=intersect(neighborNodes1,
find(visited(:) == 0));%找到可訪問的 neighborNodes是列向量
%所有鄰居節點
if(num==0)
neighborNodes=neighborNodes1;
end
%5個鄰居節點,從所有鄰居節點中選取5個
if(num==5)
neighborNodes=zeros(num,1);
for i=1:num
neighborNodes(i)=neighborNodes1(int32(1+(length(neighborNodes1)-1)*rand));
end
end
%3個鄰居節點,從所有鄰居節點中選取5個
if(num==3)
neighborNodes=zeros(num,1);
for i=1:num
neighborNodes(i)=neighborNodes1(int32(1+(length(neighborNodes1)-1)*rand));
end
end
end