/// <summary> /// 寻找到目的地的每一条路径 写的不明不白 大致思路是增加被使用过的节点的成本 /// 使得其他选择者去选择不重复的路径 /// </summary> /// <param name="src"></param> /// <param name="dst"></param> /// <param name="lurker"></param> /// <param name="lurkers"></param> /// <param name="h"></param> /// <returns></returns> public List <Vertex> AStartMbush(Vertex src, Vertex dst, Lurker lurker, List <Lurker> lurkers, Heuristic h = null) { int graphSize = vertices.Count; float[] extra = new float[graphSize]; float[] costs = new float[graphSize]; // 初始化统计数组 for (int i = 0; i < graphSize; i++) { extra[i] = 1f; costs[i] = Mathf.Infinity; } foreach (Lurker l in lurkers) { foreach (Vertex v in l.path) { extra[v.id] += 1f; } } // 定义和初始化用于计算A*的变量 Edge[] successirs; int[] previous = new int[graphSize]; for (int i = 0; i < graphSize; i++) { previous[i] = -1; } previous[src.id] = src.id; float cost = 0; Edge node = new Edge(src, 0); BinaryHeap <Edge> frontier = new BinaryHeap <Edge>(); // 加入根节点,开始进行A*计算 frontier.Add(node); while (frontier.Count != 0) { if (frontier.Count == 0) { return(new List <Vertex>()); } node = frontier.Pop(); if (ReferenceEquals(node.vertex, dst)) { return(BuildPath(src.id, node.vertex.id, ref previous)); } int nodeId = node.vertex.id; // 该导航点在此路径中的代价高于在其他路径的代价 则不选用 if (node.cost > costs[nodeId]) { continue; } successirs = GetEdges(node.vertex); foreach (Edge e in successirs) { int eId = e.vertex.id; if (previous[eId] != -1) // 排除已经记录过的导航点 { continue; } cost = e.cost; cost += costs[dst.id]; // 这个值没有赋值过吧? cost += h(e.vertex, dst); if (cost < costs[eId]) { Edge child; child = new Edge(e.vertex, cost); costs[eId] = cost; previous[eId] = nodeId; frontier.Remove(e); frontier.Add(child); } } } return(new List <Vertex>()); }
public List <Vertex> AStarMbush( Vertex src, Vertex dst, Lurker agent, List <Lurker> lurkers, Heuristic h = null) { if (ReferenceEquals(h, null)) { h = EuclidDist; } int graphSize = vertices.Count; float[] extra = new float[graphSize]; float[] costs = new float[graphSize]; int i; for (i = 0; i < graphSize; i++) { extra[i] = 1f; costs[i] = Mathf.Infinity; } foreach (Lurker l in lurkers) { foreach (Vertex v in l.path) { extra[v.id] += 1f; } } Edge[] successors; int[] previous = new int[graphSize]; for (i = 0; i < graphSize; i++) { previous[i] = -1; } previous[src.id] = src.id; float cost = 0; Edge node = new Edge(src, 0); GPWiki.BinaryHeap <Edge> frontier = new GPWiki.BinaryHeap <Edge>(); frontier.Add(node); while (frontier.Count != 0) { node = frontier.Remove(); if (ReferenceEquals(node.vertex, dst)) { return(BuildPath(src.id, node.vertex.id, ref previous)); } int nodeId = node.vertex.id; if (node.cost > costs[nodeId]) { continue; } successors = GetEdges(node.vertex); foreach (Edge e in successors) { int eId = e.vertex.id; if (previous[eId] != -1) { continue; } cost = e.cost; cost += costs[dst.id]; cost += h(e.vertex, dst); if (cost < costs[e.vertex.id]) { Edge child; child = new Edge(e.vertex, cost); costs[eId] = cost; previous[eId] = nodeId; frontier.Remove(e); frontier.Add(child); } } } return(new List <Vertex>()); }
//the A*Ambush algorithm analyzes the path of every agent to the target and //increases the cost of that route. When an agent computes the path with A*, //it chooses a different route that the ones chosen by the other agents //creating the sense of an ambush private List <Vertex> AStarAmbush(Vertex src, Vertex dst, Lurker agent, List <Lurker> lurkers, Heuristic h = null) { int graphSize = vertices.Count; float[] extra = new float[graphSize]; float[] costs = new float[graphSize]; //initialize regular cost and extra cost variables for (int i = 0; i < graphSize; i++) { extra[i] = 1f; costs[i] = Mathf.Infinity; } //add the extra cost to each vertex that is contained in another agent's path foreach (Lurker l in lurkers) { foreach (Vertex v in l.path) { extra[v.id] += 1f; } } Edge[] successors; int[] previous = new int[graphSize]; for (int i = 0; i < graphSize; i++) { previous[i] = -1; } previous[src.id] = src.id; float cost = 0; Edge node = new Edge(src, 0); BinaryHeap <Edge> frontier = new BinaryHeap <Edge>(); //A* main loop frontier.Add(node); while (frontier.Count != 0) { if (frontier.Count == 0) { return(new List <Vertex>()); } //validate that the goal has already been reached, //otherwise it's not worth computing the costs node = frontier.Remove(); if (ReferenceEquals(node.vertex, dst)) { return(BuildPath(src.id, node.vertex.id, ref previous)); } int nodeId = node.vertex.id; if (node.cost > costs[nodeId]) { continue; } //traverse the neighbours and check whether they have been visited successors = GetEdges(node.vertex); foreach (Edge e in successors) { int eId = e.vertex.id; if (previous[eId] != -1) { continue; } //if they have not been visited add them to the frontier cost = e.cost; cost += costs[dst.id]; cost += h(e.vertex, dst); if (cost < costs[e.vertex.id]) { Edge child = new Edge(e.vertex, cost); costs[eId] = cost; previous[eId] = nodeId; frontier.Remove(e); frontier.Add(child); } } } return(new List <Vertex>()); }