📜  路由终端之间的最短路径问题 - Python中的实现

📅  最后修改于: 2022-05-13 01:55:04.691000             🧑  作者: Mango

路由终端之间的最短路径问题 - Python中的实现

著名的 Dijkstra 算法可用于各种环境——包括作为一种寻找两个路由器之间最短路径的方法,也称为链路状态路由。本文解释了 Dijkstra 算法的模拟,其中节点(路由器)是终端。
一旦计算出两个节点(终端)之间的最短路径,最短路径本身作为消息依次发送到其路径上的每个终端,直到到达目的地终端。每当消息遍历一个节点时,它的终端就会显示遍历。通过这种方式,可以看到和模拟消息在最短的计算路径上的通过。

运行以下代码的过程如下:

这个实现指定了四个节点,但这可以很容易地扩展到具有 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()

Dijkstra 输出

终端输出 -

终端输出