# Shortest Path Problem Between Routing Terminals – Implementation in Python

• Difficulty Level : Expert
• Last Updated : 27 Feb, 2020

The famous Dijkstra’s algorithm can be used in a variety of contexts – including as a means to find the shortest route between two routers, also known as Link state routing. This article explains a simulation of Dijkstra’s algorithm in which the nodes (routers) are terminals.
Once the shortest path between two nodes (terminals) is calculated, the shortest path itself is sent as a message to each terminal on its path in sequence, until the destination terminal is reached. Whenever the message has traversed a node, its terminal displays the traversal. In this way, it is possible to both see and simulate the passage of a message across a shortest calculated route.

The procedure to run the following code is as follows:

• 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, then` D[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, then `D[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.

This implementation specifies four nodes but this can easily be extended to N nodes with N terminals and port numbers representing processes running on them respectively.

Consider the following example of a four-node network, with distances between them as specified and nodes numbered 0 to 3 from left to right:

Distances between terminals

For this network, the matrix G with entries G[i, j] as specified above would be:

```[[0, 1, 999, 999],
[1, 0, 2, 999],
[999, 2, 0, 3],
[999, 999, 3, 0]]
```

This matrix would have to be input to the driver code. Dijkstra’s algorithm is used to find the shortest path between source and destination. A list containing the remaining path is sent to each node en route to the final destination.

The implementation in Python is specified below.

 `# 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 Output

Terminal Output –

Terminal Output

My Personal Notes arrow_drop_up
Related Articles