private void OpenPoint(Point toOpen, State state, List <Point> notVisitedPoints, Dictionary <Point, DijkstraData> track) { for (var dy = -1; dy <= 1; dy++) { for (var dx = -1; dx <= 1; dx++) { if (dx == 0 || dy == 0) { var nextPoint = new Point(toOpen.X + dx, toOpen.Y + dy); if (track.ContainsKey(nextPoint) || !state.InsideMap(nextPoint) || state.IsWallAt(nextPoint)) { continue; } notVisitedPoints.Add(nextPoint); var currentPrice = track[toOpen].Price + state.CellCost[nextPoint.X, nextPoint.Y]; if (!track.ContainsKey(nextPoint) || track[nextPoint].Price > currentPrice) { track[nextPoint] = new DijkstraData { Previous = toOpen, Price = currentPrice } } ; } } } notVisitedPoints.Remove(toOpen); } }
public IEnumerable <PathWithCost> GetPathsByDijkstra(State state, Point start, IEnumerable <Point> targets) { HashSet <Point> chests = new HashSet <Point>(targets); HashSet <Point> candidatesToOpen = new HashSet <Point>(); HashSet <Point> visitedNodes = new HashSet <Point>(); var track = new Dictionary <Point, DijkstraData>(); track[start] = new DijkstraData { Price = 0, Previous = null }; candidatesToOpen.Add(start); while (true) { Point?toOpen = null; var bestPrice = int.MaxValue; foreach (var candidate in candidatesToOpen) { if (track[candidate].Price < bestPrice) { bestPrice = track[candidate].Price; toOpen = candidate; } } if (toOpen == null) { yield break; } if (chests.Contains(toOpen.Value)) { yield return(MakePath(track, toOpen.Value)); } var incidentNodes = GetIncidentNodes(toOpen.Value, state); foreach (var incidentNode in incidentNodes) { var currentPrice = track[toOpen.Value].Price + state.CellCost[incidentNode.X, incidentNode.Y]; if (!track.ContainsKey(incidentNode) || track[incidentNode].Price > currentPrice) { track[incidentNode] = new DijkstraData { Previous = toOpen, Price = currentPrice }; } if (!visitedNodes.Contains(incidentNode)) { candidatesToOpen.Add(incidentNode); } } candidatesToOpen.Remove(toOpen.Value); visitedNodes.Add(toOpen.Value); } }
private static List <Node> Dijkstra(Graph graph, Dictionary <Edge, double> weights, Node start, Node end) { var notVisited = graph.Nodes.ToList(); var track = new Dictionary <Node, DijkstraData>(); track[start] = new DijkstraData { Price = 0, Previous = null }; while (true) { Node toOpen = null; var bestPrice = double.PositiveInfinity; foreach (var e in notVisited) { if (track.ContainsKey(e) && track[e].Price < bestPrice) { bestPrice = track[e].Price; toOpen = e; } } if (toOpen == null) { return(null); } if (toOpen == end) { break; } foreach (var e in toOpen.IncidentEdges.Where(z => z.From == toOpen)) { var currentPrice = track[toOpen].Price + weights[e]; var nextNode = e.OtherNode(toOpen); if (!track.ContainsKey(nextNode) || track[nextNode].Price > currentPrice) { track[nextNode] = new DijkstraData { Previous = toOpen, Price = currentPrice } } ; } notVisited.Remove(toOpen); } var result = new List <Node>(); while (end != null) { result.Add(end); end = track[end].Previous; } result.Reverse(); return(result); }
private void WorkOnOpen(Point toOpen, State state, Dictionary <Point, DijkstraData> track) { foreach (var p in GetNextPoints(toOpen, state)) { int currentPrice = state.CellCost[p.X, p.Y] + track[toOpen].Price; if (!track.ContainsKey(p) || track[p].Price > currentPrice) { track[p] = new DijkstraData { Previous = toOpen, Price = currentPrice } } ; } }
private DiscoveredData searchAllData(Point start, State state, List <Point> targets) { var pointValues = pointValuesInitialization(state, start); var track = new Dictionary <Point, DijkstraData> { [start] = new DijkstraData(start, 0, null) }; var toOpenQueue = new Queue <DijkstraData>(new[] { track[start] }); var sortedTargets = new List <Point>(); while (toOpenQueue.Count != 0) { var toOpen = toOpenQueue.Dequeue(); foreach (var point in incidentPoints(toOpen.Point, state)) { var value = state.CellCost[point.X, point.Y]; if (pointValues[point.X, point.Y] <= toOpen.Value + value || value == 0) { continue; } var currentPoint = new DijkstraData(point, value + toOpen.Value, toOpen); if (!track.ContainsKey(currentPoint.Point)) { track.Add(currentPoint.Point, currentPoint); } else { track[currentPoint.Point] = currentPoint; } toOpenQueue.Enqueue(currentPoint); pointValues[point.X, point.Y] = value; } if (targets.Contains(toOpen.Point)) { sortedTargets.Add(toOpen.Point); } toOpenQueue = new Queue <DijkstraData>(toOpenQueue.OrderBy(x => x.Value)); } return(new DiscoveredData(track, sortedTargets)); }
private void GetNextPoint(State state, Dictionary <Point, DijkstraData> track, Point toOpen) { List <int> delta = new List <int>() { -1, 0, 1 }; var nextPointList = (from x in delta from y in delta where Math.Abs(x) != Math.Abs(y) select new Point(toOpen.X + x, toOpen.Y + y)) .Where(point => state.InsideMap(point) && !state.IsWallAt(point)).ToList(); foreach (var point in nextPointList) { var currentPrice = track[toOpen].Price + state.CellCost[point.X, point.Y]; if (!track.ContainsKey(point) || track[point].Price > currentPrice) { track[point] = new DijkstraData { Previous = toOpen, Price = currentPrice }; } } }
private static void OpenCell(State state, Dictionary <Point, DijkstraData> track, Point cellToOpen) { var possibleDirections = new[] { new Point(-1, 0), new Point(0, -1), new Point(0, 1), new Point(1, 0) }; var nextCells = possibleDirections .Select(point => new Point(point.X + cellToOpen.X, point.Y + cellToOpen.Y)) .Where(state.InsideMap) .Where(point => !state.IsWallAt(point)); foreach (var cell in nextCells) { var currentPrice = track[cellToOpen].Price + state.CellCost[cell.X, cell.Y]; var nextPoint = cell; if (!track.ContainsKey(nextPoint) || track[nextPoint].Price > currentPrice) { track[nextPoint] = new DijkstraData(cellToOpen, currentPrice); } } }
public IEnumerable <PathWithCost> GetPathsByDijkstra(State state, Point start, IEnumerable <Point> targets) { var notVisitedTargets = targets.ToList(); var notVisitedPoints = new List <Point>(); var track = new Dictionary <Point, DijkstraData>(); track[start] = new DijkstraData { Previous = new Point(-1, -1), Price = 0 }; notVisitedPoints.Add(start); while (notVisitedTargets.Any()) { var path = GetPathByDijkstra(state, notVisitedPoints, track, notVisitedTargets); if (path == null) { yield break; } yield return(path); notVisitedTargets.Remove(path.End); } }
public IEnumerable <PathWithCost> GetPathsByDijkstra(State state, Point start, IEnumerable <Point> targets) { var notVisited = GetMazePoints(state).Where(p => !state.IsWallAt(p)).ToList(); var track = new Dictionary <Point, DijkstraData>(); track[start] = new DijkstraData { Price = 0, Previous = new Point(-1, -1) }; while (true) { Point toOpen = GetPointToOpen(notVisited, track); if (toOpen.X == -1) { yield break; } if (targets.Contains(toOpen)) { yield return(GetPathFromTrack(track, toOpen)); } WorkOnOpen(toOpen, state, track); notVisited.Remove(toOpen); } }
public DijkstraData(Point point, int value, DijkstraData previous) { Point = point; Value = value; Previous = previous; }