Exemple #1
0
        // prebudovanie stromu
        // na vstupe je zoznam vsetkych buducich listov podstromu.
        public KDNode rebuilt(List<KDNode> l1, int dim1, KDNode newParent, Boolean isLeft) 
        {
            List<KDNode> l = l1;
            
            // ak je v zozname iba 1 vrchol, vrati sa ako list
            if (l.Count == 1)
            {   
                return l.ElementAt(0);
            }

            int newSplit;
            int dimension;
            if (newParent == null)
            {
                // root ma nastavenu deliacu suradnicu na x.
                dimension = 0;
            } else {
                dimension = 1 - newParent.getDim();
            }
            // vrati split noveho vrchola
            newSplit = findSplit(l, dimension);
            //Console.WriteLine(newSplit);

            List<KDNode> newLeft = new List<KDNode>();
            List<KDNode> newRight = new List<KDNode>();
            Boolean equal = true;
            //rozdelenie na 2 podstromy podla split a dim
            if (dimension == 0) //split cez x-ovu os
            {
                foreach (KDNode n in l) 
                {
                    // zoznam listov v lavom a pravom podstrome podla split
                    if (n.getPoint().X < newSplit)
                    {
                        newLeft.Add(n);
                    }
                    if (n.getPoint().X > newSplit)
                    {
                        newRight.Add(n);
                    }
                    // ak by mali rovnaku suradnicu, aby sa nepridavali len do jedneho podstromu
                    if (n.getPoint().X == newSplit)
                    {
                        if (equal){
                            newLeft.Add(n);
                            equal = false;
                        } else {
                            newRight.Add(n);
                            equal = true;
                        }
                    }
                }

            } else { //split cez y-ovu os
                foreach (KDNode n in l)
                {
                    // zoznam listov v lavom a pravom podstrome podla split
                    if (n.getPoint().Y < newSplit)
                    {
                        newLeft.Add(n);
                    }
                    if (n.getPoint().Y > newSplit)
                    {
                        newRight.Add(n);
                    }
                    // ak by mali rovnaku suradnicu, aby sa nepridavali len do jedneho podstromu
                    if (n.getPoint().Y == newSplit)
                    {
                        if (equal)
                        {
                            newLeft.Add(n);
                            equal = false;
                        } else {
                            newRight.Add(n);
                            equal = true;
                        }
                    }
                }
            }

            // vytvori sa koren noveho podstromu
            KDNode subroot = new KDNode(true, newSplit, dimension, null, this.g);
            if (newParent != null)
            {
                if (isLeft)
                {
                    newParent.setLeft(subroot);
                } else {
                    newParent.setRight(subroot);
                }
            }
            subroot.setParent(newParent);
            subroot.setLeft(rebuilt(newLeft, 1 - dimension, subroot, true));
            subroot.getLeft().setParent(subroot);
            subroot.setRight(rebuilt(newRight, 1 - dimension, subroot, false));
            subroot.getRight().setParent(subroot);

            return subroot;
        }
