public IEnumerable<ICell> ProcessTest( [PexAssumeUnderTest]global::PathfindingAlgorithms.Algorithms.Astar.Astar target, ICell[,] cells, Coordinates from, Coordinates to ) { PexAssume.IsNotNull(cells); PexAssume.IsTrue(cells.GetLength(0)* cells.GetLength(1) > 0); PexAssume.IsTrue(from.Inside(new Coordinates(cells.GetLength(0) - 1, cells.GetLength(1) - 1))); PexAssume.IsTrue(to.Inside(new Coordinates(cells.GetLength(0) - 1, cells.GetLength(1) - 1))); PexAssume.IsTrue(cells.GetLowerBound(0) == 0); PexAssume.IsTrue(cells.GetLowerBound(1) == 0); bool f = true; for (int x = cells.GetLowerBound(0); x <= cells.GetUpperBound(0); x++) { for (int y = cells.GetLowerBound(1); y <= cells.GetUpperBound(1); y++) { PexAssume.IsNotNull(cells[x, y]); PexAssume.IsNotNull(cells[x, y].Coordinates); f &= cells[x, y].Coordinates.Equals(new Coordinates(x, y)); } } PexAssume.IsTrue(f); IEnumerable<ICell> result = target.Process(cells, from, to); return result; // TODO: добавление проверочных утверждений в метод AstarTest.ProcessTest(Astar, ICell[,], Coordinates, Coordinates) }
public IEnumerable<ICell> Process(ICell[,] cells, Coordinates from, Coordinates to) { try { Contract.Requires(cells != null); Contract.Requires(from.Inside(new Coordinates(cells.GetLength(0), cells.GetLength(1)))); Contract.Requires(to.Inside(new Coordinates(cells.GetLength(0), cells.GetLength(1)))); InitData(cells, from, to); plannedNodes.Add(startCoord); while (plannedNodes.Count > 0) { //находим в запланированных вершину с наименьшей эвристической стоимостью var cur = TakeMinimalHeuristic(); //если найденная - пункт назначения, то заканчиваем поиск и начинаем сборку пути if (cur == goalCoord) break; CellData curData = data[cur]; curData.processed = true; //рассматриваем все с ней смежные, необработанные ранее var adjList = adjacement.Adjacement(grid, cur); foreach (Coordinates adj in adjList.Where(c => !data[c].processed)) { //определяем стоимость смежной вершины на основе уже пройденного пути double score = curData.scoreCalc + Score(grid.At(adj)); //если вершина не была посещена, или в неё можно прийти более коротким путём - обновляем информацию bool notFound = !plannedNodes.Contains(adj); CellData adjData = data[adj]; if (notFound || score < adjData.scoreCalc) { adjData.cameFrom = cur; adjData.scoreCalc = score; adjData.scoreHeur = score + Heuristic(grid.At(adj)); //если вершина ещё не была посещена - запланируем посещение if (notFound) plannedNodes.Add(adj); } } } return AssemblePath(); } catch (KeyNotFoundException) { throw new IndexOutOfRangeException(); } }
public IEnumerable<ICell> Process(ICell[,] cellMap, Coordinates start, Coordinates end) { Contract.Requires(cellMap != null); Contract.Requires(start.Inside(new Coordinates(cellMap.GetLength(0), cellMap.GetLength(1)))); Contract.Requires(end.Inside(new Coordinates(cellMap.GetLength(0), cellMap.GetLength(1)))); DNode[,] dist = new DNode[cellMap.GetLength(0), cellMap.GetLength(1)]; int count = cellMap.GetLength(0) * cellMap.GetLength(1); for (int i = 0; i < cellMap.GetLength(0); ++i) for (int j = 0; j < cellMap.GetLength(1); ++j) dist[i, j] = new DNode(); dist[start.X, start.Y].val = 0; Coordinates? min = null; do { min = FindMin(dist); if (min.HasValue) { CheckForeign(cellMap, dist, min.Value); dist[min.Value.X, min.Value.Y].visited = true; } } while (min.HasValue); int waylen = 0; DNode dnode = dist[end.X, end.Y]; while (dnode.prev.HasValue) { ++waylen; dnode = dist[dnode.prev.Value.X, dnode.prev.Value.Y]; } if (waylen > 0) { ICell[] res = new ICell[waylen + 1]; res[waylen] = cellMap[end.X, end.Y]; int i = waylen - 1; dnode = dist[end.X, end.Y]; while (dnode.prev.HasValue) { res[i--] = cellMap[dnode.prev.Value.X, dnode.prev.Value.Y]; dnode = dist[dnode.prev.Value.X, dnode.prev.Value.Y]; } return res; } else { return new LinkedList<ICell>(); } }