1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace BLL
  7. {
  8. public class PathFinder
  9. {
  10. Dictionary<BatteryCenter, double> listDistance = new Dictionary<BatteryCenter, double>();
  11. Dictionary<BatteryCenter, BatteryCenter> listPrevious = new Dictionary<BatteryCenter, BatteryCenter>();
  12. public List<BatteryCenterDistance> FindPathFromCityToCity(Map map, BatteryCenter from, BatteryCenter to, double range)
  13. {
  14. using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\log\map.txt", true))
  15. {
  16. file.WriteLine("COUNT: {0} - RANGE {1}", map.Stations.Count, range);
  17. file.WriteLine("FROM: {0} - TO: {1}", from.name, to.name);
  18. foreach (var m in map.Stations)
  19. {
  20. file.WriteLine("C: {0} - E: {1} - T: {2}", m.name, m.Edgelist.Count, m.GetType());
  21. }
  22. }
  23. List<BatteryCenterDistance> list = new List<BatteryCenterDistance>();
  24. if (map.IsAdjacent(from, to))
  25. {
  26. list.Add(new BatteryCenterDistance() { BatteryCenter = from, Distance = 0 });
  27. list.Add(new BatteryCenterDistance() { BatteryCenter = to, Distance = map.FindEdge(from, to).distance });
  28. }
  29. else
  30. {
  31. CalculateDistance(map, from, range);
  32. while (listPrevious[to] != null)
  33. {
  34. var b = map.FindEdge(to, listPrevious[to]);
  35. list.Add(new BatteryCenterDistance() { BatteryCenter = to, Distance = (b != null ? b.distance : 0) });
  36. to = listPrevious[to];
  37. }
  38. list.Add(new BatteryCenterDistance() { BatteryCenter = from, Distance = 0 });
  39. list.Reverse();
  40. double covered = 0.0;
  41. BatteryCenterDistance bcd = new BatteryCenterDistance();
  42. foreach (var b in list)
  43. {
  44. if ((covered + b.Distance >= range))
  45. {
  46. if (b.Distance > range)
  47. b.Possible = false;
  48. else
  49. {
  50. bcd.Stop = true;
  51. covered = b.Distance;
  52. }
  53. }
  54. else
  55. covered += b.Distance;
  56. bcd = b;
  57. }
  58. }
  59. return list;
  60. }
  61. private void CalculateDistance(Map map, BatteryCenter from, double range)
  62. {
  63. List<BatteryCenter> listTemp = new List<BatteryCenter>();
  64. foreach (BatteryCenter b in map.Stations)
  65. {
  66. listDistance[b] = Double.PositiveInfinity;
  67. listPrevious[b] = null;
  68. b.Mark = false;
  69. }
  70. listDistance[from] = 0;
  71. listTemp.Add(from);
  72. while (listTemp.Count > 0)
  73. {
  74. BatteryCenter current = null;
  75. double distance = Double.PositiveInfinity;
  76. foreach (BatteryCenter v in listTemp)
  77. {
  78. if (listDistance[v] < distance)
  79. {
  80. current = v;
  81. distance = listDistance[v];
  82. }
  83. }
  84. listTemp.Remove(current);
  85. current.Mark = true;
  86. foreach (var _edge in current.Edgelist)
  87. {
  88. BatteryCenter b = map.Stations.FirstOrDefault(x => x.name.Equals(_edge.BatteryStation1.name));
  89. if (((listDistance[current] + _edge.distance) < listDistance[b]) && !b.Mark && (_edge.distance <= range))
  90. {
  91. listDistance[b] = listDistance[current] + _edge.distance;
  92. listPrevious[b] = current;
  93. listTemp.Add(b);
  94. }
  95. }
  96. }
  97. }
  98. }
  99. }