Dijkstra is a typical shortest path routing algorithm used to calculate the shortest path from one node to all other nodes. The main feature is to expand horizontally at the center of the starting point until the end point is reached.
Generally, Dijkstra can be expressed in two ways: Permanent and Temporary label, and OPEN or CLOSE table.
When using OPEN and CLOSE tables, the greedy algorithm strategy is adopted. The process is as follows:
1. Declare two sets: open and close. open is used to store nodes that have not been traversed. close is used to store nodes that have been traversed.
2. In the initial stage, place the initial node in close, and all other nodes in open
3. Traverse from the center of the initial node layer by layer to obtain the child node closest to the specified node and put it in close and re-calculate the path until close contains all child nodes
The code example is as follows:
The Node object is used to encapsulate Node information, including names and subnodes.
[Java]
Public class Node {
Private String name;
Private Map <Node, Integer> child = new HashMap <Node, Integer> ();
Public Node (String name ){
This. name = name;
}
Public String getName (){
Return name;
}
Public void setName (String name ){
This. name = name;
}
Public Map <Node, Integer> getChild (){
Return child;
}
Public void setChild (Map <Node, Integer> child ){
This. child = child;
}
}
MapBuilder is used to initialize the data source and return the Start Node of the graph.
[Java]
Public class MapBuilder {
Public Node build (Set <Node> open, Set <Node> close ){
Node nodeA = new Node ("");
Node nodeB = new Node ("B ");
Node nodeC = new Node ("C ");
Node nodeD = new Node ("D ");
Node nodeE = new Node ("E ");
Node nodeF = new Node ("F ");
Node nodeG = new Node ("G ");
Node nodeH = new Node ("H ");
NodeA. getChild (). put (nodeB, 1 );
NodeA. getChild (). put (nodeC, 1 );
NodeA. getChild (). put (nodeD, 4 );
NodeA. getChild (). put (nodeG, 5 );
NodeA. getChild (). put (nodeF, 2 );
NodeB. getChild (). put (nodeA, 1 );
NodeB. getChild (). put (nodeF, 2 );
NodeB. getChild (). put (nodeH, 4 );
NodeC. getChild (). put (nodeA, 1 );
NodeC. getChild (). put (nodeG, 3 );
NodeD. getChild (). put (nodeA, 4 );
NodeD. getChild (). put (nodeE, 1 );
NodeE. getChild (). put (nodeD, 1 );
NodeE. getChild (). put (nodeF, 1 );
NodeF. getChild (). put (nodeE, 1 );
NodeF. getChild (). put (nodeB, 2 );
NodeF. getChild (). put (nodeA, 2 );
NodeG. getChild (). put (nodeC, 3 );
NodeG. getChild (). put (nodeA, 5 );
NodeG. getChild (). put (nodeH, 1 );
NodeH. getChild (). put (nodeB, 4 );
NodeH. getChild (). put (nodeG, 1 );
Open. add (nodeB );
Open. add (nodeC );
Open. add (nodeD );
Open. add (nodeE );
Open. add (nodeF );
Open. add (nodeG );
Open. add (nodeH );
Close. add (nodeA );
Return nodeA;
}
}
Shows the graph structure:
Dijkstra object is used to calculate the shortest path from the Start Node to all other nodes
[Java]
Public class Dijkstra {
Set <Node> open = new HashSet <Node> ();
Set <Node> close = new HashSet <Node> ();
Map <String, Integer> path = new HashMap <String, Integer> (); // encapsulation path Distance
Map <String, String> pathInfo = new HashMap <String, String> (); // encapsulate path information
Public Node init (){
// Initial path. Because there is no path A-> E, path (E) is set to Integer. MAX_VALUE.
Path. put ("B", 1 );
PathInfo. put ("B", "A-> B ");
Path. put ("C", 1 );
PathInfo. put ("C", "A-> C ");
Path. put ("D", 4 );
PathInfo. put ("D", "A-> D ");
Path. put ("E", Integer. MAX_VALUE );
PathInfo. put ("E", "");
Path. put ("F", 2 );
PathInfo. put ("F", "A-> F ");
Path. put ("G", 5 );
PathInfo. put ("G", "A-> G ");
Path. put ("H", Integer. MAX_VALUE );
PathInfo. put ("H", "");
// Put the initial node in close, and other nodes in open
Node start = new MapBuilder (). build (open, close );
Return start;
}
Public void computePath (Node start ){
Node nearest = getShortestPath (start); // obtain the child Node closest to the start Node and put it in close
If (nearest = null ){
Return;
}
Close. add (nearest );
Open. remove (nearest );
Map <Node, Integer> childs = nearest. getChild ();
For (Node child: childs. keySet ()){
If (open. contains (child) {// if the subnode is in open
Integer newCompute = path. get (nearest. getName () + childs. get (child );
If (path. get (child. getName ()> newCompute) {// The distance previously set is greater than the distance calculated
Path. put (child. getName (), newCompute );
PathInfo. put (child. getName (), pathInfo. get (nearest. getName () + "->" + child. getName ());
}
}
}
ComputePath (start); // repeat yourself to ensure that all child nodes are traversed.
ComputePath (nearest); // recursive layer by layer until all vertices are traversed
}
Public void printPathInfo (){
Set <Map. Entry <String, String> pathInfos = pathInfo. entrySet ();
For (Map. Entry <String, String> pathInfo: pathInfos ){
System. out. println (pathInfo. getKey () + ":" + pathInfo. getValue ());
}
}
/**
* Obtain the subnode closest to the node
*/
Private Node getShortestPath (Node node ){
Node res = null;
Int minDis = Integer. MAX_VALUE;
Map <Node, Integer> childs = node. getChild ();
For (Node child: childs. keySet ()){
If (open. contains (child )){
Int distance = childs. get (child );
If (distance <minDis ){
MinDis = distance;
Res = child;
}
}
}
Return res;
}
}
Main is used to test Dijkstra objects.
[Java] www.2cto.com
Public class Main {
Public static void main (String [] args ){
Dijkstra test = new Dijkstra ();
Node start = test. init ();
Test. computePath (start );
Test. printPathInfo ();
}
}
The output is as follows:
D: A-> D
E: A-> F-> E
F: A-> F
G: A-> C-> G
B: A-> B
C: A-> C
H: A-> B-> H