示例#1
0
    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>());
    }
示例#2
0
    /// <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);
                        }
                    }
                }
            }
        }
    }
示例#3
0
    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>());
    }
示例#4
0
    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;
        //////////////////////////////
    }
示例#5
0
    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);
    }