Exemple #2
0
        // najde numNearest najblizsich vrcholov ku target
        // na konci budu v usporiadanom zozname nearestK
        public void findNearest(KDNode subTree, KDNode target) 
        {
            // ak je to list, zistime, ci je blizsie ako doposial najdene, ak ich je dost
            if (subTree.isLeaf) {
                subTree.dist = distance(target.getPoint(), subTree.getPoint());
                if (nearestK.Count < numNearest)
                { 
                    nearestK.Add(subTree);
                } else {
                    if (nearestK.Last().dist > subTree.dist) 
                    {
                        nearestK.Remove(nearestK.Last());
                        nearestK.Add(subTree);
                    }
                }
                
                return;
            }


            int dim = subTree.getDim();

            // ak je target v lavom podstrome, nearer je lavy a further je pravy, inak opacne
            KDNode nearer;
            KDNode further;
            if (dim == 0)
            {
                if (subTree.getSplit() >= target.getPoint().X)
                {
                    nearer = subTree.getLeft();
                    further = subTree.getRight();
                } else {
                    further = subTree.getLeft();
                    nearer = subTree.getRight();
                }
            } else {
                if (subTree.getSplit() >= target.getPoint().Y)
                {
                    nearer = subTree.getLeft();
                    further = subTree.getRight();
                }else {
                    further = subTree.getLeft();
                    nearer = subTree.getRight();
                }
            }
            // najprv prehladavame blizsi podstrom 
            // (prvy prehladany blok bude ten, v kt. je target)
            // teda si ohranicime v priemere celkom slusne najblizsie vrcholy
            findNearest(nearer, target); 

            // zrata najblizsi bod od target na bunke further
            // ak je dalej ako doposial najdeny k-ty nejmensi, tak vo further
            // nemoze byt blizsi bod => nevnara sa
            Point nearestF = nearestTo(further, target);
            double dist = distance(nearestF, target.getPoint());

            if ((nearestK.Last().dist > dist) || (nearestK.Count < numNearest))
            {
                findNearest(further, target);
            }
        }
Exemple #3
0
 //vrati podstrom, do ktoreho syna ma ist novy vrchol a bola by v nom narusena rovnovaha
 public KDNode findPlace(KDNode n, KDNode leaf) 
 {
     // ak n je list, potom sa rovnovaha nenarusi a iba sa novy vrchol vlozi.
     // z listu spravime otca dvoch listov v procedure rebuilt
     if(n.isLeaf)
     {
         //Console.Write(n.getPoint());
         //Console.WriteLine(" numLeafs " + n.getNumLeafs());
         return n;
     }
     //Console.Write(n.getSplit());
     //Console.WriteLine(" numLeafs right" + n.getRight().getNumLeafs());
     //Console.WriteLine(" numLeafs left" + n.getLeft().getNumLeafs());
     // ak to nie je list, potom hladame podstrom, ktoremu sa narusi rovnovaha.
     if (n.getDim() == 0) // split je v x-ovej suradnici
     {
         if (n.getSplit() >= leaf.getPoint().X) // ak ma ist do laveho podstromu
         {
             // a uz teraz je vlavo viac listov ako vpravo, narusi sa rovnovaha n
             if (n.getLeft().getNumLeafs() > n.getRight().getNumLeafs())
             {
                 return n;
             } else { // inak sa vrati podstrom z laveho podstromu, v ktorom je narusena rovnovaha
                 return findPlace(n.getLeft(), leaf);
             }
         } else { // ak ma ist do praveho podstromu
             // a uz teraz je vpravo viac listov ako vlavo, narusi sa rovnovaha n
             if (n.getLeft().getNumLeafs() < n.getRight().getNumLeafs()) 
             {
                 return n;
             } else { // inak sa vrati podstrom z praveho podstromu, v ktorom je narusena rovnovaha
                 return findPlace(n.getRight(), leaf);
             }
         }
     } else { // split je v y-ovej suradnici
         if (n.getSplit() >= leaf.getPoint().Y) // ak ma ist do laveho podstromu (= patri hore, nad split)
         {
             // a uz teraz je vlavo viac listov ako vpravo, narusi sa rovnovaha n
             if (n.getLeft().getNumLeafs() > n.getRight().getNumLeafs())
             {
                 return n;
             }
             else
             { // inak sa vrati podstrom z laveho podstromu, v ktorom je narusena rovnovaha
                 return findPlace(n.getLeft(), leaf);
             }
         }
         else
         { // ak ma ist do praveho podstromu (= patri dole, pod split)
             // a uz teraz je vpravo viac listov ako vlavo, narusi sa rovnovaha n
             if (n.getLeft().getNumLeafs() < n.getRight().getNumLeafs())
             {
                 return n;
             }
             else
             { // inak sa vrati podstrom z praveho podstromu, v ktorom je narusena rovnovaha
                 return findPlace(n.getRight(), leaf);
             }
         }
     }
 }