def __init__(self): super(SweepPartition, self).__init__() self.sorter = SortingManager() self.cut = None self.dim = None self.recursiveSplits = None
class SweepPartition(PartitionAlgorithm): def __init__(self): super(SweepPartition, self).__init__() self.sorter = SortingManager() self.cut = None self.dim = None self.recursiveSplits = None def mbrCompare(self, d): def compare(first, second): firstDMin = first.getMbr().getMin(d) secondDMin = second.getMbr().getMin(d) c = 0 if firstDMin < secondDMin: c = -1 elif firstDMin > secondDMin: c = 1 return c return compare # La particion se basa en lo siguiente: # Determina un corte utilizando un orden parcial de los mbrs para determinada dimension d, donde el coste de ordenar la lista en base a dimension # es el menor coste. Luego, contruye dos particiones en base a este corte dimensional, si se trata de un nodo hoja, los elementos deben reinsertarse # en toda particion donde intersecten def partition(self, mbrParent, mbrPointerList, m, leafMode = False): dimensionSortedList = [] minCostDim = len(mbrPointerList)**2 + 1 # cota superior cuadratica for d in range(mbrParent.d): dimensionSortedList = dimensionSortedList + [self.sorter.mergesort(self.mbrCompare(d), mbrPointerList)] if self.sorter.cost < minCostDim: minCostDim = d sortedList = dimensionSortedList[minCostDim] dimCut = (sortedList[m-1].getMin(minCostDim) + sortedList[m].getMin(minCostDim))/2 #corte dimensional seedMbrs = mbrParent.cutOnDimension(minCostDim, dimCut) # mbr de las dos nuevas particiones recursiveSplits = [] firstPartition = [] secondPartition = [] rs = 0 if leafMode: fPLen = 0 sPLen = 0 for mb in sortedList: if seedMbrs[0].areIntersecting(mb): firstPartition = firstPartition + [mb] fPLen = fPLen + 1 if seedMbrs[1].areIntersecting(mb): secondPartition = secondPartition + [mb] sPLen = sPLen + 1 maxL = len(mbrPointerList) if fPLen == maxL or sPLen == maxL: raise PartitionError("Particion Sweep no separo de forma adecuada los elementos en las hojas") elif fPLen + sPLen < maxL: raise PartitionError("Particion perdio elementos") else: i = 0 for mb in sortedList: # Si es que el corte atraviesa al mbr, es necesario subdividirlo recursivamente posteriormente if mb.getMin(minCostDim) >= dimCut and dimCut <= mb.getMax(minCostDim): recursiveSplits = recursiveSplits + [mb] rs = rs + 1 elif mb.getMin(minCostDim) < dimCut and i < m: firstPartition = firstPartition + [mb] i = i +1 else: secondPartition = secondPartition + [mb] if rs > 0: self.cut = dimCut self.dim = minCostDim self.recursiveSplits = recursiveSplits else: self.cut = None self.dim = None self.recursiveSplits = [] return [[seedMbrs[0]] + firstPartition, [seedMbrs[1]] + secondPartition] # Particiona una lista de mbrPointers segun un corte dimensional, y, almacena los nodos # que deben ser particionados de forma recursiva antes de insertarlos def partitionOnCut(self, mbrPointerList, cut, dim): firstPartition = [] secondPartition = [] recursiveSplits = [] rs = 0 for mb in mbrPointerList: # Corte en nodo hijo if mb.getMin(dim)<= cut and cut <= mb.getMax(dim): recursiveSplits = recursiveSplits + [mb] rs = rs + 1 elif mb.getMax(dim) <= cut: firstPartition = firstPartition + [mb] else: secondPartition = secondPartition + [mb] if rs > 0: self.cut = cut self.dim = dim self.recursiveSplits = recursiveSplits else: self.cut = None self.dim = None self.recursiveSplits = [] return [firstPartition, secondPartition] def getCut(self): return self.cut def getDim(self): return self.dim def getRecursiveSplits(self): return self.recursiveSplits def needsToSplitChilds(self): return self.cut != None