Exemple #1
0
 private void BuildClusterNodeIntraEdges(AbstractionLayer layer)
 {
     foreach (var c in layer.Clusters.Values)
     {
         foreach (var cn in c.ClusterNodes.Values)
         {
             calculateDistInnerClusterNodes(cn, c);
         }
     }
 }
Exemple #2
0
 private void BuildClusterConnections(AbstractionLayer layer)
 {
     foreach (var cnode in layer.Clusters)
     {
         var neighbors = getHPAClusterNeighbors(cnode.Value);
         foreach (var n in neighbors)
         {
             cnode.Value.AddNeighbor(n.ID, n);
             n.AddNeighbor(cnode.Key, cnode.Value);
         }
     }
 }
Exemple #3
0
        private void BuildHPAClusters()
        {
            HierarchicalGraph.Clear();

            hpaWatch = new Stopwatch();
            hpaWatch.Start();

            AbstractionLayer layer = new AbstractionLayer(0, new List <Cluster>());

            //we make 10 x 10 clusters , from the upper left to the lower right.
            if (gMap.Width >= 20 && gMap.Height >= 20)
            {
                HPACsize = 10;

                int i = 0;
                int j = 0;
                for (j = 0; j <= gMap.Height / HPACsize; ++j)
                {
                    for (i = 0; i < gMap.Width; i += HPACsize)
                    {
                        CreateHPACluster(layer, i, j);
                    }
                }
            }
            else //otherwise, we divide the map to 4 clusters by the size of width / 2 x height / 2
            {
                int i = 0;
                int j = 0;
                HPACsize = (gMap.Width % 2 == 0 ? gMap.Width / 2 : gMap.Width / 2 + 1);

                for (j = 0; j <= gMap.Height / HPACsize; ++j)
                {
                    for (i = 0; i < gMap.Width; i += HPACsize)
                    {
                        CreateHPACluster(layer, i, j);
                    }
                }
            }

            HierarchicalGraph.Add(layer.ID, layer);

            BuildClusterConnections(layer);
            BuildClusterNodes(layer);
            BuildClusterNodeIntraEdges(layer);

            hpaWatch.Stop();
        }
