Beispiel #1
0
     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);
     }
 }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
 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
             }
         }
         ;
     }
 }
Beispiel #5
0
        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));
        }
Beispiel #6
0
        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);
                }
            }
        }
Beispiel #8
0
        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);
            }
        }
Beispiel #9
0
        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);
            }
        }
Beispiel #10
0
 public DijkstraData(Point point, int value, DijkstraData previous)
 {
     Point    = point;
     Value    = value;
     Previous = previous;
 }