Exemplo n.º 1
0
    def __select(self, left, right, check_value):
        """
        :param left: lower index of the array.
        :param right: higher index of the array.
        :param check_value: the control value
        """

        x = self.__median_of_medians(left, right)
        """
        4. 
        Partition the array around the median of medians
        """
        key = self.__partition(left, right, x)

        # Add all the elements smaller or equal than the key (excluded)
        partial_sum = sum_array(self.array[left:key])
        """
        5.
        If adding the key to the partial_sum
        makes this greater than the target return the key,
        else recursively select in relative subarray
        """
        debug_lwm('median: {}'.format(self.array[key]))

        if check_value > partial_sum >= check_value - self.array[key]:
            return key
        elif partial_sum == check_value:
            return key - 1
        elif partial_sum > check_value:
            return self.__select(left, key, check_value)
        else:
            return self.__select(key, right, check_value - partial_sum)
Exemplo n.º 2
0
 def __median_of_5(self, left, right):
     self.__insertion_sort(left, right)
     median = (left + right) // 2
     debug_lwm('md5[{}:{}] {} median: {}'.format(left, right,
                                                 self.array[left:right],
                                                 self.array[median]))
     return median
Exemplo n.º 3
0
    def __duplicated_values(self, idx):

        x = idx

        while self.array[x] == self.array[x + 1]:
            debug_lwm("{}\t{}".format(self.array[x], self.array[x + 1]))
            x += 1
        return idx, x
Exemplo n.º 4
0
    def __lwm_calculate(self, left, right, sumTarget):  # check_value

        med = (right - left) // 2
        sommaTotale = self.sum_array

        index = self.__select(left, right, med)
        debug_lwm(index)
        array_idx = self.__duplicated_values(index)
        sumLeftPivot = self.__sum(self.array[0:array_idx[0]])
        sumRightPivot = self.__sum(self.array[array_idx[1]:right + 1])

        debug_lwm((sumLeftPivot, sumLeftPivot))
        while not (sumLeftPivot < sumTarget and sumRightPivot <= sumTarget):
            if sumLeftPivot >= sumTarget:
                tmpRight = index
                med = left + (tmpRight - left) / 2
                index = self.__select(left, tmpRight, med)

                array_idx = self.__duplicated_values(index)

                sumRightPivot = sumRightPivot + self.__sum(
                    self.array[array_idx[1] + 1:tmpRight])
                sumLeftPivot = sommaTotale - sumRightPivot - self.__sum(
                    self.array[array_idx[0]:array_idx[1]])

            else:
                tmpLeft = index
                med = tmpLeft + (right - tmpLeft) / 2
                index = self.__select(tmpLeft, right, med)

                array_idx = self.__duplicated_values(index)

                sumLeftPivot = sumLeftPivot + self.__sum(
                    self.array[tmpLeft:array_idx[0] - 1])
                sumRightPivot = sommaTotale - sumLeftPivot - self.__sum(
                    self.array[array_idx[0]:array_idx[1]])

            return index