Exemple #4
0
        private void BuildClusterNodes(AbstractionLayer layer)
        {
            foreach (var c in layer.Clusters)
            {
                //for every cluster, we look at its OuterNodes - all 4 sides.
                //We look at the neighboring nodes. If they are traversable,
                //we start tracking an entrance. We expand an entrance as long as both the neighboring nodes
                //are traversable. If one of them is not, we stop, look at the number of entrances and
                //dependng on its size, create the corresponding number of cluster nodes.

                foreach (var side in c.Value.OuterNodes)
                {
                    Cluster neighbor;
                    List <Tuple <int, int> > possibleEntrances = new List <Tuple <int, int> >();
                    switch (side.Key)
                    {
                    case 'U':
                        //get the upper neighbor
                        neighbor = c.Value.GetNeighbor('U');
                        if (neighbor == null)
                        {
                            continue;
                        }

                        //now we start tracking entrances between these clusters.
                        possibleEntrances = new List <Tuple <int, int> >();
                        foreach (var n in side.Value)
                        {
                            int id = n - gMap.Width;
                            if (gMap.Nodes[n].IsTraversable() && gMap.Nodes[id].IsTraversable())
                            {
                                //ITEM1 is the Cluster node, ITEM2 is the NEIGHBOR cluster node
                                possibleEntrances.Add(Tuple.Create(n, id));
                            }
                            else
                            {
                                //there is an obstacle on either side of the outer nodes.
                                //get the number of items in hte possibleEntrances and create the cluster Nodes.
                                //after that, clear the possibleEntrances list and continue;
                                if (possibleEntrances.Count > 0)
                                {
                                    if (possibleEntrances.Count < 5)
                                    {
                                        //make a single entrance in the middle.
                                        //the FIRST tuple item is the node of 'c' and the second item is the node of neighbor
                                        Tuple <int, int> entrance = possibleEntrances[possibleEntrances.Count / 2];

                                        createClusterNodes(c.Value, neighbor, entrance);
                                        possibleEntrances.Clear();
                                    }
                                    else if (possibleEntrances.Count >= 5 && possibleEntrances.Count < 7)    //the continuous entrance length is higher than/equal to 5
                                    {
                                        //we create two entrances in this case, one on the start and one on the end.
                                        Tuple <int, int> entrance1 = possibleEntrances[0];
                                        Tuple <int, int> entrance2 = possibleEntrances[possibleEntrances.Count - 1];

                                        createClusterNodes(c.Value, neighbor, entrance1, entrance2);
                                        possibleEntrances.Clear();
                                    }
                                    else     //>=7
                                    {
                                        //we create two entrances in this case - the first one column from the start,
                                        //the second one column from the end
                                        Tuple <int, int> entrance1 = possibleEntrances[2];
                                        Tuple <int, int> entrance2 = possibleEntrances[possibleEntrances.Count - 3];

                                        createClusterNodes(c.Value, neighbor, entrance1, entrance2);
                                        possibleEntrances.Clear();
                                    }
                                }
                            }
                        }
                        if (possibleEntrances.Count > 0)
                        {
                            if (possibleEntrances.Count < 5)
                            {
                                //make a single entrance in the middle.
                                //the FIRST tuple item is the node of 'c' and the second item is the node of neighbor
                                Tuple <int, int> entrance = possibleEntrances[possibleEntrances.Count / 2];

                                createClusterNodes(c.Value, neighbor, entrance);
                                possibleEntrances.Clear();
                            }
                            else if (possibleEntrances.Count >= 5 && possibleEntrances.Count < 7)
                            {
                                //we create two entrances in this case, one on the start and one on the end.
                                Tuple <int, int> entrance1 = possibleEntrances[0];
                                Tuple <int, int> entrance2 = possibleEntrances[possibleEntrances.Count - 1];

                                createClusterNodes(c.Value, neighbor, entrance1, entrance2);
                                possibleEntrances.Clear();
                            }
                            else     //>= 7
                            {
                                //we create two entrances in this case - the first one column from the start,
                                //the second one column from the end
                                Tuple <int, int> entrance1 = possibleEntrances[2];
                                Tuple <int, int> entrance2 = possibleEntrances[possibleEntrances.Count - 3];

                                createClusterNodes(c.Value, neighbor, entrance1, entrance2);
                                possibleEntrances.Clear();
                            }
                        }
                        break;

                    case 'R':
                        //get the neighbor on the right
                        neighbor = c.Value.GetNeighbor('R');
                        if (neighbor == null)
                        {
                            continue;
                        }

                        //now we start tracking entrances between these clusters.
                        possibleEntrances = new List <Tuple <int, int> >();
                        foreach (var n in side.Value)
                        {
                            int id = n + 1;
                            if (gMap.Nodes[n].IsTraversable() && gMap.Nodes[id].IsTraversable() && ((GridMap)gMap).SameRow(n, id))
                            {
                                //ITEM1 is the Cluster node, ITEM2 is the NEIGHBOR cluster node
                                possibleEntrances.Add(Tuple.Create(n, id));
                            }
                            else
                            {
                                //there is an obstacle on either side of the outer nodes.
                                //get the number of items in hte possibleEntrances and create the cluster Nodes.
                                //after that, clear the possibleEntrances list and continue;
                                if (possibleEntrances.Count > 0)
                                {
                                    if (possibleEntrances.Count < 5)
                                    {
                                        //make a single entrance in the middle.
                                        //the FIRST tuple item is the node of 'c' and the second item is the node of neighbor
                                        Tuple <int, int> entrance = possibleEntrances[possibleEntrances.Count / 2];

                                        createClusterNodes(c.Value, neighbor, entrance);
                                        possibleEntrances.Clear();
                                    }
                                    else if (possibleEntrances.Count >= 5 && possibleEntrances.Count < 7)    //the continuous entrance length is higher than/equal to 5
                                    {
                                        //we create two entrances in this case, one on the start and one on the end.
                                        Tuple <int, int> entrance1 = possibleEntrances[0];
                                        Tuple <int, int> entrance2 = possibleEntrances[possibleEntrances.Count - 1];

                                        createClusterNodes(c.Value, neighbor, entrance1, entrance2);
                                        possibleEntrances.Clear();
                                    }
                                    else     //>=7
                                    {
                                        //we create two entrances in this case - the first one column from the start,
                                        //the second one column from the end
                                        Tuple <int, int> entrance1 = possibleEntrances[2];
                                        Tuple <int, int> entrance2 = possibleEntrances[possibleEntrances.Count - 3];

                                        createClusterNodes(c.Value, neighbor, entrance1, entrance2);
                                        possibleEntrances.Clear();
                                    }
                                }
                            }
                        }
                        if (possibleEntrances.Count > 0)
                        {
                            if (possibleEntrances.Count < 5)
                            {
                                //make a single entrance in the middle.
                                //the FIRST tuple item is the node of 'c' and the second item is the node of neighbor
                                Tuple <int, int> entrance = possibleEntrances[possibleEntrances.Count / 2];

                                createClusterNodes(c.Value, neighbor, entrance);
                                possibleEntrances.Clear();
                            }
                            else if (possibleEntrances.Count >= 5 && possibleEntrances.Count < 7)
                            {
                                //we create two entrances in this case, one on the start and one on the end.
                                Tuple <int, int> entrance1 = possibleEntrances[0];
                                Tuple <int, int> entrance2 = possibleEntrances[possibleEntrances.Count - 1];

                                createClusterNodes(c.Value, neighbor, entrance1, entrance2);
                                possibleEntrances.Clear();
                            }
                            else     //>= 7
                            {
                                //we create two entrances in this case - the first one column from the start,
                                //the second one column from the end
                                Tuple <int, int> entrance1 = possibleEntrances[2];
                                Tuple <int, int> entrance2 = possibleEntrances[possibleEntrances.Count - 3];

                                createClusterNodes(c.Value, neighbor, entrance1, entrance2);
                                possibleEntrances.Clear();
                            }
                        }
                        break;
                    }
                }
            }
        }
