/// <summary> /// Do unit selection. /// </summary> /// <param name="searchConfig">Search configuration.</param> /// <returns>The best path.</returns> public List<PathNodeInfo> UnitSelecting(SearchConfig searchConfig) { ILatticeProvider latticeProvider = searchConfig.LatticeProvider; ITargetCostCalculator targetCostCalculator = searchConfig.TargetCostCalculator; IJoinCalculator joinCostCalculator = searchConfig.JoinCostCalculator; int targetCount = latticeProvider.GetColumnCount(); if (targetCount == 0) { string message = Helper.NeutralFormat("The ILatticeProvider contains 0 targets!"); throw new InvalidDataException(message); } List<PathNodeInfo> bestPath = new List<PathNodeInfo>(targetCount); TargetNode[] targets = new TargetNode[targetCount]; LatticeNode[][] lattice = new LatticeNode[targetCount][]; for (int i = 0; i < targetCount; i++) { int candidateCount = latticeProvider.GetRowCount(i); if (candidateCount == 0) { string message = Helper.NeutralFormat("The ILatticeProvider contains 0 candidates for target {0}!", i); throw new InvalidDataException(message); } targets[i] = new TargetNode(latticeProvider.GetTarget(i), candidateCount); lattice[i] = new LatticeNode[candidateCount]; for (int j = 0; j < candidateCount; j++) { PathNodeInfo pathNodeInfo = new PathNodeInfo(latticeProvider.GetCandidate(i, j), float.PositiveInfinity, float.PositiveInfinity); lattice[i][j] = new LatticeNode(pathNodeInfo, float.PositiveInfinity, -1); } } for (int i = 0; i < targets[0].CandidateCount; i++) { LatticeNode nodeCur = lattice[0][i]; float targetCost = targetCostCalculator.GetTargetCost(targets[0].Target, nodeCur.PathNodeInfo.Candidate); nodeCur.BestScore = targetCost; nodeCur.PathNodeInfo.TargetCost = targetCost; } for (int col = 1; col < targetCount; col++) { TargetNode targetCur = targets[col]; TargetNode targetLeft = targets[col - 1]; for (int i = 0; i < targetCur.CandidateCount; i++) { LatticeNode nodeCur = lattice[col][i]; LatticeNode nodeLeft = lattice[col - 1][0]; float joinCost = joinCostCalculator.GetJoinCost(targetLeft.Target, targetCur.Target, nodeLeft.PathNodeInfo.Candidate, nodeCur.PathNodeInfo.Candidate); float bestPreScore = nodeLeft.BestScore + joinCost; int bestPreNodeIndex = 0; float bestJoinCost = joinCost; for (int j = 1; j < targets[col - 1].CandidateCount; j++) { nodeLeft = lattice[col - 1][j]; joinCost = joinCostCalculator.GetJoinCost(targetLeft.Target, targetCur.Target, nodeLeft.PathNodeInfo.Candidate, nodeCur.PathNodeInfo.Candidate); float preCost = nodeLeft.BestScore + joinCost; if (preCost < bestPreScore) { bestPreScore = preCost; bestPreNodeIndex = j; bestJoinCost = joinCost; } } float targetCost = targetCostCalculator.GetTargetCost(targetCur.Target, nodeCur.PathNodeInfo.Candidate); nodeCur.BestScore = bestPreScore + targetCost; nodeCur.BestPreNodeIndex = bestPreNodeIndex; nodeCur.PathNodeInfo.TargetCost = targetCost; nodeCur.PathNodeInfo.JoinCost = bestJoinCost; } } int columnIndex = targetCount - 1; LatticeNode bestNode = lattice[columnIndex][0]; float bestScore = bestNode.BestScore; for (int i = 1; i < targets[columnIndex].CandidateCount; i++) { LatticeNode curNode = lattice[columnIndex][i]; if (curNode.BestScore < bestScore) { bestNode = curNode; bestScore = bestNode.BestScore; } } while (true) { bestPath.Add(bestNode.PathNodeInfo); columnIndex--; if (columnIndex < 0) { break; } bestNode = lattice[columnIndex][bestNode.BestPreNodeIndex]; } bestPath.Reverse(); return bestPath; }
//搜索路径算法,根据DJ算法生成最短路径 public bool FindPath(AutoSearchPoint startPoint, AutoSearchPoint endPoint, ref AutoSearchPath autoSearchPath) { List <int> path = new List <int>(); //最后生成的最短路径图 //统计所有节点,计算srcid的逆临街表,放在nodeMap中 Dictionary <int, PathNodeInfo> nodeMap = new Dictionary <int, PathNodeInfo>(); foreach (MapConnectPath connectPath in m_ConnectPath) { if (false == nodeMap.ContainsKey(connectPath.SrcSceneId)) { PathNodeInfo info = new PathNodeInfo(); info.sceneId = connectPath.SrcSceneId; info.dis = GetDisBySceneID(startPoint.SceneID, info.sceneId); info.prevNode = startPoint.SceneID; nodeMap.Add(info.sceneId, info); } if (false == nodeMap.ContainsKey(connectPath.DstSceneId)) { PathNodeInfo info = new PathNodeInfo(); info.sceneId = connectPath.DstSceneId; info.dis = GetDisBySceneID(startPoint.SceneID, info.sceneId); info.prevNode = startPoint.SceneID; nodeMap.Add(info.sceneId, info); } } List <int> openList = new List <int>(); List <int> closeList = new List <int>(); //放入开始点 openList.Add(startPoint.SceneID); while (openList.Count > 0) { int minPt = openList[0]; int minDis = m_nMinDistanceMaxValue; foreach (int openPoint in openList) { if (!nodeMap.ContainsKey(openPoint)) { continue; } if (nodeMap[openPoint].dis < minDis) { minPt = openPoint; minDis = nodeMap[openPoint].dis; } } int minDisNode = minPt; openList.Remove(minDisNode); closeList.Add(minDisNode); //展开该节点,更新所有邻接表的距离,并把下一个(或几个)最短路径上的点放入openList。 foreach (MapConnectPath connectPath in m_ConnectPath) { if (connectPath.SrcSceneId == minDisNode) { int newDis = nodeMap[minDisNode].dis + GetDisBySceneID(minDisNode, connectPath.DstSceneId); if (newDis < nodeMap[connectPath.DstSceneId].dis) { nodeMap[connectPath.DstSceneId].dis = newDis; nodeMap[connectPath.DstSceneId].prevNode = minDisNode; } if (!openList.Contains(connectPath.DstSceneId) && !closeList.Contains(connectPath.DstSceneId)) { openList.Add(connectPath.DstSceneId); } } } } if (!nodeMap.ContainsKey(endPoint.SceneID)) { return(false); } //这里生成最短路径和下一个场景号,这里的邻接表已经记录了最短路径信息 if (nodeMap[endPoint.SceneID].dis < m_nMinDistanceMaxValue) { path.Insert(0, endPoint.SceneID); int backId = nodeMap[endPoint.SceneID].prevNode; while (backId != -1) { if (backId == startPoint.SceneID) { //int nextScn = path[0]; path.Insert(0, backId); break; } path.Insert(0, backId); backId = nodeMap[backId].prevNode; } } if (path.Count > 1) { //生成路径 int beginScene = path[0]; int endScene = -1; for (int i = 1; i < path.Count; ++i) { endScene = path[i]; foreach (MapConnectPath connectPath in m_ConnectPath) { if (connectPath.SrcSceneId == beginScene && connectPath.DstSceneId == endScene) { AutoSearchPoint point = new AutoSearchPoint(connectPath.SrcSceneId, connectPath.TelePosX, connectPath.TelePosZ); autoSearchPath.AutoSearchPosCache.Add(point); beginScene = endScene; } } } //最后加入目标点 autoSearchPath.AutoSearchPosCache.Add(endPoint); return(true); } return(false); }
public LatticeNode(PathNodeInfo pathNodeInfo, float bestScore, int bestPreNodeIndex) { this.PathNodeInfo = pathNodeInfo; this.BestScore = bestScore; this.BestPreNodeIndex = bestPreNodeIndex; }