题目描述
背景
在无线多跳自组织网络环境中,高效地将关键数据从网络的一端传播到整个网络是多跳自组织网络中非常重要的一个,广泛应用于网络控制、公共数据广播、时间同步等,该数据广播协议一般称为数据分发协议。
挑战
分发协议本质是一种广播协议,目的是让环境中所有的节点都收到消息。但分发协议在无线多跳网络中存在多方面的权衡与设计挑战,例如:
- 应实现整体节能,分发协议应尽量减少无线发送次数,延长网络的工作寿命;
- 应实现个体节能,应减少特定节点的发送次数,当节点失效时,可能会影响整个网络的工作;
- 尽量减少网络跳数,网络跳数过多,传输成功率下降,传输延迟上升。
题目
- 在MATLAB或Python中模拟 N ( N > 100 ) N(N>100) N(N>100)多跳传感网络应该是一个节点 N N N随机分布节点 100 m ? 100 m 100m*100m 100m?100m的正方形 2 2 2维平面。每个节点的通信半径r符合正态分布 r ~ N ( μ , σ 2 ) r\sim N(\mu,\sigma ^2) r~N(μ,σ2), 0 < μ < 10 , σ < 5 0<\mu<10,\sigma<5 0<μ<10,σ<5;进一步,假设当两个节点距离为d时,通信成功率 t = 1 − d 2 r 1 r 2 t=1-\frac{d^2}{r_1r_2} t=1−r1r2d2。每个节点一些基本物理信息: l d ld ld,总电量,单次发射耗电量;
- 设计自己的数据分发协议:
- 基本要求:在不考虑电量的情况下,可实现从任意选定的一点将信息分发至全网;
- 进阶要求:在考虑电量的情况下,实现从任意选定的一点将信息分发至全网;
- 高阶要求:在考虑电量的情况下,提出一种最优的数据分发策略。
- 可视化多跳网络,并通过简单的过程动画展示分发过程。
分析
每个节点都有不同的通信半径 r r r,并且 r > 0 r>0 r>0;通信成功率 t t t的范围为 0 < t < 1 0<t<1 0<t<1,所以
t = { 0 , 1 − d 2 r 1 r 2 ≤ 0 1 − d 2 r 1 r 2 , 0 < 1 − d 2 r 1 r 2 ≤ 1 t=\left\{ \begin{array}{r} 0 & , &1-\frac{d^2}{r_1r_2}\leq0 \\ 1-\frac{d^2}{r_1r_2}& , &0<1-\frac{d^2}{r_1r_2}\leq1 \end{array}\right. t={ 01−r1r2d2,,1−r1r2d2≤00<1−r1r2d2≤1
使用广度优先搜索(宽度优先搜索),就需要用一个队列来储存当前信息所到位置。
基础要求
代码
文件名:dessimation.py
import numpy as np
import queue
import matplotlib.pyplot as plt
import matplotlib.animation as animation
N = 500
mu = np.random.rand()*10
sigma = np.random.rand()*5
r = np.random.randn(N)*sigma+mu
for i in range(N):
while r[i] <= 0:
r[i] = np.random.randn()*sigma+mu
node_pos = np.random.rand(N, 2)*100
T = np.zeros((N, N))
count = {
}
mark = {
}
for i in range(N):
count[i] = 0
mark[i] = False
flag = True
while(flag):
for i in range(N):
for j in range(i+1, N):
d = np.linalg.norm(
node_pos[i]-node_pos[j])
t = 1-(d*d)/(r[i]*r[j])
if t > 0:
T[i][j] = t
T[j][i] = t
flag = False
for i in range(N):
if np.max(T[i]) == 0:
mu = np.random.rand()*10
sigma = np.random.rand()*5
r = np.random.randn(N)*sigma+mu
for i in range(N):
while r[i] <= 0:
r[i] = np.random.randn()*sigma+mu
node_pos = np.random.rand(N, 2)*100
T = np.zeros((N, N))
flag = True
break
q = queue.Queue()
begin = np.random.randint(N)
q.put(begin)
mark[begin] = True
fig, ax = plt.subplots()
rposx, rposy, bposx, bposy = [], [], [], []
line1, = ax.plot(bposx, bposy, '.b')
line2, = ax.plot(rposx, rposy, '.r')
def init():
ax.set_xlim(-1, 101)
ax.set_ylim(-1, 101)
return line1, line2
def update(frame):
rposx.clear()
rposy.clear()
bposx.clear()
bposy.clear()
for i in range(N):
if mark[i]:
rposx.append(node_pos[i][0])
rposy.append(node_pos[i][1])
else:
bposx.append(node_pos[i][0])
bposy.append(node_pos[i][1])
if not q.empty():
flag = False
now = q.get()
for i in range(N):
if T[now][i] != 0 and not mark[i]:
flag = True
if np.random.rand() < T[now][i]:
mark[i] = True
q.put(i)
if flag:
count[now] += 1
else:
flag = False
maxpossibility = 0
for i in range(N):
if not mark[i]:
flag = True
for j in range(N):
if mark[j] and T[i][j] > maxpossibility:
maxpossibility = T[i][j]
begin = j
if flag:
q.put(begin)
else:
anim.event_source.stop()
line1.set_data(bposx, bposy)
line2.set_data(rposx, rposy)
return line1, line2
anim = animation.FuncAnimation(
fig=fig, func=update, frames=2*N, init_func=init, interval=20, blit=False)
plt.show()
代码分析与说明
不考虑电量的情况下,直接传输即可。
N = 500
mu = np.random.rand()*10
sigma = np.random.rand()*5
r = np.random.randn(N)*sigma+mu
for i in range(N):
while r[i] <= 0:
r[i] = np.random.randn()*sigma+mu
node_pos = np.random.rand(N, 2)*100
T = np.zeros((N, N))
count = {
}
mark = {
}
for i in range(N):
count[i] = 0
mark[i] = False
总共有 N = 500 N=500 N=500个节点;随机生成 0 < μ < 10 0<\mu<10 0<μ<10和 0 < σ < 5 0<\sigma<5 0<σ<5;之后生成一组初始的通信半径 r r r,将 r r r调整为 r > 0 r>0 r>0;随机生成节点位置 n o d e _ p o s node\_pos node_pos;为通信成功率 T T T分配空间, T T T也可以看做一个邻接矩阵;用 c o u n t count count记录每一个节点发送次数;用 m a r k mark mark记录某一个节点是否已经收到信息。
flag = True
while(flag):
f l a g flag flag在这里是为了保证每个节点可达,有不可达的节点就重新计算 T T T,初始值设置为 T r u e True True。
这段代码的前半部分作用是计算矩阵 T T T:
for i in range(N):
for j in range(i+1, N):
d = np.linalg.norm(node_pos[i]-node_pos[j])
t = 1-(d*d)/(r[i]*r[j])
if t > 0:
T[i][j] = t
T[j][i] = t
因为图是无向图,所以 T T T是对称矩阵; d d d是节点之间的距离, t t t为两个节点之间的通信成功率。
但这个图要保证每个节点可达,所有需要进行一系列的判断:
flag = False
for i in range(N):
if np.max(T[i]) == 0:
mu = np.random.rand()*10
sigma = np.random.rand()*5
r = np.random.randn(N)*sigma+mu
for i in range(N):
while r[i] <= 0:
r[i] = np.random.randn()*sigma+mu
node_pos = np.random.rand(N, 2)*100
T = np.zeros((N, N)