annstasi

Untitled

Mar 31st, 2021 (edited)
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.41 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Greedy.Architecture;
  7. using System.Drawing;
  8.  
  9. namespace Greedy
  10. {
  11. public class DijkstraPathFinder
  12. {
  13. // По аналогии с уроком
  14. class DijkstraData
  15. {
  16. public Point Previous { get; set; }
  17. public int Cost { get; set; }
  18. }
  19. public IEnumerable<PathWithCost> GetPathsByDijkstra(State state, Point start, IEnumerable<Point> targets)
  20. {
  21. var notVisited = MapProcessing(state).Where(a =>
  22. {
  23. return !state.IsWallAt(a);
  24. }).ToList();
  25. var previous = new Point(-1, -1);
  26. // Запоминаем путь, задаем начальное положение
  27. var track = new Dictionary<Point, DijkstraData>
  28. {
  29. [start] = new DijkstraData {Previous = previous, Cost = 0 }
  30. };
  31. // Количество сундуков
  32. var targetsCount = targets.Count();
  33.  
  34. while (targetsCount > 0)
  35. {
  36. var Open = GetPoint(notVisited, track);
  37. if (Open.X == -1) yield break;
  38.  
  39. if (targets.Contains(Open))
  40. {
  41. yield return CreatePath(track, Open);
  42. }
  43.  
  44. CheckPrice(Open, state, track);
  45. notVisited.Remove(Open);
  46. targetsCount--;
  47. }
  48. }
  49. private Point GetPoint(List<Point> notVisited, Dictionary<Point, DijkstraData> track)
  50. {
  51. var toOpen = new Point(-1, -1);
  52. var bestCost = double.PositiveInfinity;
  53.  
  54. //П
  55. foreach (var e in notVisited)
  56. {
  57. if (track.ContainsKey(e) && track[e].Cost < bestCost)
  58. {
  59. bestCost = track[e].Cost;
  60. toOpen = e;
  61. }
  62. }
  63. return toOpen;
  64. }
  65. private PathWithCost CreatePath(Dictionary<Point, DijkstraData> track, Point target)
  66. {
  67. var path = new List<Point>();
  68. int cost = track[target].Cost;
  69.  
  70. while (target.X != -1)
  71. {
  72. path.Add(target);
  73. target = track[target].Previous;
  74. }
  75. path.Reverse();
  76.  
  77. var result = new PathWithCost(cost, path.ToArray());
  78. return result;
  79. }
  80. private void CheckPrice(Point p, State s, Dictionary<Point, DijkstraData> track)
  81. {
  82. foreach (var point in CheckNeighbours(p, s))
  83. {
  84. var costsNow = s.CellCost[point.X, point.Y] + track[p].Cost;
  85. if (track.ContainsKey(point) && track[point].Cost <= costsNow)
  86. {
  87. continue;
  88. }
  89. track[point] = new DijkstraData { Previous = p, Cost = costsNow };
  90. }
  91. }
  92. private IEnumerable<Point> MapProcessing(State s)
  93. {
  94. var w = s.MapWidth;
  95. var h = s.MapHeight;
  96.  
  97. for (var i = 0; i < w; i++)
  98. {
  99. for (var j = 0; j < h; j++)
  100. yield return new Point(i, j);
  101. }
  102. }
  103. public IEnumerable<Point> CheckNeighbours(Point point1, State s)
  104. {
  105. int[] moves = { -1, 0, 1 };
  106.  
  107. IEnumerable<Point> enumerable()
  108. {
  109. foreach (var x in moves)
  110. {
  111. foreach (var y in moves)
  112. {
  113. if (Math.Abs(x) == Math.Abs(y))
  114. {
  115. continue;
  116. }
  117. yield return new Point(point1.X + x, point1.Y + y);
  118. }
  119. }
  120. }
  121. return enumerable().Where(point =>
  122. {
  123. return !(!s.InsideMap(point) || s.IsWallAt(point));
  124. });
  125. }
  126. }
  127. }
Add Comment
Please, Sign In to add comment