import tkinter as tk
import random
import math
import sys
# 设置最大递归次数
sys.setrecursionlimit(2000)
# 设置一个常量代表传感器固定半径
SENOR_RADIUS = 6
class Window:
def __init__(self, master):
self.root = master
self.createpage()
self.run()
'''创建界面'''
def createpage(self):
self.root.geometry('1210x710')
# 设置窗口是否可以变化长/宽,False不可变,True可变,默认为True
self.root.resizable(width=False, height=False)
#设置模块1 参数输入 的各个部件在窗口的相对位置横坐标
flame1_text_x = 130
#设置外围框,让界面更好看
tk.LabelFrame(self.root, text='|参数|', fg='black', padx=10, pady=10,font='Verdana 10 bold').place(x=10, y=10, height=250, width=290)
# ZigBee网络的nwkMaxChildren (Cm)
tk.Label(self.root, text='最大子节点数(Cm):', fg='black').place(x = 15, y = 35)
self.nwkMaxChildren_text = tk.StringVar(value="5")
self.nwkMaxChildren = tk.Entry(self.root, textvariable=self.nwkMaxChildren_text)
self.nwkMaxChildren.place(x = flame1_text_x , y = 35)
# nwkMaxRouters (Rm)
tk.Label(self.root, text='ZR节点数(Rm):', fg='black').place(x = 15, y = 65)
self.nwkMaxRouters_text = tk.StringVar(value="3")
self.nwkMaxRouters = tk.Entry(self.root, textvariable=self.nwkMaxRouters_text)
self.nwkMaxRouters.place(x = flame1_text_x , y = 65)
# newMaxDepth (Lm)
tk.Label(self.root, text='网络最大深度(Lm):', fg='black').place(x=15, y=95)
self.newMaxDepth_text = tk.StringVar(value="5")
self.newMaxDepth = tk.Entry(self.root, textvariable=self.newMaxDepth_text)
self.newMaxDepth.place(x = flame1_text_x , y = 95)
# 协调器(coordinator)
tk.Label(self.root, text='协调器(ZC):', fg='black').place(x=15, y=125)
self.coordinator_text = tk.StringVar(value="1")#由于ZC的值固定为 1,所以我们也要设置ZC的值为 1
self.coordinator = tk.Entry(self.root, textvariable=self.coordinator_text, state = 'readonly')
# state Entry 组件可以设置的状态:"normal","disabled" 或 "readonly"
#(注意,它跟 "disabled" 相似,但它支持选中和拷贝,只是不能修改,而 "disabled" 是完全禁止)
self.coordinator.place(x = flame1_text_x , y = 125)
# 路由器(Router)
tk.Label(self.root, text='路由器(ZR):', fg='black').place(x=15, y=155)
self.router_text = tk.StringVar(value="15")
self.router = tk.Entry(self.root, textvariable=self.router_text)
self.router.place(x = flame1_text_x , y = 155)
# 普通节点(Device)
tk.Label(self.root, text='终端节点(ZED):', fg='black').place(x=15, y=185)
self.device_text = tk.StringVar(value="15")
self.device = tk.Entry(self.root, textvariable=self.device_text)
self.device.place(x = flame1_text_x , y = 185)
#传感器通讯距离(distance_get)
tk.Label(self.root, text='传感器通讯距离:', fg='black').place(x=15, y=215)
self.distance_get_text = tk.StringVar(value="300")
self.distance_get = tk.Entry(self.root, textvariable=self.distance_get_text)
self.distance_get.place(x = flame1_text_x , y = 215)
# 创建按钮
tk.Button(self.root, text='ZigBee传感器布置', command=self.Pictue_Create).place(x=50, y=280,height=50, width=200)
#设置模块2 路径查找 的各个部件在窗口的相对位置纵坐标
flame2_text_y = 400
#创建外包框
tk.LabelFrame(self.root, text='|路径查找|', fg='black', padx=10, pady=10,font='Verdana 10 bold').place(x=10, y=flame2_text_y, height=120, width=290)
#source_node_address 源节点地址
tk.Label(self.root, text='源节点地址:', fg='black').place(x=15, y=flame2_text_y + 30)
self.source_node_address_text = tk.StringVar()
self.source_node_address = tk.Entry(self.root, textvariable=self.source_node_address_text)
self.source_node_address.place(x = flame1_text_x , y = flame2_text_y + 30)
#destination_node_address 目的节点地址
tk.Label(self.root, text='目的节点地址:', fg='black').place(x=15, y=flame2_text_y + 70)
self.destination_node_address_text = tk.StringVar()
self.destination_node_address = tk.Entry(self.root, textvariable=self.destination_node_address_text)
self.destination_node_address.place(x = flame1_text_x , y = flame2_text_y + 70)
# 创建按钮
tk.Button(self.root, text='显示路径', command = self.Path_Lookup_ready ).place(x=50, y=flame2_text_y + 140,height=50, width=200)
# 创建画布
self.cv = tk.Canvas(self.root, bg='white', width=900, height=700)
self.cv.place(x=300)
'''清空内容'''
def Wipe_Data(self):
# 清空文本框和画图框内的内容
self.cv.delete(tk.ALL)
'''创建ZC中心传感器'''
def Gathering_Point_Create(self):
self.sensor_zc[0][0] = self.gathering_point_center_x
self.sensor_zc[0][1] = self.gathering_point_center_y
#设置标志数,表示这个传感器是ZC
self.sensor_zc[0][9] = 0
self.cv.create_oval((self.gathering_point_center_x - SENOR_RADIUS, self.gathering_point_center_y - SENOR_RADIUS,
self.gathering_point_center_x + SENOR_RADIUS, self.gathering_point_center_y + SENOR_RADIUS),
outline='black',
fill='red'
)
#设置ZC的初始地址和计算出C(skip)的值
self.sensor_zc[0][7] = 6
if(self.Rm == 1):
Cskip = 1 + self.Cm * (self.Lm - self.sensor_zc[0][5] - 1)
else:
Cskip = (1 + self.Cm - self.Rm - self.Cm * math.pow(self.Rm,(self.Lm - self.sensor_zc[0][5] - 1))) / (1 - self.Rm)
self.sensor_zc[0][8] = int(Cskip)
address = str(self.sensor_zc[0][7])
C_skip = str(self.sensor_zc[0][8])
text_string = address + " C:" + C_skip
#创建字体
self.cv.create_text(self.gathering_point_center_x, self.gathering_point_center_y + self.canvas_text_y, text = 'ZC-' + text_string)
'''创建ZR中心传感器'''
def ZR_Sensor_Create(self):
for num_sensor_zr_temp in range(0, self.Zr):
circle_center_x = random.randint(15, 885)
circle_center_y = random.randint(15, 685)
# 将每次随机生成的传感器的坐标 放入列表
self.sensor_zr[num_sensor_zr_temp][0] = circle_center_x
self.sensor_zr[num_sensor_zr_temp][1] = circle_center_y
#设置标志数,表示这个传感器是ZR
self.sensor_zr[num_sensor_zr_temp][9] = 1
self.cv.create_rectangle((circle_center_x - 5, circle_center_y - 5,
circle_center_x + 10, circle_center_y + 5),
outline='blue',
fill='blue'
)
'''创建ZED中心传感器'''
def ZED_Sensor_Create(self):
for num_sensor_zr_temp in range(0, self.Zed):
circle_center_x = random.randint(15, 885)
circle_center_y = random.randint(15, 685)
# 将每次随机生成的传感器的坐标 放入列表
self.sensor_zed[num_sensor_zr_temp][0] = circle_center_x
self.sensor_zed[num_sensor_zr_temp][1] = circle_center_y
#设置标志数,表示这个传感器是ZED
self.sensor_zed[num_sensor_zr_temp][7] = 2
self.cv.create_oval((circle_center_x - SENOR_RADIUS, circle_center_y - SENOR_RADIUS,
circle_center_x + SENOR_RADIUS, circle_center_y + SENOR_RADIUS),
outline='purple',
fill='purple'
)
'''在canvas上画图'''
def Pictue_Create(self):
#将打印在画布上的信息格式化
self.canvas_text_y = 12
# 清空内容
self.Wipe_Data()
# 获取输入框中的内容
self.Cm = self.nwkMaxChildren.get()
self.Rm = self.nwkMaxRouters.get()
self.Lm = self.newMaxDepth.get()
self.Zc = self.coordinator.get()
self.Zr = self.router.get()
self.Zed = self.device.get()
self.distance = self.distance_get.get()
# 打印获取的内容
#将获取的数值转成int
self.Cm = int(self.Cm)
self.Rm = int(self.Rm)
self.Lm = int(self.Lm)
self.Zc = int(self.Zc)
self.Zr = int(self.Zr)
self.Zed = int(self.Zed)
self.distance = int(self.distance)
# 创建存储ZC(协调器)的二维列表
self.sensor_zc = [[0 for i in range(10)]]
# 创建存储ZR(路由器)的二维列表
self.sensor_zr = [[0 for i in range(10)]for j in range(self.Zr)]
# 创建存储ZED普通节点(Device)的二维列表
self.sensor_zed = [[0 for i in range(8)]for j in range(self.Zed)]
# 确定Zc的坐标&
self.gathering_point_center_x = 450
self.gathering_point_center_y = 350
# 生成通讯中心(ZC)
self.Gathering_Point_Create()
# 创建临时数组储存已经进行连接的ZR、ZED传感器坐标等等信息
self.sensor_zr_temp = []
self.sensor_zed_temp = []
#创建ZR、ZED传感器
self.ZR_Sensor_Create()
self.ZED_Sensor_Create()
#打印生成的两个数组
'''
print('==========================================================')
print("这是连接的ZR保存数值的列表:",self.sensor_zr)
print("这是连接的ZED保存数值的列表:",self.sensor_zed)
print('==========================================================')
'''
#判断每个传感器上的点的连接
self.Tree_Topology_Establishment()
#打印生成的两个数组
'''
print('----------------------------------------------------------')
print("这是连接的ZC保存所有数值的列表:",self.sensor_zc)
print("这是连接的ZR保存所有数值的列表:",self.sensor_zr_temp)
print("这是连接的ZR保存没有连接的列表:",self.sensor_zr)
print("这是连接的ZED保存的列表:",self.sensor_zed_temp)
print("这是连接的ZED保存没有连接的列表:",self.sensor_zed)
print('----------------------------------------------------------')
'''
'''计算ZC与旁边传感器ZC和ZED的关系,符合条件的进行连接'''
def Cal_ZC_Connect(self):
#把ZR旁边的ZED结点连接起来R
for num_sensor_zr in range(0, self.Zr):
temp_x = self.gathering_point_center_x - self.sensor_zr[num_sensor_zr][0]
temp_y = self.gathering_point_center_y - self.sensor_zr[num_sensor_zr][1]
temp_x = temp_x * temp_x
temp_y = temp_y * temp_y
temp_distance = math.sqrt(temp_x + temp_y)
#两点的距离小于规定的传感器通讯距离
if(temp_distance <= self.distance):
if(self.sensor_zc[0][3] < self.Cm):
if(self.sensor_zc[0][4] < self.Rm):
self.sensor_zc[0][4] = self.sensor_zc[0][4] + 1
self.sensor_zc[0][3] = self.sensor_zc[0][3] + 1
self.sensor_zr[num_sensor_zr][2] = 1
self.sensor_zr[num_sensor_zr][5] = self.sensor_zc[0][5] + 1
#显示子结点在父节点中的编号
self.sensor_zr[num_sensor_zr][6] = self.sensor_zc[0][4]
#地址的分配
if(self.Rm == 1):
Cskip = 1 + self.Cm * (self.Lm - self.sensor_zc[0][5] - 1)
else:
Cskip = (1 + self.Cm - self.Rm - self.Cm * math.pow(self.Rm,(self.Lm - self.sensor_zc[0][5] - 1))) / (1 - self.Rm)
#计算下一个子结点的地址
self.sensor_zr[num_sensor_zr][7] = self.sensor_zc[0][7] + 1 + self.sensor_zc[0][8] * (self.sensor_zc[0][4] - 1)
#计算下一个子结点的Cskip并存入数组
Cskip_child = (1 + self.Cm - self.Rm - self.Cm * math.pow(self.Rm,(self.Lm - self.sensor_zr[num_sensor_zr][5] - 1))) / (1 - self.Rm)
self.sensor_zr[num_sensor_zr][8] = int(Cskip_child)
#把地址和其他数据显示在传感器下面
address = str(self.sensor_zr[num_sensor_zr][7])
C_skip = str(self.sensor_zr[num_sensor_zr][8])
Num = str(self.sensor_zr[num_sensor_zr][6])
text_string = 'A:' + address# + ' C:' + C_skip + ' N:' + Num
self.cv.create_text(self.sensor_zr[num_sensor_zr][0], self.sensor_zr[num_sensor_zr][1] + self.canvas_text_y, text='ZR-' + text_string)
#对两个传感器进行连接
self.cv.create_line(self.gathering_point_center_x, self.gathering_point_center_y,
self.sensor_zr[num_sensor_zr][0], self.sensor_zr[num_sensor_zr][1],
fill='orange')
#创建临时数组存储已经连接的传感器的数据
temp_arr = self.sensor_zr[num_sensor_zr][::]
self.sensor_zr_temp.append(temp_arr)
#把ZC旁边的ZED结点连接起来
for num_sensor_zed in range(0, self.Zed):
temp_x = self.gathering_point_center_x - self.sensor_zed[num_sensor_zed][0]
temp_y = self.gathering_point_center_y - self.sensor_zed[num_sensor_zed][1]
temp_x = temp_x * temp_x
temp_y = temp_y * temp_y
temp_distance = math.sqrt(temp_x + temp_y)
#两点的距离小于规定的传感器通讯距离
if(temp_distance <= self.distance):
if((self.Cm - self.sensor_zc[0][3]) > 0):
if(self.sensor_zed[num_sensor_zed][2] == 0):
self.sensor_zc[0][3] = self.sensor_zc[0][3] + 1
self.sensor_zed[num_sensor_zed][2] = 1
self.sensor_zed[num_sensor_zed][3] = self.sensor_zc[0][5] + 1
#显示子结点在父节点中的编号
self.sensor_zed[num_sensor_zed][4] = self.sensor_zc[0][3] - self.sensor_zc[0][4]
#地址的分配
if(self.Rm == 1):
Cskip = 1 + self.Cm * (self.Lm - self.sensor_zc[0][5] - 1)
else:
Cskip = (1 + self.Cm - self.Rm - self.Cm * math.pow(self.Rm,(self.Lm - self.sensor_zc[0][5] - 1))) / (1 - self.Rm)
#计算ZED的address
self.sensor_zed[num_sensor_zed][5] = self.sensor_zc[0][7] + self.sensor_zc[0][8] * self.Rm + self.sensor_zc[0][3] - self.sensor_zc[0][4]
#把地址显示在传感器下面
address = str(self.sensor_zed[num_sensor_zed][5])
Num = str(self.sensor_zed[num_sensor_zed][4])
text_string = 'A:' + address# + ' N:' + Num
self.cv.create_text(self.sensor_zed[num_sensor_zed][0], self.sensor_zed[num_sensor_zed][1] + self.canvas_text_y, text='ZED-' + text_string)
#对两个传感器之间连线
self.cv.create_line(self.gathering_point_center_x, self.gathering_point_center_y,
self.sensor_zed[num_sensor_zed][0], self.sensor_zed[num_sensor_zed][1],
fill='orange')
#创建临时数组存储已经连接的传感器的数据
temp_arr = self.sensor_zed[num_sensor_zed][::]
self.sensor_zed_temp.append(temp_arr)
'''计算ZR与旁边传感器ZR的关系,符合条件的进行连接'''
def Cal_Con_ZRtoZR_Recursion(self):
# 设置标志数
self.i = 0
# 对列表求差集
difference_set = list(set([tuple(t) for t in self.sensor_zr]).difference(set([tuple(t) for t in self.sensor_zr_temp])))
self.sensor_zr.clear()
# 求差集以后 会变成列表包元组 需要转化成列表包列表
for num_sensor_zr_temp in range(0, (len(difference_set))):
temp_arr_a = [ difference_set[num_sensor_zr_temp][0],
difference_set[num_sensor_zr_temp][1],
difference_set[num_sensor_zr_temp][2],
difference_set[num_sensor_zr_temp][3],
difference_set[num_sensor_zr_temp][4],
difference_set[num_sensor_zr_temp][5],
difference_set[num_sensor_zr_temp][6],
difference_set[num_sensor_zr_temp][7],
difference_set[num_sensor_zr_temp][8],
difference_set[num_sensor_zr_temp][9]]
self.sensor_zr.append(temp_arr_a)
'''
print('----------------------------------------------------------')
print("这是sensor_zr列表:",self.sensor_zr,"它的长度为",len(self.sensor_zr))
print("这是sensor_zr_temp列表:",self.sensor_zr_temp,"它的长度为",len(self.sensor_zr_temp))
print('----------------------------------------------------------')
'''
# 对sensor_zr_temp 和 sensor_zr两个列表遍历
'''
外层循环:对符合要求并已经进行连接的传感器坐标列表遍历
'''
for num_sensor_zr_temp in range(0, len(self.sensor_zr_temp)):
#sensor_zr_temp: 储存符合要求并已经进行连接的传感器坐标
'''
内层循环:对没有遍历或者不符合要求的传感器坐标遍历
'''
for num_sensor_zr in range(0, len(self.sensor_zr)):
#sensor_zr: 储存没有遍历或者不符合要求的传感器坐标
temp_x = self.sensor_zr[num_sensor_zr][0] - self.sensor_zr_temp[num_sensor_zr_temp][0]
temp_y = self.sensor_zr[num_sensor_zr][1] - self.sensor_zr_temp[num_sensor_zr_temp][1]
temp_x = temp_x * temp_x
temp_y = temp_y * temp_y
temp_distance = math.sqrt(temp_x + temp_y)
#判断每个点与剩余未连接点的连接情况
if(temp_distance <= self.distance):
if(self.sensor_zr_temp[num_sensor_zr_temp][3] < self.Cm):
if(self.sensor_zr_temp[num_sensor_zr_temp][4] < self.Rm):
if(self.sensor_zr_temp[num_sensor_zr_temp][5] < self.Lm):
if(self.sensor_zr[num_sensor_zr][2] == 0):
self.sensor_zr_temp[num_sensor_zr_temp][4] = self.sensor_zr_temp[num_sensor_zr_temp][4] + 1
self.sensor_zr_temp[num_sensor_zr_temp][3] = self.sensor_zr_temp[num_sensor_zr_temp][3] + 1
self.sensor_zr[num_sensor_zr][2] = 1
self.sensor_zr[num_sensor_zr][5] = self.sensor_zr_temp[num_sensor_zr_temp][5] + 1
#显示子结点在父节点中的编号
self.sensor_zr[num_sensor_zr][6] = self.sensor_zr_temp[num_sensor_zr_temp][4]
#地址的分配
if(self.Rm == 1):
Cskip = 1 + self.Cm * (self.Lm - self.sensor_zr_temp[num_sensor_zr_temp][5] - 1)
else:
Cskip = (1 + self.Cm - self.Rm - self.Cm * math.pow(self.Rm,(self.Lm - self.sensor_zr_temp[num_sensor_zr_temp][5] - 1))) / (1 - self.Rm)
self.sensor_zr[num_sensor_zr][7] = self.sensor_zr_temp[num_sensor_zr_temp][7] + 1 + self.sensor_zr_temp[num_sensor_zr_temp][8] * (self.sensor_zr_temp[num_sensor_zr_temp][4] - 1)
Cskip_child = (1 + self.Cm - self.Rm - self.Cm * math.pow(self.Rm,(self.Lm - self.sensor_zr[num_sensor_zr][5] - 1))) / (1 - self.Rm)
self.sensor_zr[num_sensor_zr][8] = int(Cskip_child)
#把地址显示在传感器下面
address = str(self.sensor_zr[num_sensor_zr][7])
C_skip = str(self.sensor_zr[num_sensor_zr][8])
Num = str(self.sensor_zr[num_sensor_zr][6])
text_string = 'A:' + address# + ' C:' + C_skip + ' N:' + Num
self.cv.create_text(self.sensor_zr[num_sensor_zr][0], self.sensor_zr[num_sensor_zr][1] + self.canvas_text_y, text='ZR-' + text_string)
#对两个传感器连线
self.cv.create_line(self.sensor_zr[num_sensor_zr][0], self.sensor_zr[num_sensor_zr][1],
self.sensor_zr_temp[num_sensor_zr_temp][0], self.sensor_zr_temp[num_sensor_zr_temp][1],
fill='orange')
#创建临时数组存储已经连接的传感器的数据
temp_arr = self.sensor_zr[num_sensor_zr][::]
self.sensor_zr_temp.append(temp_arr)
# 当判定有点相连的 令标志数等于1
self.i = 1
'''这段代码是取还没有进行连接的传感器坐标数据'''
reList = list(set([tuple(t) for t in self.sensor_zr_temp]))
self.sensor_zr_temp.clear()
# 去重以后 会变成列表包元组 需要转化成列表包列表
for num_sensor_zr_temp in range(0, (len(reList))):
temp_arr_a = [reList[num_sensor_zr_temp][0],
reList[num_sensor_zr_temp][1],
reList[num_sensor_zr_temp][2],
reList[num_sensor_zr_temp][3],
reList[num_sensor_zr_temp][4],
reList[num_sensor_zr_temp][5],
reList[num_sensor_zr_temp][6],
reList[num_sensor_zr_temp][7],
reList[num_sensor_zr_temp][8],
reList[num_sensor_zr_temp][9]]
self.sensor_zr_temp.append(temp_arr_a)
if(self.i == 0):
# 当没有点可以遍历的时候 退出递归
self.over()
else:
self.Cal_Con_ZRtoZR_Recursion()
def Cal_Con_ZRtoZED_Recursion(self):
#设置标志数
self.i = 0
# 对列表求差集
difference_set = list(set([tuple(t) for t in self.sensor_zed]).difference(set([tuple(t) for t in self.sensor_zed_temp])))
self.sensor_zed.clear()
# 求差集以后 会变成列表包元组 需要转化成列表包列表
for num_sensor_zed_a in range(0, (len(difference_set))):
temp_arr_a = [ difference_set[num_sensor_zed_a][0],
difference_set[num_sensor_zed_a][1],
difference_set[num_sensor_zed_a][2],
difference_set[num_sensor_zed_a][3],
difference_set[num_sensor_zed_a][4],
difference_set[num_sensor_zed_a][5],
difference_set[num_sensor_zed_a][6],
difference_set[num_sensor_zed_a][7]]
self.sensor_zed.append(temp_arr_a)
'''
外层循环:对符合要求并已经进行连接的传感器坐标列表遍历
'''
for num_sensor_zr_temp in range(0, len(self.sensor_zr_temp)):
'''
内层循环:对没有遍历或者不符合要求的传感器坐标遍历
'''
for num_sensor_zed in range(0, len(self.sensor_zed)):
#sensor_zr: 储存没有遍历或者不符合要求的传感器坐标
#sensor_zr_temp: 储存符合要求并已经进行连接的传感器坐标
temp_x = self.sensor_zed[num_sensor_zed][0] - self.sensor_zr_temp[num_sensor_zr_temp][0]
temp_y = self.sensor_zed[num_sensor_zed][1] - self.sensor_zr_temp[num_sensor_zr_temp][1]
temp_x = temp_x * temp_x
temp_y = temp_y * temp_y
temp_distance = math.sqrt(temp_x + temp_y)
#判断每个点与剩余未连接点的连接情况
if(temp_distance <= self.distance):
if((self.Cm - self.sensor_zr_temp[num_sensor_zr_temp][3]) > 0):
if(self.sensor_zed[num_sensor_zed][2] == 0):
if(self.sensor_zr_temp[num_sensor_zr_temp][5] < self.Lm):
self.sensor_zr_temp[num_sensor_zr_temp][3] = self.sensor_zr_temp[num_sensor_zr_temp][3] + 1
self.sensor_zed[num_sensor_zed][2] = 1
self.sensor_zed[num_sensor_zed][3] = self.sensor_zr_temp[num_sensor_zr_temp][5] + 1
self.sensor_zed[num_sensor_zed][4] = self.sensor_zr_temp[num_sensor_zr_temp][3] - self.sensor_zr_temp[num_sensor_zr_temp][4]
#地址的分配
if(self.Rm == 1):
Cskip = 1 + self.Cm * (self.Lm - self.sensor_zr_temp[num_sensor_zr_temp][5] - 1)
else:
Cskip = (1 + self.Cm - self.Rm - self.Cm * math.pow(self.Rm,(self.Lm - self.sensor_zr_temp[num_sensor_zr_temp][5] - 1))) / (1 - self.Rm)
#计算ZED的address
self.sensor_zed[num_sensor_zed][5] = self.sensor_zr_temp[num_sensor_zr_temp][7] + self.sensor_zr_temp[num_sensor_zr_temp][8] * self.Rm + self.sensor_zr_temp[num_sensor_zr_temp][3] - self.sensor_zr_temp[num_sensor_zr_temp][4]
#把地址显示在传感器下面
address = str(self.sensor_zed[num_sensor_zed][5])
Num = str(self.sensor_zed[num_sensor_zed][4])
text_string = 'A:' + address# + ' N:' + Num
self.cv.create_text(self.sensor_zed[num_sensor_zed][0], self.sensor_zed[num_sensor_zed][1] + self.canvas_text_y, text='ZED-' + text_string)
#对两个传感器进行连线
self.cv.create_line(self.sensor_zed[num_sensor_zed][0], self.sensor_zed[num_sensor_zed][1],
self.sensor_zr_temp[num_sensor_zr_temp][0], self.sensor_zr_temp[num_sensor_zr_temp][1],
fill='orange')
#创建临时数组存储已经连接的传感器的数据
temp_arr = self.sensor_zed[num_sensor_zed][::]
self.sensor_zed_temp.append(temp_arr)
# 当判定有点相连的 令标志数等于1
self.i = 1
'''这段代码是取还没有进行连接的传感器坐标数据'''
reList = list(set([tuple(t) for t in self.sensor_zed_temp]))
self.sensor_zed_temp.clear()
# 去重以后 会变成列表包元组 需要转化成列表包列表
for num_sensor_zed_temp in range(0, (len(reList))):
temp_arr_a = [ reList[num_sensor_zed_temp][0],
reList[num_sensor_zed_temp][1],
reList[num_sensor_zed_temp][2],
reList[num_sensor_zed_temp][3],
reList[num_sensor_zed_temp][4],
reList[num_sensor_zed_temp][5],
reList[num_sensor_zed_temp][6],
reList[num_sensor_zed_temp][7]]
self.sensor_zed_temp.append(temp_arr_a)
if(self.i == 0):
# 当没有点可以遍历的时候 退出递归
self.over()
else:
self.Cal_Con_ZRtoZED_Recursion()
'''构建ZigBee树状图'''
def Tree_Topology_Establishment(self):
#判断ZC和ZR、ZED是否可以进行连接,并对其分配地址
self.Cal_ZC_Connect()
#计算 ZR 和 ZR 的连接情况,并对其分配地址
self.Cal_Con_ZRtoZR_Recursion()
#计算 ZR 和 ZED 的连接情况,并对其分配地址
self.Cal_Con_ZRtoZED_Recursion()
'''路径查找'''
def Path_Lookup_ready(self):
#读取数据
self.SNA = self.source_node_address.get()
self.DNA = self.destination_node_address.get()
self.SNA = int(self.SNA)
self.DNA = int(self.DNA)
# 创建存储起始结点信息的二维列表
self.SNA_list = [0 for i in range(10)]
# 创建存储目的结点信息的二维列表
self.DNA_list = [0 for i in range(10)]
#设置标志数,标志是否查找到结点地址
Sign_SNA = 0
Sign_DNA = 0
#在ZC ZR ZED中找SNA
while(1):
if(self.sensor_zc[0][7] == self.SNA):
#print('起始节点在ZC组中')
Sign_SNA = 1
self.SNA_list = self.sensor_zc[0][::]
break
for num_sensor_zr_temp in range(0, len(self.sensor_zr_temp)):
if(self.sensor_zr_temp[num_sensor_zr_temp][7] == self.SNA):
#print('起始节点在ZR组中')
Sign_SNA = 1
self.SNA_list = self.sensor_zr_temp[num_sensor_zr_temp][::]
break
if(Sign_SNA != 1):
for num_sensor_zed_temp in range(0,len(self.sensor_zed_temp)):
if(self.sensor_zed_temp[num_sensor_zed_temp][5] == self.SNA):
#print('起始节点在ZED组中')
Sign_SNA = 1
self.SNA_list[0] = self.sensor_zed_temp[num_sensor_zed_temp][0]
self.SNA_list[1] = self.sensor_zed_temp[num_sensor_zed_temp][1]
self.SNA_list[2] = self.sensor_zed_temp[num_sensor_zed_temp][2]
self.SNA_list[5] = self.sensor_zed_temp[num_sensor_zed_temp][3]
self.SNA_list[6] = self.sensor_zed_temp[num_sensor_zed_temp][4]
self.SNA_list[7] = self.sensor_zed_temp[num_sensor_zed_temp][5]
self.SNA_list[8] = self.sensor_zed_temp[num_sensor_zed_temp][6]
self.SNA_list[9] = self.sensor_zed_temp[num_sensor_zed_temp][7]
break
break
# 输出SNA_list)
# print(self.SNA_list)
# 在ZC ZR ZED中找DNA
while(1):
if(self.sensor_zc[0][7] == self.DNA):
#print('目的节点在ZC组中')
Sign_DNA = 1
self.DNA_list = self.sensor_zc[0][::]
break
for num_sensor_zr_temp in range(0, len(self.sensor_zr_temp)):
if(self.sensor_zr_temp[num_sensor_zr_temp][7] == self.DNA):
#print('目的节点在ZR组中')
Sign_DNA = 1
self.DNA_list = self.sensor_zr_temp[num_sensor_zr_temp][::]
break
if(Sign_DNA != 1):
for num_sensor_zed_temp in range(0,len(self.sensor_zed_temp)):
if(self.sensor_zed_temp[num_sensor_zed_temp][5] == self.DNA):
#print('目的节点在ZED组中')
Sign_DNA = 1
self.DNA_list[0] = self.sensor_zed_temp[num_sensor_zed_temp][0]
self.DNA_list[1] = self.sensor_zed_temp[num_sensor_zed_temp][1]
self.DNA_list[2] = self.sensor_zed_temp[num_sensor_zed_temp][2]
self.DNA_list[5] = self.sensor_zed_temp[num_sensor_zed_temp][3]
self.DNA_list[6] = self.sensor_zed_temp[num_sensor_zed_temp][4]
self.DNA_list[7] = self.sensor_zed_temp[num_sensor_zed_temp][5]
self.DNA_list[8] = self.sensor_zed_temp[num_sensor_zed_temp][6]
self.DNA_list[9] = self.sensor_zed_temp[num_sensor_zed_temp][7]
break
break
# 输出DNA_list
# print(self.DNA_list)
if(Sign_DNA == 0) or (Sign_SNA == 0):
self.over()
else:
#查找&进入递归
self.Path_Lookup()
def Path_Lookup(self):
#判断两个点的地址是否相同
if(self.SNA_list[7] == self.DNA_list[7]):
return 0
#对两个传感器进行判断
else:
#计算当前SNA的父节点的Cskip
if (self.SNA_list[9] == 0):
deep_SNA = 0
else:
deep_SNA = self.SNA_list[5] - 1
if(self.Rm == 1):
Cskip_SNA = 1 + self.Cm * (self.Lm - self.sensor_zc[0][5] - 1)
else:
Cskip_SNA = (1 + self.Cm - self.Rm - self.Cm * math.pow(self.Rm,(self.Lm - deep_SNA - 1))) / (1 - self.Rm)
Cskip_SNA = int(Cskip_SNA)
#计算计算当前DNA的父节点的CskipD
if (self.DNA_list[9] == 0):
deep_DNA = 0
else:
deep_DNA = self.DNA_list[5] - 1
if(self.Rm == 1):
Cskip_DNA = 1 + self.Cm * (self.Lm - self.sensor_zc[0][5] - 1)
else:
Cskip_DNA = (1 + self.Cm - self.Rm - self.Cm * math.pow(self.Rm,(self.Lm - deep_DNA - 1))) / (1 - self.Rm)
Cskip_DNA = int(Cskip_DNA)
#判断DNA是不是在SNA的子树中
if (self.SNA_list[9] == 0) or ((self.SNA_list[9] == 1) and (self.SNA_list[7] < self.DNA_list[7]) and ( self.DNA_list[7] < (self.SNA_list[7] + Cskip_SNA))):
#DNA在SNA的子树中,DNA向父节点回写,并以父节点覆盖DNA中的数据
#print('DNA在SNA的子树中')
#通过公式反推子结点对应父节点的地址
if(self.DNA_list[9] == 1):
DNA_Parent_Address = self.DNA_list[7] - 1 - Cskip_DNA * (self.DNA_list[6] - 1)
else:
DNA_Parent_Address = self.DNA_list[7] - Cskip_DNA * self.Rm - self.DNA_list[6]
#print(DNA_Parent_Address)
#用父节点的地址向ZC的地址比对,判断当前子结点的父节点是不是ZC
if(self.sensor_zc[0][7] == DNA_Parent_Address):
#对两个传感器进行连接
self.cv.create_line(self.gathering_point_center_x, self.gathering_point_center_y,
self.DNA_list[0], self.DNA_list[1],
fill='blue'
)
self.DNA_list = self.sensor_zc[0][::]
#用父节点的地址向ZR的地址比对,判断当前子结点的父节点对应的ZR
for num_sensor_zr_temp in range(0, len(self.sensor_zr_temp)):
if(self.sensor_zr_temp[num_sensor_zr_temp][7] == DNA_Parent_Address):
self.cv.create_line(self.sensor_zr_temp[num_sensor_zr_temp][0], self.sensor_zr_temp[num_sensor_zr_temp][1],
self.DNA_list[0], self.DNA_list[1],
fill='blue'
)
self.DNA_list = self.sensor_zr_temp[num_sensor_zr_temp][::]
break
else:
#DNA不在SNA的子树中
#print('DNA不在SNA的子树中')
#SNA向父节点回写,并以父节点覆盖SNA中的数据
#通过公式反推子结点对应父节点的地址
if(self.SNA_list[9] == 1):
SNA_Parent_Address = self.SNA_list[7] - 1 - Cskip_SNA * (self.SNA_list[6] - 1)
else:
SNA_Parent_Address = self.SNA_list[7] - Cskip_SNA * self.Rm - self.SNA_list[6]
#print(SNA_Parent_Address)
#用父节点的地址向ZC的地址比对,判断当前子结点的父节点是不是ZC
if(self.sensor_zc[0][7] == SNA_Parent_Address):
#对两个传感器进行连接
self.cv.create_line(self.gathering_point_center_x, self.gathering_point_center_y,
self.SNA_list[0], self.SNA_list[1],
fill='blue')
self.SNA_list = self.sensor_zc[0][::]
#用父节点的地址向ZR的地址比对,判断当前子结点的父节点对应的ZR
for num_sensor_zr_temp in range(0, len(self.sensor_zr_temp)):
if(self.sensor_zr_temp[num_sensor_zr_temp][7] == SNA_Parent_Address):
self.cv.create_line(self.sensor_zr_temp[num_sensor_zr_temp][0], self.sensor_zr_temp[num_sensor_zr_temp][1],
self.SNA_list[0], self.SNA_list[1],
fill='blue')
self.SNA_list = self.sensor_zr_temp[num_sensor_zr_temp][::]
break
'''
print('递归完成后的SNA:',self.SNA_list)
print('递归完成后的DNA:',self.DNA_list)
print('-------------------------------------------------')
'''
#递归
self.Path_Lookup()
def over(self):
return 0
#print("递归完成")
def run(self):
try:
self.root.mainloop()
except Exception as e:
print("*** exception:\n".format(e))
def main():
window = tk.Tk()
window.title('SensorProject Design By HJK and ZN')
Window(window).run()
if __name__ == '__main__':
main()
打包好的文件,下载后解压点击其中的 sensorprojectfinal.exe 就可以运行了
链接:https://pan.baidu.com/s/1rPiKkslLS8cV7UR8wJs-Tg
提取码:1111
算法思想: