public List <Vertex> GetPathDijkstra(GameObject srcObj, GameObject dstObj) { if (srcObj == null || dstObj == null) { return(new List <Vertex>()); } Vertex src = GetNearestVertex(srcObj.transform.position); Vertex dst = GetNearestVertex(dstObj.transform.position); GPWiki.BinaryHeap <Edge> frontier = new GPWiki.BinaryHeap <Edge>(); Edge[] edges; Edge node, child; int size = vertices.Count; float[] distValue = new float[size]; int[] previous = new int[size]; node = new Edge(src, 0); frontier.Add(node); distValue[src.id] = 0; previous[src.id] = src.id; for (int i = 0; i < size; i++) { if (i == src.id) { continue; } distValue[i] = Mathf.Infinity; previous[i] = -1; } while (frontier.Count != 0) { node = frontier.Remove(); int nodeId = node.vertex.id; // exit if necessary if (ReferenceEquals(node.vertex, dst)) { return(BuildPath(src.id, node.vertex.id, ref previous)); } edges = GetEdges(node.vertex); foreach (Edge e in edges) { int eId = e.vertex.id; if (previous[eId] != -1) { continue; } float cost = distValue[nodeId] + e.cost; if (cost < distValue[e.vertex.id]) { distValue[eId] = cost; previous[eId] = nodeId; frontier.Remove(e); child = new Edge(e.vertex, cost); frontier.Add(child); } } } return(new List <Vertex>()); }
/// <summary> /// Returns the shortest path from source to destination /// using A* algorithm. /// </summary> /// <param name='src' type='GameObject'> /// Source. /// </param> /// <param name='dst' type='GameObject'> /// Destination /// </param> public List <GameObject> Astar(GameObject src, GameObject dst) { List <AiEdge> successors; AiVertex auxVertex; int cost = 0; bool isInFrontier = false, isInExplored = false; AiNode node = new AiNode(src, 1); AiNode dstNode = new AiNode(dst, 1); AiNode child; GPWiki.BinaryHeap <AiNode> frontier = new GPWiki.BinaryHeap <AiNode>(); List <GameObject> explored = new List <GameObject>(); frontier.Add(node); while (true) { if (frontier.Count == 0) { return(new List <GameObject>()); } node = frontier.Remove(); explored.Add(node.m_GameObject); if (node.Equals(dstNode)) { return(explored); } auxVertex = node.m_GameObject.GetComponent <AiVertex>(); successors = auxVertex.m_Successors; foreach (AiEdge e in successors) { cost = e.m_Cost; cost += (int)Vector3.Distance(e.m_Vertex.gameObject.transform.position, dst.transform.position); child = new AiNode(e.m_Vertex.gameObject, cost); isInFrontier = frontier.Contains(child); isInExplored = explored.Contains(child.m_GameObject); if (!isInExplored && !isInFrontier) { frontier.Add(child); } else if (isInFrontier) { foreach (AiNode n in frontier) { if (n.Equals(child) && (n.m_Cost > child.m_Cost)) { frontier.Remove(child); frontier.Add(child); } } } } } }
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>()); }
public IEnumerator GetPathInFrames(GameObject srcObj, GameObject dstObj, Heuristic h = null) { // changes over A* isFinished = false; path = new List <Vertex>(); if (srcObj == null || dstObj == null) { path = new List <Vertex>(); isFinished = true; yield break; } ////////////////////////////// if (ReferenceEquals(h, null)) { h = EuclidDist; } Vertex src = GetNearestVertex(srcObj.transform.position); Vertex dst = GetNearestVertex(dstObj.transform.position); GPWiki.BinaryHeap <Edge> frontier = new GPWiki.BinaryHeap <Edge>(); Edge[] edges; Edge node, child; int size = vertices.Count; float[] distValue = new float[size]; int[] previous = new int[size]; node = new Edge(src, 0); frontier.Add(node); distValue[src.id] = 0; previous[src.id] = src.id; for (int i = 0; i < size; i++) { if (i == src.id) { continue; } distValue[i] = Mathf.Infinity; previous[i] = -1; } while (frontier.Count != 0) { // changes over A* yield return(null); ////////////////////////////// node = frontier.Remove(); int nodeId = node.vertex.id; if (ReferenceEquals(node.vertex, dst)) { // changes over A* path = BuildPath(src.id, node.vertex.id, ref previous); break; ////////////////////////////// } edges = GetEdges(node.vertex); foreach (Edge e in edges) { int eId = e.vertex.id; if (previous[eId] != -1) { continue; } float cost = distValue[nodeId] + e.cost; // key point cost += h(node.vertex, e.vertex); if (cost < distValue[e.vertex.id]) { distValue[eId] = cost; previous[eId] = nodeId; frontier.Remove(e); child = new Edge(e.vertex, cost); frontier.Add(child); } } } // chages over A* isFinished = true; yield break; ////////////////////////////// }
public List <GuildRecord> ComputeMapFlooding() { GPWiki.BinaryHeap <GuildRecord> open; open = new GPWiki.BinaryHeap <GuildRecord>(); List <GuildRecord> closed; closed = new List <GuildRecord>(); foreach (Guild g in guildList) { GuildRecord gr = new GuildRecord(); Vector3 pos = g.baseObject.transform.position; gr.location = GetNearestVertex(pos); gr.guild = g; gr.strength = g.GetDropOff(0f); open.Add(gr); } while (open.Count != 0) { GuildRecord current; current = open.Remove(); Vertex v = current.location; Vector3 currPos; currPos = v.transform.position; Vertex[] neighbours; neighbours = GetNeighbours(v); foreach (Vertex n in neighbours) { Vector3 nPos = n.transform.position; float dist = Vector3.Distance(currPos, nPos); float strength = current.guild.GetDropOff(dist); if (strength < dropOffThreshold) { continue; } GuildRecord neighGR = new GuildRecord(); neighGR.location = n; neighGR.strength = strength; VertexInfluence vi; vi = n as VertexInfluence; neighGR.guild = vi.guild; if (closed.Contains(neighGR)) { Vertex location = neighGR.location; int index = closed.FindIndex(x => x.location == location); GuildRecord gr = closed[index]; if (gr.guild.name != current.guild.name && gr.strength < strength) { continue; } } else if (open.Contains(neighGR)) { bool mustContinue = false; foreach (GuildRecord gr in open) { if (gr.Equals(neighGR)) { mustContinue = true; break; } } if (mustContinue) { continue; } } else { neighGR = new GuildRecord(); neighGR.location = n; } neighGR.guild = current.guild; neighGR.strength = strength; open.Add(neighGR); } closed.Add(current); } return(closed); }