Пример #1
0
    // Wave algo - fill all nearby cells with distance from first cell to the last cell on grid
    public virtual Distances FindDistanceForAllReachableLinkedCells()
    {
        Distances       distances = new Distances(this);
        List <MazeCell> frontier  = new List <MazeCell>()
        {
            this
        };

        // Will expands until last connected cell found
        while (frontier.Count > 0)
        {
            var newFrontier = new List <MazeCell>();

            foreach (var frontierCell in frontier)
            {
                foreach (var linkedCell in frontierCell.Links())
                {
                    if (distances.ContainsKey(linkedCell)) // if cell is visited then skip
                    {
                        continue;
                    }
                    distances.Add(linkedCell, distances[frontierCell] + 1);
                    newFrontier.Add(linkedCell);
                }
            }

            frontier = newFrontier;
        }

        return(distances);
    }
Пример #2
0
    //Dijkstra algorithm - go backwards - from goal cell to root cell
    public Distances DijkstraShortestPathTo(MazeCell goal)
    {
        MazeCell currentCell = goal;
        // навигационная цепочка
        Distances breadcrumbTrail = new Distances(this.startingCell);

        breadcrumbTrail[currentCell] = this[currentCell];

        // starightforward algo -  For each cell along the path, the neighboring cell with the lowest distance will be the next step of the solution
        while (currentCell != startingCell)
        {
            foreach (MazeCell neighbourCell in currentCell.Links())  //get all linked cells of current cell
            {
                if (this[neighbourCell] < this[currentCell])         //find linked cell with min distance (closest to the startingCell)
                {
                    if (!breadcrumbTrail.ContainsKey(neighbourCell)) // add to dictionary if not exists in dictionary
                    {
                        breadcrumbTrail.Add(neighbourCell, this[neighbourCell]);
                    }
                    else
                    {
                        breadcrumbTrail[neighbourCell] = this[neighbourCell]; // replace distance if less distance value found
                    }

                    currentCell = neighbourCell;                    // switch current cell to the neighbour
                    break;
                }
            }
        }
        return(breadcrumbTrail);
    }
        public List <HorizontalPoint> GetHorizontalPointsInRange(float fromAngle, float toAngle, VerticalAngle verticalAngle)
        {
            if (Distances == null || (!Distances.ContainsKey(verticalAngle)))
            {
                return new List <HorizontalPoint>()
                       {
                           new HorizontalPoint(0, float.NaN)
                       }
            }
            ;

            List <HorizontalPoint> pointsInRange = new List <HorizontalPoint>();
            bool angleSpansZero = fromAngle > toAngle;

            int startIndex = Distances[verticalAngle].FindIndex(point => point.Angle > fromAngle);

            if (angleSpansZero)
            {
                if (startIndex != -1)
                {
                    for (int i = startIndex; i < Distances[verticalAngle].Count; i++)
                    {
                        pointsInRange.Add(Distances[verticalAngle][i]);
                    }
                }

                int endIndex = Distances[verticalAngle].FindIndex(point2 => point2.Angle > toAngle);

                for (int i = 0; i < endIndex; i++)
                {
                    pointsInRange.Add(Distances[verticalAngle][i]);
                }
            }
            else
            {
                if (startIndex == -1)
                {
                    return new List <HorizontalPoint>()
                           {
                               new HorizontalPoint(0, float.NaN)
                           }
                }
                ;

                int             i     = startIndex;
                HorizontalPoint point = Distances[verticalAngle][i];
                while (point.Angle < toAngle && i < Distances[verticalAngle].Count)
                {
                    point = Distances[verticalAngle][i];

                    pointsInRange.Add(point);
                    ++i;
                }
            }

            return(pointsInRange);
        }
        public float GetDistance(float fromAngle, float toAngle, VerticalAngle verticalAngle, CalculationType calculationType)
        {
            if (Distances == null || (!Distances.ContainsKey(verticalAngle)))
            {
                return(float.NaN);
            }

            List <float> distancesInRange = GetDistancesInRange(fromAngle, toAngle, verticalAngle);

            return(PerformCalculation(distancesInRange, calculationType));
        }
