// 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); }
//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)); }
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); }
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); } }
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; }
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); }
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()); }
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); }
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); }
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); }