📄 7.m
字号:
end
end%一簇运行完毕(while((P(m).next~=0)&(P(k).energy>0))%簇内的各节点逐个的运行)
if(head==0)%如果是因为头节点能量用完而跳出的,则直接跳到下一层
break
end
%修改时间标识
if(P(k).energy<=0)%若因为簇头能量小于0而结束的结束本簇运行的,则跳过本簇次的后续程序
continue;%for k=1:1000 %次外层循环;用于最底层的通信
end
if((P(k).num)>maxnum)
maxnum=P(k).num;
end%纪录最大的传输时间
end%结束该头节点的运行(if)
end%(for k=1:1000 %次外层循环;用于最底层的通信)
time=time+maxnum;%完成一轮底层通信所用的时间
%簇头的信息传输
for i=1:1000
%起始时确定根节点,若发生根节点变化的情况时重新分配网络
if((P(i).level==2)&(P(i).energy>0)&(head==0))%用head纪录根节点<初始时head=1>
head=i;%认为第一个头节点为根节点
%修改新根节点的路由信息
P(head).out=0;
P(head).sur=100;
P(head).ort=0;
%修改头节点的传输功率(重新建立新的网络结构)
for j=i+1:1000
if((P(j).level==2)&(P(j).energy>0))
P(j).sur=0;%清空原来的网络层次
end
end
for j=i+1:1000
if((P(j).level==2)&(P(j).energy>0))
N5=fix(sqrt((P(head).x-P(j).x)^2+(P(head).y-P(j).y)^2+(P(head).z-P(j).z)^2));%距离公式
if(N5<=6928)%(外围一层头节点)
P(j).ort=head;
P(j).sur=1;
P(j).out=M*N5^2;%修改头节点到根节点的传输功率
end
end
end
%建立新的外围二层节点
for j=i+1:1000
sd=fix(sqrt((P(head).x-P(j).x)^2+(P(head).y-P(j).y)^2+(P(head).z-P(j).z)^2));
W2=head;
for v=i+1:1000
if((P(j).level==2)&(P(j).energy>0)&(P(j).sur==0)&(P(v).level==2)&(P(v).energy>0)&(P(v).sur==2))
N5=fix(sqrt((P(v).x-P(j).x)^2+(P(v).y-P(j).y)^2+(P(v).z-P(j).z)^2));%距离公式
if(N5<sd)%(外围一层头节点)
sd=N5;
W2=v;
end
end
end
if(W2==head)
P(j).sur=1;
else
P(j).sur=2;
end
P(j).ort=W2;
P(j).out=M*sd^2;%修改头节点到根节点的传输功率
end
break;%因为网络重组所以重新运行
else%如果没有调整网络
%起始时确定根节点,若发生根节点变化的情况时重新分配网络
%外围一层头节点
if((P(i).level==2)&(P(i).sur==1)&(P(i).energy>0))%找出一般性外围一层的节点
P(i).energy=P(i).energy-P(i).out*(P(i).num+1);%发射功率,因为包含子节点的信息所以要用乘
if(P(i).energy<=0)%若功率用尽,则找簇头代替,
num=num-1;%总数减少了1
fprintf('头节点%d ',P(i).id);%输出该头节点
P(i).level=0;%作为能量耗尽的标示
if(P(i).next~=0)%若簇不空,
P(P(i).next).level=2;%改变头节点。不用考虑P(k).next是否存在,因为如果不存在则不会出现头节点能量为零的情况
z=i;%z用于对头节点改造的计序
while(P(z).next~=0)%(内二层循环)用于对头节点的改造
P(P(i).next).num=P(P(i).next).num+1;%邻节点数加1
P(P(z).next).cid=P(i).next;%改变网络中各节点的头节点标识
P(P(z).next).out=M*(fix(sqrt((P(P(z).next).x-P(P(i).next).x)^2+(P(P(z).next).y-P(P(i).next).y)^2+(P(P(z).next).z-P(P(i).next).z)^2)))^2;%距离公式%改变至总簇头的传输能量%修改传输功率
z=P(z).next;%向后爬动
end%完成对各子节点的改造
if(P(i).next~=0)%如果上面的循环运行了,减去纪录自己的一次
P(P(i).next).num=P(P(i).next).num-1;%减去自己的一点
end
%修改路由
P(P(i).next).sur=1;
P(P(i).next).ort=head;
%该点代替头节点链表中的位置,因为有后续节点代替所以簇数不会减少
%用后续节点取代原节点作中继节点
for a=1:1000
if(P(a).ort==i)
P(a).ort=P(i).next;
P(a).out=M*(fix(sqrt((P(P(i).next).x-P(a).x)^2+(P(P(i).next).y-P(a).y)^2+(P(P(i).next).z-P(a).z)^2)))^2;%距离公式,改变传输功率为至总簇头的传输能量
end
end
Q=P(P(i).next).ort;
P(P(i).next).out=M*(fix(sqrt((P(P(i).next).x-P(Q).x)^2+(P(P(i).next).y-P(Q).y)^2+(P(P(i).next).z-P(Q).z)^2)))^2;%距离公式,改变传输功率为至总簇头的传输能量
continue;%因为该簇的头节点变化了所以跳出该簇循环
else%(若簇空了,修改网络结构)
for d=1:1000
if((P(d).level==2)&(P(d).energy>0)&(P(d).ort==i))
W2=head;
N7=fix(sqrt((P(d).x-P(head).x)^2+(P(d).y-P(head).y)^2+(P(d).z-P(head).z)^2));%以该点为中继的节点到根节点的距离
for s=1:1000
if((P(s).level==2)&(P(s).sur==1)&(P(s).energy>0))
N6=fix(sqrt((P(d).x-P(s).x)^2+(P(d).y-P(s).y)^2+(P(d).z-P(s).z)^2));%修改传输功率
if(N6<N7)
N7=N6;
W2=s;
end
end
end
P(d).ort=W2;
P(d).out=M*N7^2;
if(W2==head)
P(d).sur=1;
end
end
end
continue;%结束该簇的后续程序
end%簇空不空
else%当一般功率没有用尽时,则头节点接收
P(head).energy=P(head).energy-(P(i).num+1)*receive;
if(P(head).energy<=0)%当根节点能量用尽时
head=0;%定义从新标示根节点
break;%提前结束本层(高层)循环(for)
else%当根节点的能量也没有用尽时
time=time+1;
account=account+1;
end%当根节点能量没有用尽
end%当外围一层头节点能量没有用尽
end%外围一层节点结束
%外围二层头节点
if((P(i).level==2)&(P(i).sur==2)&(P(i).energy>0))%找出一般性外围二层的节点
P(i).energy=P(i).energy-P(i).out*(P(i).num+1);%发射功率,因为包含子节点的信息所以要用乘
if(P(i).energy<=0)%若功率用尽,则找簇头代替
num=num-1;%总数减少了1
fprintf('头节点%d ',P(i).id);%输出该头节点
P(i).level=0;%作为能量耗尽的标示
if(P(i).next~=0)%空的时候什么也不用做
P(P(i).next).level=2;%改变头节点。不用考虑P(k).next是否存在,因为如果不存在则不会出现头节点能量为零的情况
z=i;%z用于对头节点改造的计序
while(P(z).next~=0)%(内二层循环)用于对头节点的改造
P(P(i).next).num=P(P(i).next).num+1;%邻节点数加1
P(P(z).next).cid=P(i).next;%改变网络中各节点的头节点标识
P(P(z).next).out=M*(fix(sqrt((P(P(z).next).x-P(P(i).next).x)^2+(P(P(z).next).y-P(P(i).next).y)^2+(P(P(z).next).z-P(P(i).next).z)^2)))^2;%距离公式%改变至总簇头的传输能量%修改传输功率
z=P(z).next;%向后爬动
end%完成对各子节点的改造
if(P(i).next~=0)%如果上面的循环运行了,减去纪录自己的一次
P(P(i).next).num=P(P(i).next).num-1;%减去自己的一点
end
%修改路由
P(P(i).next).sur=2;
P(P(i).next).ort=P(i).ort;
continue%结束该点的后续运行
end
else%能量没有用完,使用路由传递
time=time+1;
account=account+(P(i).num+1);
T=P(i).ort;
P(T).energy=P(T).energy-(receive+P(T).out)*(P(i).num+1);
if(P(T).energy<=0)
num=num-1;%总数减少了1
fprintf('头节点%d ',P(T).id);%输出该头节点
P(T).level=0;%作为能量耗尽的标示
if(P(T).next~=0)%若簇不空,
P(P(T).next).level=2;%改变头节点。不用考虑P(k).next是否存在,因为如果不存在则不会出现头节点能量为零的情况
z=T;%z用于对头节点改造的计序
while(P(z).next~=0)%(内二层循环)用于对头节点的改造
P(P(T).next).num=P(P(T).next).num+1;%邻节点数加1
P(P(z).next).cid=P(T).next;%改变网络中各节点的头节点标识
P(P(z).next).out=M*(fix(sqrt((P(P(z).next).x-P(P(T).next).x)^2+(P(P(z).next).y-P(P(T).next).y)^2+(P(P(z).next).z-P(P(T).next).z)^2)))^2;%距离公式%改变至总簇头的传输能量%修改传输功率
z=P(z).next;%向后爬动
end%完成对各子节点的改造
if(P(T).next~=0)%如果上面的循环运行了,减去纪录自己的一次
P(P(T).next).num=P(P(T).next).num-1;%减去自己的一点
end
%修改路由
P(P(T).next).sur=1;
P(P(T).next).ort=head;
%该点代替头节点链表中的位置,因为有后续节点代替所以簇数不会减少
%用后续节点取代原节点作中继节点
for a=1:1000
if(P(a).ort==T)
P(a).ort=P(T).next;
P(a).out=M*(fix(sqrt((P(P(T).next).x-P(a).x)^2+(P(P(T).next).y-P(a).y)^2+(P(P(T).next).z-P(a).z)^2)))^2;%距离公式,改变传输功率为至总簇头的传输能量
end
end
P(P(T).next).out=M*(fix(sqrt((P(P(T).next).x-P(head).x)^2+(P(P(T).next).y-P(head).y)^2+(P(P(T).next).z-P(head).z)^2)))^2;%距离公式,改变传输功率为至总簇头的传输能量
else%(若簇空了,修改网络结构)
for d=1:1000
if((P(d).level==2)&(P(d).energy>0)&(P(d).ort==T))
W2=head;
N7=fix(sqrt((P(d).x-P(head).x)^2+(P(d).y-P(head).y)^2+(P(d).z-P(head).z)^2));%以该点为中继的节点到根节点的距离
for s=1:1000
if((P(s).level==2)&(P(s).sur==1)&(P(s).energy>0))
N6=fix(sqrt((P(d).x-P(s).x)^2+(P(d).y-P(s).y)^2+(P(d).z-P(s).z)^2));%修改传输功率
if(N6<N7)
N7=N6;
W2=s;
end
end
end
P(d).ort=W2;
P(d).out=M*N7^2;
if(W2==head)
P(d).sur=1;
end
end
end
continue;%只要中继节点能量用尽就从来
end%该簇是否空
else%若中继1层节点的能量没有用完
P(head).energy=P(head).energy-(P(i).num+1)*receive;
if(P(head).energy<=0)
head=0;
break;
else
time=time+1;
account=account+(P(i).num+1);
end%根节点能量是否用完
end%中继节点能量是否用完
end%该二层节点的能量是否用完
end%二层节点结束
end%是否调整网络
end%簇头循环
ti(tr)=time;
if(tr==2)
act(tr)=account;
else
act(tr)=account-ac(tr-1);
end
ac(tr)=account;
tr=tr+1;
end%循环
fprintf('\n');
fprintf('网络的生存周期为: %d\n',time);
fprintf('网络的通信总量为: %d\n',account);
b=0;
for a=1:1000
if(P(a).level~=0)
b=b+1;
fprintf('最后的根节点为: %d 坐标为:',P(a).id);
disp([P(a).x P(a).y P(a).z]);
fprintf('\n');
end
end
figure
plot(ti,ac);
xlabel('time');
ylabel('account');
title('通信总量曲线');
figure
plot(ti,act);
xlabel('time');
ylabel('account');
title('通信增量曲线');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -