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