写在前面:没有进行非常难的代码编写,仅仅是算法思想的抽象实现
首先,明确如何建立模型。
这里我选择使用python编程语言来实现模型,因为python编程语言相较于其他编程语言,更适合进行数据运算,也更方便进行图形化演示。
先在excel中建立起街道模型,并形成二维矩阵作为地图。这里我选择的是64x64的二维矩阵,并模仿背景道路图设计的地图。
其中绿色代表绿地,白色代表楼房,红色代表街道,黄色代表固定信号站。这里建议在构建道路的时候,选择使用一格宽度作为道路抽象模型,而非其他宽度作为道路模型,因为在车辆运行时牵扯到变道问题。
然后,在代码中保存二维矩阵作为地图,并在窗口函数中进行调用,以实现窗口化展示结果。
self.top=tkinter.Tk()
self.top.title("道路模型") # 标题
self.top.resizable(0, 0) # 大小可调性
self.top.geometry('900x640') # 大小
for i in range(64):
for j in range(64):
if map[i][j]==0:
self.l = tkinter.Label(self.top, text=(chr(9608)), fg='white',font=('黑体',6))
self.l.place(x=i*10,y=j*10)
elif map[i][j]==1:
self.l = tkinter.Label(self.top, text=(chr(9608)), fg='green',font=('黑体',6))
self.l.place(x=i * 10, y=j * 10)
elif map[i][j]==2:
self.l = tkinter.Label(self.top, text=(chr(9608)), fg='orange',font=('黑体',6))
self.l.place(x=i * 10, y=j * 10)
else :
self.l = tkinter.Label(self.top, text=(chr(9608)), fg='gray',font=('黑体',6))
self.l.place(x=i * 10, y=j * 10)
运行结果如下:
可以看到,基本上已经有了一个街道模型的感觉。
然后,设立car类,并设计运行函数,能够保证车辆在道路上运行。
def run(self):
num=0
axx=[]
ayy=[]
if self.x==0:
self.x = 32
self.y = 32
self.px = self.x
self.px = self.y
s=r.randint(0,3)
if s==0:
self.y=self.y-1
elif s==1:
self.y=self.y+1
elif s==2:
self.x=self.x-1
else:
self.x=self.x+1
elif self.x==63:
self.x = 32
self.y = 32
self.px = self.x
self.px = self.y
s=r.randint(0,3)
if s==0:
self.y=self.y-1
elif s==1:
self.y=self.y+1
elif s==2:
self.x=self.x-1
else:
self.x=self.x+1
elif self.y==0:
self.x = 32
self.y = 32
self.px = self.x
self.px = self.y
s=r.randint(0,3)
if s==0:
self.y=self.y-1
elif s==1:
self.y=self.y+1
elif s==2:
self.x=self.x-1
else:
self.x=self.x+1
elif self.y==63:
self.x = 32
self.y = 32
self.px = self.x
self.px = self.y
s=r.randint(0,3)
if s==0:
self.y=self.y-1
elif s==1:
self.y=self.y+1
elif s==2:
self.x=self.x-1
else:
self.x=self.x+1
else:
if map[self.x][self.y]==map[self.x-1][self.y] and self.x-1!=self.px:
num=num+1
axx.append(self.x-1)
ayy.append(self.y)
if map[self.x][self.y]==map[self.x+1][self.y] and self.x+1!=self.px:
num=num+1
axx.append(self.x+1)
ayy.append(self.y)
if map[self.x][self.y]==map[self.x][self.y-1] and self.y-1!=self.py:
num=num+1
axx.append(self.x)
ayy.append(self.y-1)
if map[self.x][self.y]==map[self.x][self.y+1] and self.y+1!=self.py:
num=num+1
axx.append(self.x)
ayy.append(self.y+1)
self.px=self.x
self.py=self.y
n=r.randint(0,num-1)
self.x=axx[n]
self.y=ayy[n]
由此,实现了车辆的前进一步以及随即转向,然后只需要生成一定量的车辆,并通过while函数维持每隔一定时间调用一次run函数即可。
def make(self):
if self.flag==0:
self.flag=1
self.a=car('001')
self.b=car('002')
self.c=car('003')
else:
self.flag=1
self.l = tkinter.Label(self.top, text=(chr(9608)), fg='red',font=('黑体',6))
self.l.place(x=self.a.x * 10, y=self.a.y * 10)
self.l = tkinter.Label(self.top, text=(chr(9608)), fg='blue',font=('黑体',6))
self.l.place(x=self.b.x * 10, y=self.b.y * 10)
self.l = tkinter.Label(self.top, text=(chr(9608)), fg='purple',font=('黑体',6))
self.l.place(x=self.c.x * 10, y=self.c.y * 10)
self.top.update()
while self.flag==1:
self.carr()
t.sleep(0.5)
最终可得到如下结果:
一共有三辆车,其中红色的为车a,蓝色为车b,紫色为车c。
然后解决通信问题。首先是通过GPS实现的简单直接通信,即发送方将信息发送到GPS卫星,卫星保持一个列表存储车辆实时位置,并再将信息发送给接收方。
def sen1(self):
sta=self.c1.get()
aim=self.c2.get()
self.n=2
if sta==aim:
print('error')
else:
if sta=='a':
message=self.a.send()
elif sta=='b':
message=self.b.send()
else:
message=self.c.send()
if aim=='a':
self.a.reciv(message)
elif aim=='b':
self.b.reciv(message)
else:
self.c.reciv(message)
self.l = tkinter.Label(self.top, text=('message:'+str(message)), fg='black', font=('黑体', 15))
self.l.place(relx=0.75,rely=0.8)
self.l = tkinter.Label(self.top, text=('num:'+str(self.n)), fg='black', font=('黑体', 15))
self.l.place(relx=0.75,rely=0.9)
然后是GPSR通信,GPSR通信是发送方先发送信息和接收方所在的区域,然后通过贪心选择和D2D多跳实现数据的传输。
这里我定义了很多的中间固定信号站作为多跳节点,然后每个中间固定信号站有一定的信号范围,在接受到传输信号后,查看自己的信号范围内是否有目标节点,有则直接进行传输,否则将会通过贪心选择选择范围内最接近目标节点的下一站点,或者随机选择一个站点(无最近)。代码实现如下:
def search(self,aax,aay,aim):
lx=0
ly=0
ax=aax
ay=aay
self.n=0
for o in range(99):
le=9999
print(o,ax,ay)
self.n=self.n+1
for i in range(ax-6,ax+6):
if i>=0 and i<64:
for j in range(ay-6,ay+6):
if j>=0 and j<64:
if aim.x==i and aim.y==j:
return self.n
if map[i][j]==2 and i!=ax and j!=ay:
if le>=int((aim.x-i)*(aim.x-i)+(aim.y-j)*(aim.y-j)):
le=int((aim.x-i)*(aim.x-i)+(aim.y-j)*(aim.y-j))
lx=i
ly=j
ax=lx
ay=ly
这里我原本打算使用递归,后来在实验中发现如果使用递归可能会出现内存错误,故选择循环来代替递归,并设置了最大递归深度
然后只需要对发送方进行处理,并调用search函数即可。
def sen2(self):
sta=self.c1.get()
aim=self.c2.get()
self.n=0
if sta==aim:
print('error')
else:
if sta=='a':
message=self.a.send()
if aim == 'a':
try:
self.n=self.search(self.a.x,self.a.y,self.a)
except:
self.n=-1
self.a.reciv(message)
elif aim == 'b':
try:
self.n=self.search(self.a.x,self.a.y,self.b)
except:
self.n=-1
self.b.reciv(message)
else:
try:
self.n=self.search(self.a.x,self.a.y,self.c)
except:
self.n=-1
self.c.reciv(message)
elif sta=='b':
message=self.b.send()
if aim == 'a':
try:
self.n=self.search(self.a.x,self.a.y,self.a)
except:
self.n=-1
self.a.reciv(message)
elif aim == 'b':
try:
self.n=self.search(self.a.x,self.a.y,self.b)
except:
self.n=-1
self.b.reciv(message)
else:
try:
self.n=self.search(self.a.x,self.a.y,self.c)
except:
self.n=-1
self.c.reciv(message)
else:
message=self.c.send()
if aim == 'a':
try:
self.n=self.search(self.a.x,self.a.y,self.a)
except:
self.n=-1
self.a.reciv(message)
elif aim == 'b':
try:
self.n=self.search(self.a.x,self.a.y,self.b)
except:
self.n=-1
self.b.reciv(message)
else:
try:
self.n=self.search(self.a.x,self.a.y,self.c)
except:
self.n=-1
self.c.reciv(message)
self.l = tkinter.Label(self.top, text=('message:'+str(message)), fg='black', font=('黑体', 15))
self.l.place(relx=0.75,rely=0.8)
self.l = tkinter.Label(self.top, text=('num:'+str(self.n)), fg='black', font=('黑体', 15))
self.l.place(relx=0.75,rely=0.9)
通过一个变量存储路径中的节点数目,并在后台打印每个节点的坐标值。结果如下:
绘制在图中即为: