Beispiel #1
0
        /// <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>());
        }
Beispiel #2
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>());
    }
Beispiel #3
0
    //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>());
    }