Пример #5
0
        public void CalcDistancesAndAssign()
        {
            Enumerable.Range(0, Clusters).AsParallel().ForAll(i =>
            {
                for (var m = 0; m < LSA.MatrixContainer.VMatrix.ColumnCount; m++)
                {
                    var newDistance = Distance.Cosine(Centers[i], LSA.MatrixContainer.VMatrix.Column(m).ToArray());

                    if (!Distances.ContainsKey(m) || newDistance < Distances[m])
                    {
                        ClusterMap[m] = i;
                        Distances[m]  = newDistance;
                    }
                }
            });
        }
        public HorizontalPoint LargestDistanceInRange(float fromAngle, float toAngle)
        {
            if (Distances == null || !Distances.ContainsKey(Config.DefaultVerticalAngle))
            {
                return(new HorizontalPoint(float.NaN, float.NaN));
            }

            bool angleSpansZero = fromAngle > toAngle;

            if (angleSpansZero)
            {
                return(Distances[Config.DefaultVerticalAngle].OrderByDescending(i => i.Distance).First(i => (i.Angle <toAngle || i.Angle> fromAngle)));
            }
            else
            {
                return(Distances[Config.DefaultVerticalAngle].OrderByDescending(i => i.Distance).First(i => (i.Angle > fromAngle && i.Angle < toAngle)));
            }
            //TODO: Check what happens if there is no available distance in range
        }
        public List <float> GetDistancesInRange(float fromAngle, float toAngle, VerticalAngle verticalAngle)
        {
            if (Distances == null || (!Distances.ContainsKey(verticalAngle)))
            {
                return new List <float>()
                       {
                           float.NaN
                       }
            }
            ;

            List <float>           distancesInRange        = new List <float>();
            List <HorizontalPoint> horizontalPointsInRange = GetHorizontalPointsInRange(fromAngle, toAngle, verticalAngle);

            foreach (HorizontalPoint point in horizontalPointsInRange)
            {
                distancesInRange.Add(point.Distance);
            }

            return(distancesInRange);
        }
Пример #8
0
        private void UpdateDist(int id_1, int id_2, float dist)
        {
            if (id_1 == id_2)
            {
                dist = 0;
            }

            if (!Distances.ContainsKey(id_1))
            {
                Distances.Add(id_1, new Dictionary <int, float>());
            }

            if (!Distances.ContainsKey(id_2))
            {
                Distances.Add(id_2, new Dictionary <int, float>());
            }

            Distances.TryGetValue(id_1, out var distance_table_1);
            Distances.TryGetValue(id_2, out var distance_table_2);

            if (!distance_table_2.TryGetValue(id_1, out var current_dist))
            {
                distance_table_2.Add(id_1, dist);
            }
            else
            {
                distance_table_2[id_1] = Math.Min(current_dist, dist);
            }


            if (!distance_table_1.TryGetValue(id_2, out current_dist))
            {
                distance_table_1.Add(id_2, dist);
            }
            else
            {
                distance_table_1[id_2] = Math.Min(current_dist, dist);
            }
        }
Пример #9
0
        public Distances CellDistances()
        {
            var distances = new Distances(this);
            var frontier = new List<Cell>() { this };

            while (frontier.Count > 0)
            {
                var newFrontier = new List<Cell>();
                foreach (var cell in frontier)
                {
                    foreach (var linked in cell.Links)
                    {
                        if (!distances.ContainsKey(linked))
                        {
                            distances.Add(linked, distances[cell] + 1);
                            newFrontier.Add(linked);
                        }
                    }
                }
                frontier = newFrontier;
            }
            return distances;
        }
Пример #10
0
    public bool Move(Point destination)
    {
        UpdatePathingData();
        if (!Distances.ContainsKey(destination))
        {
            return(false);
        }
        if (Path.Count != 0)
        {
            return(false);
        }

        IsMoving = true;

        Point prev = destination;

        Path.Push(destination);
        while (Paths[prev] != Position)
        {
            Path.Push(Paths[prev]);
            prev = Paths[prev];
        }

        Directions CardDirection = Position.GetDirection(Path.Peek());

        _deathEvent.OnFacingChanged(CardDirection);
        Previous = Path.Peek();
        Dest     = Path.Pop().ToWorldPoint();

        this.PostNotification(Notifications.ACTOR_LEFT_POINT, Position);

        Position = destination;

        this.PostNotification(Notifications.ACTOR_ENTERED_POINT, Position);

        return(true);
    }
