private void Generate() { HierarchicalMapFactory factory = new HierarchicalMapFactory(); HierarchicalMap hierarchicalMap = factory.CreateHierarchicalMap(m_concreteMap, m_clusterSize, m_maxLevel); List <PathNode> path = HierarchicalSearch.Search(factory, hierarchicalMap, m_maxLevel, m_startNode.Pos, m_goalNode.Pos); for (int i = 0; i < path.Count; i++) { var node = m_concreteMap.Get(path[i].Pos); node.SetSearchType(SearchType.Path); } }
public void CreateHierarchicalMap_WhenCreating_Return() { var abstractMapFactory = new HierarchicalMapFactory(); var passability = new Program.ExamplePassability(); var concreteMap = ConcreteMapFactory.CreateConcreteMap(40, 40, passability); var hierarchicalMap = abstractMapFactory.CreateHierarchicalMap(concreteMap, 10, 2, EntranceStyle.EndEntrance); Assert.AreEqual(16, hierarchicalMap.Clusters.Count); Assert.AreEqual(10, hierarchicalMap.ClusterSize); Assert.AreEqual(40, hierarchicalMap.Height); Assert.AreEqual(40, hierarchicalMap.Width); Assert.AreEqual(2, hierarchicalMap.MaxLevel); Assert.AreEqual(AbsType.ABSTRACT_OCTILE, hierarchicalMap.Type); Assert.NotNull(hierarchicalMap.AbstractGraph); }
public static List <PathNode> Search(HierarchicalMapFactory factory, HierarchicalMap map, int maxLevel, Vector2Int startPos, Vector2Int goalPos, int maxRefineCount = int.MaxValue) { //首先插入起点和终点到图中 var startAbsId = factory.InsertAbstractNode(map, startPos); var goalAbsId = factory.InsertAbstractNode(map, goalPos); var path = SearchImpl(map, startAbsId, goalAbsId, maxLevel, maxRefineCount); //可以在这里应用路径平滑 //搜索完毕后就移除起点和终点(如果常用,也可以留着) factory.RemoveAbstractNode(map, goalAbsId); factory.RemoveAbstractNode(map, startAbsId); return(path); }
private static List <IPathNode> HierarchicalSearch(HierarchicalMap hierarchicalMap, int maxLevel, ConcreteMap concreteMap, Position startPosition, Position endPosition) { var factory = new HierarchicalMapFactory(); var startAbsNode = factory.InsertAbstractNode(hierarchicalMap, startPosition); var targetAbsNode = factory.InsertAbstractNode(hierarchicalMap, endPosition); var maxPathsToRefine = int.MaxValue; var hierarchicalSearch = new HierarchicalSearch(); var abstractPath = hierarchicalSearch.DoHierarchicalSearch(hierarchicalMap, startAbsNode, targetAbsNode, maxLevel, maxPathsToRefine); var path = hierarchicalSearch.AbstractPathToLowLevelPath(hierarchicalMap, abstractPath, hierarchicalMap.Width, maxPathsToRefine); var smoother = new SmoothWizard(concreteMap, path); path = smoother.SmoothPath(); factory.RemoveAbstractNode(hierarchicalMap, targetAbsNode); factory.RemoveAbstractNode(hierarchicalMap, startAbsNode); return(path); }
public static void Main2(string[] args) { const int clusterSize = 8; const int maxLevel = 2; const int height = 128; const int width = 128; Position startPosition = new Position(17, 38); Position endPosition = new Position(16, 18); // Prepare the abstract graph beforehand IPassability passability = new FakePassability(width, height); var concreteMap = ConcreteMapFactory.CreateConcreteMap(width, height, passability); var abstractMapFactory = new HierarchicalMapFactory(); var absTiling = abstractMapFactory.CreateHierarchicalMap(concreteMap, clusterSize, maxLevel, EntranceStyle.EndEntrance); var watch = Stopwatch.StartNew(); var regularSearchPath = RegularSearch(concreteMap, startPosition, endPosition); var regularSearchTime = watch.ElapsedMilliseconds; watch = Stopwatch.StartNew(); var hierarchicalSearchPath = HierarchicalSearch(absTiling, maxLevel, concreteMap, startPosition, endPosition); var hierarchicalSearchTime = watch.ElapsedMilliseconds; var pospath = hierarchicalSearchPath.Select(p => { if (p is ConcretePathNode) { var concretePathNode = (ConcretePathNode)p; return(concreteMap.Graph.GetNodeInfo(concretePathNode.Id).Position); } var abstractPathNode = (AbstractPathNode)p; return(absTiling.AbstractGraph.GetNodeInfo(abstractPathNode.Id).Position); }).ToList(); #if !DEBUG Console.WriteLine("Regular search: " + regularSearchTime + " ms"); Console.WriteLine("Number of nodes: " + regularSearchPath.Count); Console.WriteLine("Hierachical search: " + hierarchicalSearchTime + " ms"); Console.WriteLine("Number of nodes: " + hierarchicalSearchPath.Count); #endif #if DEBUG //Console.WriteLine("Regular search: " + regularSearchTime + " ms"); //Console.WriteLine($"{regularSearchPath.Count} path nodes"); //PrintFormatted(concreteMap, absTiling, clusterSize, regularSearchPath); //Console.WriteLine(); //Console.WriteLine(); //Console.WriteLine(); Console.WriteLine("Hierachical search: " + hierarchicalSearchTime + " ms"); Console.WriteLine($"{hierarchicalSearchPath.Count} path nodes"); PrintFormatted(concreteMap, absTiling, clusterSize, pospath); Console.WriteLine(); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Press any key to quit..."); Console.ReadKey(); #endif }
public static void Main(string[] args) { const int clusterSize = 8; const int maxLevel = 2; const int height = 128; const int width = 128; //IPassability passability = new ExamplePassability(); IPassability passability = new FakePassability(width, height); var concreteMap = ConcreteMapFactory.CreateConcreteMap(width, height, passability); var abstractMapFactory = new HierarchicalMapFactory(); var absTiling = abstractMapFactory.CreateHierarchicalMap(concreteMap, clusterSize, maxLevel, EntranceStyle.EndEntrance); //var edges = absTiling.AbstractGraph.Nodes.SelectMany(x => x.Edges.Values) // .GroupBy(x => x.Info.Level) // .ToDictionary(x => x.Key, x => x.Count()); Func <Position, Position, List <IPathNode> > doHierarchicalSearch = (startPosition, endPosition) => HierarchicalSearch(absTiling, maxLevel, concreteMap, startPosition, endPosition); Func <Position, Position, List <IPathNode> > doRegularSearch = (startPosition, endPosition) => RegularSearch(concreteMap, startPosition, endPosition); Func <List <IPathNode>, List <Position> > toPositionPath = (path) => path.Select(p => { if (p is ConcretePathNode) { var concretePathNode = (ConcretePathNode)p; return(concreteMap.Graph.GetNodeInfo(concretePathNode.Id).Position); } var abstractPathNode = (AbstractPathNode)p; return(absTiling.AbstractGraph.GetNodeInfo(abstractPathNode.Id).Position); }).ToList(); //Position startPosition2 = new Position(18, 0); //Position endPosition2 = new Position(20, 0); var points = Enumerable.Range(0, 2000).Select(_ => { var pos1 = ((FakePassability)passability).GetRandomFreePosition(); var pos2 = ((FakePassability)passability).GetRandomFreePosition(); while (Math.Abs(pos1.X - pos2.X) + Math.Abs(pos1.Y - pos2.Y) < 10) { pos2 = ((FakePassability)passability).GetRandomFreePosition(); } return(Tuple.Create(pos1, pos2)); }).ToArray(); var searchStrategies = new[] { doRegularSearch, doHierarchicalSearch }; foreach (var searchStrategy in searchStrategies) { var watch = Stopwatch.StartNew(); for (int i = 0; i < points.Length; i++) { Position startPosition2 = points[i].Item1; Position endPosition2 = points[i].Item2; var regularSearchPath = searchStrategy(startPosition2, endPosition2); var posPath1 = toPositionPath(regularSearchPath); } var regularSearchTime = watch.ElapsedMilliseconds; Console.WriteLine(regularSearchTime); } }