clear;
clc;
clf;
NodeNums=100;
AreaR=100;
Bx=20;
By=150;
En=0.25;
send_to_sink=0; %%簇头距离基站距离
data_pkt_length=2000;
die_node_num=0; %%本轮死亡节点数
die_node_num_pri=0;
run_round=0;
En_Cost=0; %%本轮消耗能量
En_Cost_pre=0; %%上一轮消耗能量
En_cost_per_round=0;
begin_to_send=0; %%开始发送的num
num=1;
alive=1;
dead=0;
Node.x=AreaR*rand(1,NodeNums);
Node.y=AreaR*rand(1,NodeNums);
Node.pri=linspace(0,0,NodeNums);
Node.already=linspace(0,0,NodeNums);
Node.to_nbr_dis=zeros(NodeNums);
Node.to_pri_dis=linspace(0,0,NodeNums); %%与当前节点最近的距离
Node.send_dis=linspace(0,0,NodeNums); %%节点之间距离表初始为0
Node.E=linspace(En,En,NodeNums);
Node.status=linspace(alive,alive,NodeNums);
ETX=50*0.000000001; %%发送数据包消耗能量
ERX=50*0.000000001; %%接收数据包消耗能量
Efs=100*0.000000000001; %%连接点之间的传递参数
Emp=0.0013*0.000000000001; %%簇首与基站之间的传递参数
EDA=5*0.000000001; %%融合数据消耗能量
do=sqrt(Efs/Emp); %%平均半径
%%计算各个节点距离基站的位置距离
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% 数据通信
while (NodeNums-die_node_num)>0 %%每一轮循环为一次数据通信,直到节点死光
if run_round==0||die_node_num_pri~=die_node_num %%当上一轮死亡节点不等于下一轮死亡节点数
Node.pri=linspace(0,0,NodeNums); %% 与当前节点最近的节点num
num_plot=1;
Node.already=linspace(0,0,NodeNums);
for i=1:1:NodeNums
if Node.status(i)==alive
to_sink_dist(i)=sqrt((Node.x(i)-Bx)^2+(Node.y(i)-By)^2);
else
to_sink_dist(i)=0;
end
end %%求出所有存活节点到基站的距离
[Max_Dis, Max_num]=max(to_sink_dist); %%求出距离基站最大的距离
now_node=Max_num;
Node.already(now_node)=1;
node_head=Max_num; %%头结点
% send_to_sink=now_node;
node_to_send=now_node;
start_node=now_node; %%求出开始节点
while num_plot~=NodeNums-die_node_num
if num_plot==NodeNums-die_node_num
Node.pri(now_node)=0;
node_tail=now_node; %%记录尾节点
end
for j=1:1:NodeNums
if Node.already(j)==0&&Node.status(j)==alive
Node.to_nbr_dis(now_node,j)=sqrt((Node.x(now_node)-Node.x(j))^2+(Node.y(now_node)-Node.y(j))^2); %%与邻居的距离
else
Node.to_nbr_dis(now_node,j)=0;
end
end
j=1;
while Node.to_nbr_dis(now_node,j)==0 %%即当有节点死亡时
j=j+1; %%重新编号
end
min_dis=Node.to_nbr_dis(now_node,j);
min_num=j;
for j=1:1:NodeNums
if Node.to_nbr_dis(now_node,j)~=0&&Node.to_nbr_dis(now_node,j)<min_dis
min_dis=Node.to_nbr_dis(now_node,j);
min_num=j;
end
end %%找出与当前节点距离最近的节点
Node.to_pri_dis(now_node)=min_dis; %%求出最小距离
Node.pri(now_node)=min_num; %%最小num
if now_node==Max_num
Node.to_pri_dis(now_node);
end
now_node=Node.pri(now_node);
% min_num
Node.already(now_node)=1;
% Node.to_pri_dis(now_node)=min_dis;
% min_dis
num_plot=num_plot+1;
end
node_tail=now_node;
I_want=1;
if I_want==1
figure(1);
if run_round~=1
clf;
end
% plot(Bx,By,'*k',Bx,By,'ok');%%标注基站位置
% hold on;
for i=1:1:NodeNums
if Node.status(i)==alive
plot(Node.x(i), Node.y(i), 'o','markersize',5);%%标注存活节点位置
hold on;
end
end
plot(Node.x(node_tail), Node.y(node_tail), 'o-r','markersize',5);%%链尾节点
plot(Node.x(node_head), Node.y(node_head), 'o-r','markersize',5);%%链首节点
for i=1:1:NodeNums
if Node.status(i)==alive
if Node.pri(i)~=0
plot([Node.x(i);Node.x(Node.pri(i))],[Node.y(i);Node.y(Node.pri(i))]);%%相邻节点间成链
hold on;
end
else
plot(Node.x(i), Node.y(i), 'o-r'); %%输出尾节点
end
end
end
xlabel('X-coordinate');
ylabel('Y-coordinate');
title('节点分布图');
end
send_to_sink=mod(begin_to_send,NodeNums)+1; %%领导节点的定义方式
run_round=run_round+1;
while Node.status(send_to_sink)~=alive %%如果领导节点死亡,领导节点变为距离其最近的下一个节点
send_to_sink=mod(send_to_sink,NodeNums)+1;
end
begin_to_send=send_to_sink+1;
die_node_num_pri=die_node_num;
num=1;
right_send_num=1;
node_to_send=node_head;
start_node=node_head;
while node_to_send~=send_to_sink
right_send_num=right_send_num+1;
node_to_send=Node.pri(node_to_send);
end
% right_send_num
Node.send_dis=linspace(0,0,NodeNums);
while num~=NodeNums+1-die_node_num
if num<right_send_num
Node.send_dis(start_node)=Node.to_pri_dis(start_node);
start_node=Node.pri(start_node);
end
if num==right_send_num
Node.send_dis(start_node)=to_sink_dist(start_node);
start_node_1=start_node;
start_node=Node.pri(start_node);
end
if num>right_send_num
Node.send_dis(start_node)=Node.to_pri_dis(start_node_1);
start_node_1=start_node;
start_node=Node.pri(start_node);
end
num=num+1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 链首的三种不同位置的情况下各节点剩余的能量的计算
if send_to_sink==node_head %%链头节点是簇头的情况
for i=1:1:NodeNums
if Node.status(i)==alive
if i==send_to_sink
if Node.send_dis(i)>do
Node.E(i)=Node.E(i)-(ERX*data_pkt_length+EDA*2*data_pkt_length+ETX*data_pkt_length+Efs*(Node.send_dis(i).^2)*data_pkt_length);
else
Node.E(i)=Node.E(i)-(ERX*data_pkt_length+EDA*2*data_pkt_length+ETX*data_pkt_length+Efs*(Node.send_dis(i).^2)*data_pkt_length);
end
end
if i==node_tail
if Node.send_dis(i)>do
Node.E(i)=Node.E(i)-(ETX*data_pkt_length+Efs*(Node.send_dis(i).^2)*data_pkt_length);
else
Node.E(i)=Node.E(i)-(ETX*data_pkt_length+Efs*(Node.send_dis(i).^2)*data_pkt_length);
end
end
if i~=send_to_sink&&i~=node_head&&i~=node_tail
if Node.send_dis(i)>do
Node.E(i)=Node.E(i)-(ERX*data_pkt_length+EDA*2*data_pkt_length+ETX*data_pkt_length+Efs*(Node.send_dis(i).^2)*data_pkt_length);
else
Node.E(i)=Node.E(i)-(ERX*data_pkt_length+EDA*2*data_pkt_length+ETX*data_pkt_length+Efs*(Node.send_dis(i).^2)*data_pkt_length);
end
end
end
end
end
if send_to_sink==node_tail %%链尾节点是簇头的情况
for i=1:1:NodeNums
if Node.status(i)==alive
if i==send_to_sink
if Node.send_dis(i)>do
Node.E(i)=Node.E(i)-(ERX*data_pkt_length+EDA*2*data_pkt_length+ETX*data_pkt_length+Emp*(Node.send_dis(i).^4)*data_pk