路由终端之间的最短路径问题 - Python中的实现
著名的 Dijkstra 算法可用于各种环境——包括作为一种寻找两个路由器之间最短路径的方法,也称为链路状态路由。本文解释了 Dijkstra 算法的模拟,其中节点(路由器)是终端。
一旦计算出两个节点(终端)之间的最短路径,最短路径本身作为消息依次发送到其路径上的每个终端,直到到达目的地终端。每当消息遍历一个节点时,它的终端就会显示遍历。通过这种方式,可以看到和模拟消息在最短的计算路径上的通过。
运行以下代码的过程如下:
- Execute the driver code
- Before providing any input to the driver code, run the router codes router1.py, router2.py, etc. in separate terminals/tabs.
- Now provide input to the driver code in the form of a matrix G, in which any entry
G[i, j]
is the distance from node i to node j. The matrix must be symmetrical. If i=j, thenD[i, j]=0
as the distance between a node and itself is considered to be nothing. If there is no direct connection between two nodes, thenD[i, j]=999
(the equivalent of infinity). - Specify source and destination nodes, where the nodes vary from 0 to 3, and represent terminals 1 to 4 respectively.
这个实现指定了四个节点,但这可以很容易地扩展到具有 N 个终端的 N 个节点,端口号分别表示在它们上运行的进程。
考虑以下四节点网络示例,它们之间的距离是指定的,节点从左到右编号为 0 到 3:
对于这个网络,上面指定的具有条目 G[i, j] 的矩阵 G 将是:
[[0, 1, 999, 999],
[1, 0, 2, 999],
[999, 2, 0, 3],
[999, 999, 3, 0]]
该矩阵必须输入到驱动程序代码中。 Dijkstra 算法用于寻找源和目的地之间的最短路径。包含剩余路径的列表被发送到前往最终目的地的每个节点。
下面指定了Python中的实现。
# Driver Code for implementing Dijkstra's algorithm
import socket
import sys
import pickle
S = set()
G =[] # adjacency matrix
# give input matrix
for i in range(4):
listo =[0, 0, 0, 0]
for j in range(4):
listo[j]= int(input("give input"))
G.append(listo)
source = int(input("give source"))
destination = int(input("give destination"))
Q =[] # empty queue
for i in range(4):
Q.append(i)
d =[0, 0, 0, 0] # initialize d values
pi =[0, 0, 0, 0] # initialize pi values
for i in range(4):
if(i == source):
d[i]= 0
else:
d[i]= 999
for i in range(4):
pi[i]= 9000
S.add(source)
# While items still exist in Q
while (len(Q)!= 0):
# Find the minimum distance x from
# source of all nodes in Q
x = min(d[q] for q in Q)
u = 0
for q in Q:
if(d[q]== x):
# Find the node u in Q with minimum
# distance x from source
u = q
print(u, "Is the minimum distance")
Q.remove(u) # removed the minimum vertex
S.add(u)
adj =[]
for y in range(4):
# find adjacent vertices to minimum vertex
if(y != u and G[u][y]!= 999):
adj.append(y)
# For each adjacent vertex, perform the update
# of distance and pi vectors
for v in adj:
if(d[v]>(d[u]+G[u][v])):
d[v]= d[u]+G[u][v]
pi[v]= u # update adjacents distance and pi
route =[]
x = destination
# If destination is source, then pi[x]= 9000.
if(pi[x]== 9000):
print(source)
else:
# Find the path from destination to source
while(pi[x]!= 9000):
route.append(x)
x = pi[x]
route.reverse()
print(route) # Display the route
print(pi) # Display the path vector
print(d) # Display the distance of each node from source
'''We will now send the calculated minimal route to the terminal
# representing 'source'. From the source terminal, the 'route' list
# will be sent to the next hop en route to the final destination.
# At each intermediate terminal, the router removes its own identity
from the list and sends the rest of the route to the next router.
This continues until the final router is reached.'''
sendingroute = pickle.dumps(route)
sockets =[8895, 8896, 8897, 8898]
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((socket.gethostname(), sockets))
try:
# try sendall if it doesn't work.
sock.send(sendingroute)
finally:
print("")
sock.close()
# Code for Router 1
import socket
import sys
import pickle
for i in range(1) :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((socket.gethostname(), 8895))
sock.listen(1)
connection, client_address = sock.accept()
route =[]
sockets =[8895, 8896, 8897, 8898]
while 1:
try:
route = pickle.loads(connection.recv(1024))
except EOFError:
break
finally:
break
print("Traversed 1")
socknext = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if(len(route)>0):
x = route[0]
route.remove(x)
dataroute = pickle.dumps(route)
socknext.connect((socket.gethostname(), sockets[x]))
try:
socknext.send(dataroute) # try sendall
data = socknext.recv(16)
print(data)
finally:
print("")
socknext.close()
# Code for Router 2
import socket
import sys
import pickle
for i in range(1) :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((socket.gethostname(), 8896))
sock.listen(1)
connection, client_address = sock.accept()
route =[]
sockets =[8895, 8896, 8897, 8898]
while 1:
try:
route = pickle.loads(connection.recv(1024))
except EOFError:
break
finally:
break
print("Traversed 2")
socknext = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if(len(route)>0):
x = route[0]
route.remove(x)
dataroute = pickle.dumps(route)
socknext.connect((socket.gethostname(), sockets[x]))
try:
socknext.send(dataroute) # try sendall
data = socknext.recv(16)
print(data)
finally:
print("")
socknext.close()
# Code for Router 3
import socket
import sys
import pickle
for i in range(1) :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((socket.gethostname(), 8897))
sock.listen(1)
connection, client_address = sock.accept()
route =[]
sockets =[8895, 8896, 8897, 8898]
while 1:
try:
route = pickle.loads(connection.recv(1024))
except EOFError:
break
finally:
break
print("Traversed 3")
socknext = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if(len(route)>0):
x = route[0]
route.remove(x)
dataroute = pickle.dumps(route)
socknext.connect((socket.gethostname(), sockets[x]))
try:
socknext.send(dataroute) # try sendall
data = socknext.recv(16)
print(data)
finally:
print("")
socknext.close()
# Code for Router 4
import socket
import sys
import pickle
for i in range(1) :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((socket.gethostname(), 8898))
sock.listen(1)
connection, client_address = sock.accept()
route =[]
sockets =[8895, 8896, 8897, 8898]
while 1:
try:
route = pickle.loads(connection.recv(1024))
except EOFError:
break
finally:
break
print("Traversed 4")
socknext = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if(len(route)>0):
x = route[0]
route.remove(x)
dataroute = pickle.dumps(route)
socknext.connect((socket.gethostname(), sockets[x]))
try:
socknext.send(dataroute) # try sendall
data = socknext.recv(16)
print(data)
finally:
print("")
socknext.close()
终端输出 -
在评论中写代码?请使用 ide.geeksforgeeks.org,生成链接并在此处分享链接。