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)
def lwm(self, array): """ :param array: l'array nel quale trovare la mediana pesata inferiore :return: """ self.array = array self.__merge_sort(self.array) # calcolo il valore di controllo sum_tot = sum_array(self.array) / 2 _sum = 0 """ creo 2 variabili in cui andranno sommate i valori man mano che l'array viene controllato """ for el in self.array: _sum += el """ Ogni ciclo sommo il numero corrente a questo punto eseguo il controllo se sum_tot e' contenuto tra la sommatora senza l'elemento corrente e quella con'elemento corrente """ if _sum - el < sum_tot <= _sum: self.__result = el return
def lwm(self, array): self.array = array self.sum_array = sum_array(array) # case of array full of 0 if self.sum_array is 0: return 0 check_value = self.sum_array / 2 self.idx_median = self.__select(0, len(array) - 1, check_value)
def __lwm_calculate(self, left, right, check_value): # Find the values who will work as key idx_lwm = self.__select(left, right) # Add all the elements smaller or equal than the key (excluded) partial_sum = sum_array(self.array[left:idx_lwm]) """ If adding the key to the partial_sum makes this greater than the target return the key, else recursively search in the relative subarray """ if check_value > partial_sum >= check_value - self.array[idx_lwm]: return idx_lwm elif partial_sum == check_value: return idx_lwm - 1 elif partial_sum > check_value: return self.__lwm_calculate(left, idx_lwm, check_value) else: return self.__lwm_calculate(idx_lwm, right, check_value - partial_sum)
def lwm(self, array): self.array = array self.__insertion_sort() # calcolo il valore di controllo sum_tot = sum_array(self.array)/2 _sum = 0 """ creo 2 variabili in cui andranno sommate i valori man mano che l'array viene controllato """ for el in self.array: _sum += el """ Ogni ciclo sommo il numero corrente a questo punto eseguo il controllo se sum_tot e' contenuto tra la sommatora senza l'elemento corrente e quella con'elemento corrente """ if _sum-el < sum_tot <= _sum: self.__result = el return