Пример #11
0
        public string Solve()
        {
            long maxDistance = Distances.Keys.Max();

            while (Distances[maxDistance] < Guests)
            {
                long takeGuests = Distances[maxDistance];
                Distances.Remove(maxDistance);
                Guests -= takeGuests;

                if (maxDistance % 2 == 1)
                {
                    long newDistance = (maxDistance - 1) / 2;
                    if (!Distances.ContainsKey(newDistance))
                    {
                        Distances[newDistance] = 0;
                    }

                    Distances[newDistance] += takeGuests * 2;
                }
                else
                {
                    long newDistance1 = maxDistance / 2;
                    long newDistance2 = newDistance1 - 1;

                    if (!Distances.ContainsKey(newDistance1))
                    {
                        Distances[newDistance1] = 0;
                    }

                    if (!Distances.ContainsKey(newDistance2))
                    {
                        Distances[newDistance2] = 0;
                    }

                    Distances[newDistance1] += takeGuests;
                    Distances[newDistance2] += takeGuests;
                }

                maxDistance = Distances.Keys.Max();

                if (maxDistance == 0)
                {
                    break;
                }
            }

            long lMin;
            long lMax;

            if (maxDistance == 0)
            {
                lMin = 0;
                lMax = 0;
            }
            else if (maxDistance % 2 == 1)
            {
                lMin = (maxDistance - 1) / 2;
                lMax = lMin;
            }
            else
            {
                lMax = maxDistance / 2;
                lMin = lMax - 1;
            }

            return(lMax.ToString() + " " + lMin.ToString());
        }
Пример #12
0
    public Distances DFSPathTo(MazeCell goal)
    {
        Stack <MazeCell> stack = new Stack <MazeCell>();

        stack.Push(this.startingCell);

        Distances distances = new Distances(startingCell);

        var current = startingCell;

        while (current != goal)
        {
            current = stack.Peek();

            foreach (var linkedCell in current.Links())
            {
                if (distances.ContainsKey(linkedCell))
                {
                    continue;
                }
                distances.Add(linkedCell, distances[current] + 1);

                if (linkedCell == goal)
                {
                    current = linkedCell;
                    break;
                }

                if (stack.Contains(linkedCell))
                {
                    continue;
                }
                stack.Push(linkedCell);
            }
        }

        Distances breadcrumbs = new Distances(this.startingCell);

        breadcrumbs.Add(current, distances[current]);

        while (current != startingCell)
        {
            foreach (MazeCell neighbour in current.Links())
            {
                if (distances[neighbour] < distances[current])
                {
                    if (!breadcrumbs.ContainsKey(neighbour))
                    {
                        breadcrumbs.Add(neighbour, distances[neighbour]);
                    }
                    else
                    {
                        breadcrumbs[neighbour] = distances[neighbour];
                    }
                    current = neighbour;
                    break;
                }
            }
        }

        return(breadcrumbs);
    }
