Nothing to say, now directly on the encapsulation method:
Using system;using system.collections.concurrent;using system.collections.generic;namespace algorithm {//<summary> Dijkstra///Dijkstra algorithm///</summary> public class Dijkstra:icloneable {//<summary> Node collection </summary> public concurrentdictionary<string, node> LN {get; set;} <summary> Start Nodes </summary> public node Startnode {get; set;} <summary> End Node </summary> public node Endnode {get; set;} <summary>dijkstra Constructors </summary>//<param name= "List" > Node collection </param>//<para M name= "Start" > Start node </param>//<param name= "End" > End node </param> public Dijkstra (Concurre ntdictionary<string, node> list, string start, String end) {LN = list; Init (start, end); }///<summary>dijkstra constructor </summary>//<param name= "List" > Node collection </param>//<param name= "Start" > Start node </param>//<param name= "End" > End node </param> Public Dijkstra (ienumerable<map> list, string start, String end) {LN = Initnode (list); Init (start, end); }///<summary> Find Shortest Path </summary> public bool Find () {return findmin (new LIST&L T node> {startnode}, Endnode); }///<summary> initialize </summary> private void Init (string start, String end) {Sta Rtnode = Ln[start]; Endnode = Ln[end]; if (Startnode = = NULL | | Endnode = = null) {throw new ArgumentNullException ();//NULL exception} Startnode.set Rank (NULL); Startnode.isfind = true; Initrank (new list<node> {startnode}); }///<summary> Initialize rank </summary>//<param name= "SRCs" > Node collection </param>private void Initrank (ienumerable<node> srcs) {var nextnode = new list<node> (); foreach (var node in SRCs) {foreach (var edge in node). LE) {edge. Currentnode.setrank (node); if (Edge. Currentnode.rank = = (node. Rank + 1) &&!nextnode.contains (edge. CurrentNode)) Nextnode.add (edge. CurrentNode); }} if (Nextnode.count > 0) initrank (nextnode); }///<summary> Find </summary>//<param name= "SRCs" > Start node Collection </param>//<par Am Name= "dest" > End node </param> private bool Findmin (list<node> SRCS, node dest) {des T.getrank (); var minlen = 0; var isfind = false; var nextnodes = new list<node> (); String Tmppath; foreach (var node in SRCs) {if(node. Equals (dest)) return false; foreach (var edge in node. LE) {var Tempdestrank = edge. Currentnode.rank; if (Tempdestrank! = (node. Rank + 1)) continue; if (!nextnodes.contains (edge. CurrentNode)) {Nextnodes.add (edge. CurrentNode); } edge. currentnode.mindistance = node. Mindistance + Edge. Weight; if (!edge. Currentnode.equals (dest)) continue; Minlen = node. Mindistance + Edge. Weight; Isfind = true; Break }} if (Isfind) {foreach (var node in SRCs) { Tmppath = Findminx (node, dest, node. Mindistance, node. Rank, "", ref Minlen); if (Tmppath = = "") continue; Dest. Path = node. Path + Tmppath; Dest. Mindistance = Minlen; }} else {foreach (var next in nextnodes) { Minlen =-1; foreach (var node in SRCs) {if (Minlen = =-1) Minlen = next. Mindistance; Tmppath = Findminx (node, next, node). Mindistance, node. Rank, "", ref Minlen); if (Tmppath = = "") continue; Next. Path = node. Path + Tmppath; Next. Mindistance = Minlen; }} if (Nextnodes.count = = 0) return false; Findmin (Nextnodes, dest); } return isfind; }///<summary>///Find the smallest path from the starting node to the target node, where recursive lookups are used. The target node is fixed and the starting node is recursive. </summary>//<param name= "src" > Start node, temporary recursive node </param>///<param Name= "Dest" > Find Road Target node in the path </param>//<param NAMe= "Minx" > currently finds the minimum path value, this value is shared in recursion </param>//<param name= "Startdist" > The distance from the current node to the SRC node </param> <param name= "Srcrank" > Source node src level </param>//<param name= "path" > Path passed in lookup </param> private string Findminx (node src, node dest, int startdist, int srcrank, string path, ref int minx) {VA R Goalpath = ""; var tmpPath1 = "," + Path + ","; var tmpPath2 = "," + src. Path + ","; foreach (var node in Src. LE) {String tmppath = path; Node. Currentnode.setrank (SRC); var tmprank = node. Currentnode.rank; var tmpnodename = "," + node. Currentnode.name + ","; The diffusion level is greater than or equal to the target level and is a non-traversed node. if (Tmprank <= Srcrank | | tmppath1.indexof (TMPNODENAME, stringcomparison.ordinal)! =-1 | | Tmppath2.indexof (Tmpnodename, stringcomparison.ordinal)! =-1) continue; var tmplength = node. Weight + startdist; if (node. Currentnode.equals (dest)) {if (Minx > Tmplength) { Minx = tmplength; Tmppath + = "," + node. Currentnode.name; Goalpath = Tmppath; } else if (minx = = tmplength) {Tmppath + = "," + node. Currentnode.name; Goalpath = Tmppath; }} else {if (tmplength >= minx) continue; Distance is less than minimum, query sub node Tmppath + = "," + node. Currentnode.name; Tmppath = Findminx (node. CurrentNode, dest, Tmplength, Srcrank, Tmppath, ref minx); if (Tmppath! = "") Goalpath = Tmppath; }} return Goalpath; }//<summarY> initialization diagram </summary>//<param name= "List" > Point collection </param> Private concurrentdictionary<st Ring, node> Initnode (ienumerable<map> list) {var Node = new concurrentdictionary<string, No De> (); foreach (var item in list) {Node N1; Node N2; if (!node. ContainsKey (item. N1)) {n1 = new Node (item. N1); Node. TryAdd (item. N1, N1); } else {n1 = Node[item. N1]; } if (!node. ContainsKey (item. N2)) {n2 = new Node (item. N2); Node. TryAdd (item. N2, N2); } else {n2 = Node[item. N2]; } N1. LE. ADD (new Edge (item). N2, item. Weight, N2)); } return node; } #regionCopy public Object Clone () {return memberwiseclone (); }///<summary> Light copy </summary> public Dijkstra cloneentity () {return Clone () as Dijkstra; } #endregion}///<summary>////</summary> public class Node:icloneable { <summary> node names </summary> public String name {get; set;} <summary> Node Edge collection </summary> public list<edge> LE {get; set;} <summary> node level </summary> public Int32 rank {get; set;} <summary> Shortest distance </summary> public Int32 mindistance {get; set;} <summary> path </summary> Public String path {get; set;} <summary> Query Identity </summary> public bool Isfind {get; set;} Public Node (String name) {name = name; Isfind = false; Rank =-1; mindistance = 0; LE = new list<edge> (); }///<summary> Set node level </summary>//<param name= "parentnode" > Parent node </param> publ IC void Setrank (Node parentnode) {if (Rank! =-1) return; Rank = parentnode! = null? Parentnode.rank + 1:0; }///<summary> Get node level </summary> public Int32 GetRank () {return Rank; #region Copy public Object Clone () {return memberwiseclone (); }///<summary> Light copy </summary> public Node cloneentity () {return Clone () as Nod E } #endregion}///<summary>///</summary> public class Edge:icloneable { <summary> Edge name </summary> public String name {get; set;} <summary> weights, costs, distance </summary> public Int32 Weight {get; set;} <summary> current vector end point node </summary> public node CurrentNode {get; set;} Public Edge (String name, Int32 Weight, node node) {name = name; Weight = Weight; CurrentNode = node; }///<summary> Set current node </summary>//<param name= "node" > Current vector endpoint </param> publi c void Setcurrentnode (node node) {CurrentNode = node; #region Copy public Object Clone () {return memberwiseclone (); }///<summary> Light copy </summary> public Edge cloneentity () {return Clone () as EDG E } #endregion}///<summary> graphic </summary> public class Map:icloneable {//<sum Mary> node 1</summary> public string N1 {get; set;} <summary> node 2</summary> public string N2 {get; set;} <summary> weight, price, distance </summary> public int Weight {get; set;} Public map () {} public map (string n1, string n2, int weight) {N1 = n1; N2 = n2; Weight = Weight; #region Copy public Object Clone () {return memberwiseclone (); }///<summary> Light copy </summary> public map cloneentity () {return Clone () as map; } #endregion}}
Usage:
Private Ienumerable<map> Initmap () {var list = new List<map> {NE W Map ("A", "B", 3), New map ("A", "C", 5), New map ("A", "D", 2), new map ("B", "A", 3), new map ("B", "C", 4), new map ("B", "E", "ten"), New map ("C", "a", 5), New Map ("C", "B", 4), New map ("C", "D", 2), New map ("C", "F", 1), New Map ("C", "G", 6), new map ("D", "A", 2), new map ("D", "C", 2), New map ( "D", "H", 3), new map ("E", "B", "ten"), New map ("E", "F", 4), new map ("E", "I", 2), New map ("F", "C", 1), New map ("F", "E", 4), New map ("F", "K", 8), New Map ("F", "L", 2), New map ("G", "C", 6), New map ("G", "H", 8), new Map ("G", "L", 2), New map ("H", "D", 3), New map ("H", "G", 8), New map ("I", "E", 2), n EW map ("I", "K", 6), New map ("I", "J", 1), New map ("J", "I", 1), New map ("J", "K", 9), New map ("K", "J", 9), New map ("K", "I", 6), New map ("K", "F", 8), New Map ("K", "L", 5), New map ("L", "K", 5), New map ("L", "F", 2), New Map ("L", "G", 2)}; return list; }void call () {var dij = new Dijkstra (Initmap (), start, end);d ij. Find (); var _path = string. Format ("minimum distance: {0} path: {1}{2} total time: {3} milliseconds \ r \ n", Dij. Endnode.mindistance, start, Dij. Endnode.path, SW. Elapsedmilliseconds); Show results on Interface}
C # Dijkstra algorithm Dijkstra