Exemple #5
0
        public void CreateHPACluster(AbstractionLayer layer, int columnPos, int rowPos)
        {
            Cluster c = new Cluster(layer.LastAssignedClusterID);

            layer.LastAssignedClusterID++;

            HashSet <int> innerNodes = new HashSet <int>();
            Dictionary <char, OuterNodeArea> outerNodes = new Dictionary <char, OuterNodeArea>
            {
                { 'U', new OuterNodeArea() },
                { 'D', new OuterNodeArea() },
                { 'L', new OuterNodeArea() },
                { 'R', new OuterNodeArea() },
            };

            int startY = rowPos * HPACsize * gMap.Width;
            int endY   = startY == 0 ? HPACsize * gMap.Width : startY + gMap.Width * HPACsize;

            int startX = columnPos;
            int endX   = columnPos + HPACsize; //non-inclusive

            for (int j = startY; j < endY; j += gMap.Width)
            {
                for (int i = startX; i < endX; ++i)
                {
                    if (gMap.Nodes.ContainsKey(i + j))
                    {
                        gMap.Nodes[i + j].HPAClusterParent = c.ID;
                        innerNodes.Add(i + j);
                        if (j == startY || i == startX || i == endX - 1 || j + gMap.Width >= endY)
                        {
                            char direction = 'D'; //default init

                            if (j == startY)      //first row. 'U' outer node
                            {
                                direction = 'U';
                            }

                            else if (i == startX) //first column. 'L' node
                            {
                                direction = 'L';
                            }

                            else if (i == endX - 1) //last column. 'R' node
                            {
                                direction = 'R';
                            }

                            else //j + gMap.Width >= endY. last row. 'D' node
                            {
                                direction = 'D';
                            }

                            outerNodes[direction].Add(i + j);
                        }
                    }
                }
            }

            if (innerNodes.Count != 0 && outerNodes.Count != 0)
            {
                c.SetInnerNodes(innerNodes);
                c.SetOuterNodes(outerNodes);
                layer.Clusters.Add(c.ID, c);
            }
            else
            {
                //do not add the cluster to layer; decrease the ID
                layer.LastAssignedClusterID--;
            }
        }