Пример #13
0
    public Distances BFSMeetInMiddlePathTo(MazeCell goal)
    {
        Queue <MazeCell> grayQueueWithStartingCell = new Queue <MazeCell>();
        Queue <MazeCell> grayQueueWithGoalCell     = new Queue <MazeCell>();

        grayQueueWithStartingCell.Enqueue(this.startingCell);
        grayQueueWithGoalCell.Enqueue(goal);

        Distances distancesStarting = new Distances(startingCell);
        Distances distancesGoal     = new Distances(goal);

        bool notFound = true;

        var currentCell = startingCell;

        while (notFound)
        {
            currentCell = grayQueueWithStartingCell.Dequeue();

            foreach (var linkedCell in currentCell.Links())
            {
                if (distancesGoal.ContainsKey(linkedCell))
                {
                    notFound = false;
                    if (!distancesStarting.ContainsKey(linkedCell))
                    {
                        distancesStarting.Add(linkedCell, distancesStarting[currentCell] + 1);
                    }
                    currentCell = linkedCell;
                    break;
                }

                if (distancesStarting.ContainsKey(linkedCell))
                {
                    continue;
                }
                distancesStarting.Add(linkedCell, distancesStarting[currentCell] + 1);

                if (grayQueueWithStartingCell.Contains(linkedCell))
                {
                    continue;
                }
                grayQueueWithStartingCell.Enqueue(linkedCell);
            }

            if (!notFound)
            {
                break;
            }

            currentCell = grayQueueWithGoalCell.Dequeue();

            foreach (var linkedCell in currentCell.Links())
            {
                if (distancesStarting.ContainsKey(linkedCell))
                {
                    notFound = false;
                    if (!distancesGoal.ContainsKey(linkedCell))
                    {
                        distancesGoal.Add(linkedCell, distancesGoal[currentCell] + 1);
                    }
                    currentCell = linkedCell;
                    break;
                }

                if (distancesGoal.ContainsKey(linkedCell))
                {
                    continue;
                }
                distancesGoal.Add(linkedCell, distancesGoal[currentCell] + 1);

                if (grayQueueWithGoalCell.Contains(linkedCell))
                {
                    continue;
                }
                grayQueueWithGoalCell.Enqueue(linkedCell);
            }
        }

        Distances breadcrumbs = new Distances(this.startingCell);

        breadcrumbs.Add(currentCell, distancesStarting[currentCell]);

        MazeCell breadcrumbsCurrent = currentCell;

        while (currentCell != startingCell)
        {
            foreach (MazeCell neighbour in currentCell.Links())
            {
                if (!distancesStarting.ContainsKey(neighbour))
                {
                    continue;
                }

                if (distancesStarting[neighbour] < distancesStarting[currentCell])
                {
                    if (!breadcrumbs.ContainsKey(neighbour))
                    {
                        breadcrumbs.Add(neighbour, distancesStarting[neighbour]);
                    }
                    else
                    {
                        breadcrumbs[neighbour] = distancesStarting[neighbour];
                    }

                    currentCell = neighbour;
                    break;
                }
            }
        }

        currentCell = breadcrumbsCurrent;
        Distances breadcrumbsGoal = new Distances(goal);

        while (currentCell != goal)
        {
            foreach (MazeCell neighbour in currentCell.Links())
            {
                if (!distancesGoal.ContainsKey(neighbour))
                {
                    continue;
                }

                if (distancesGoal[neighbour] < distancesGoal[currentCell])
                {
                    if (!breadcrumbsGoal.ContainsKey(neighbour))
                    {
                        breadcrumbsGoal.Add(neighbour, distancesGoal[neighbour]);
                    }
                    else
                    {
                        breadcrumbsGoal[neighbour] = distancesGoal[neighbour];
                    }

                    currentCell = neighbour;
                    break;
                }
            }
        }

        MazeCell maxCell = null;
        MazeCell minCell = null;

        int max = breadcrumbsGoal.MaxDistanceValue();
        int min = breadcrumbsGoal.MinDistanceValue();

        while (max > min)
        {
            foreach (MazeCell cell in breadcrumbsGoal.Keys)
            {
                if (breadcrumbsGoal[cell] == min)
                {
                    minCell = cell;
                }

                if (breadcrumbsGoal[cell] == max)
                {
                    maxCell = cell;
                }
            }

            breadcrumbsGoal[minCell] = max;
            breadcrumbsGoal[maxCell] = min;
            max--;
            min++;
        }

        max = breadcrumbs.MaxDistanceValue();
        max++;

        foreach (MazeCell cell in breadcrumbsGoal.Keys)
        {
            breadcrumbs.Add(cell, breadcrumbsGoal[cell] + max);
        }

        return(breadcrumbs);
    }
Пример #14
0
    public Distances BFSPathTo(MazeCell goal)
    {
        Queue <MazeCell> grayQueue = new Queue <MazeCell>();

        grayQueue.Enqueue(this.startingCell);

        Distances distances = new Distances(startingCell);

        var current = startingCell;

        while (current != goal)
        {
            current = grayQueue.Dequeue();

            foreach (var linkedCell in current.Links())
            {
                if (distances.ContainsKey(linkedCell))
                {
                    continue;
                }
                if (linkedCell == goal)
                {
                    distances.Add(linkedCell, distances[current] + 1);
                    current = linkedCell;
                    break;
                }

                distances.Add(linkedCell, distances[current] + 1);

                if (grayQueue.Contains(linkedCell))
                {
                    continue;
                }
                grayQueue.Enqueue(linkedCell);
            }
        }

        Distances pathToGoal = new Distances(this.startingCell);

        pathToGoal.Add(current, distances[current]);

        while (current != startingCell)
        {
            foreach (MazeCell neighbour in current.Links())
            {
                if (distances[neighbour] < distances[current])
                {
                    if (!pathToGoal.ContainsKey(neighbour))
                    {
                        pathToGoal.Add(neighbour, distances[neighbour]);
                    }
                    else
                    {
                        pathToGoal[neighbour] = distances[neighbour];
                    }
                    current = neighbour;
                    break;
                }
            }
        }

        return(pathToGoal);
    }