def _old_sampling_of_one_exchange_neighborhood(self, param, array, index):
        neighbourhood = []
        number_of_sampled_neighbors = 0
        iteration = 0
        checked_neighbors = []
        checked_neighbors_non_unit_cube = []
        while True:
            hp = self.incumbent.configuration_space.get_hyperparameter(param)
            num_neighbors = hp.get_num_neighbors(self.incumbent.get(param))
            self.logger.debug('\t' + str(num_neighbors))

            # Obtain neigbors differently for different possible numbers of
            # neighbors
            if num_neighbors == 0:
                self.logger.debug('\tNo neighbors!')
                break
            # No infinite loops
            elif iteration > 500:
                self.logger.debug('\tMax iter')
                break
            elif np.isinf(num_neighbors):
                num_samples_to_go = min(
                    10, self._continous_param_neighbor_samples -
                    number_of_sampled_neighbors)
                if number_of_sampled_neighbors >= self._continous_param_neighbor_samples or num_samples_to_go <= 0:
                    break
                neighbors = hp.get_neighbors(array[index],
                                             self.rng,
                                             number=num_samples_to_go)
            else:
                if iteration > 0:
                    break
                neighbors = hp.get_neighbors(array[index], self.rng)
            # self.logger.debug('\t\t' + str(neighbors))
            # Check all newly obtained neighbors
            for neighbor in neighbors:
                if neighbor in checked_neighbors:
                    iteration += 1
                    continue
                new_array = array.copy()
                new_array = change_hp_value(self.incumbent.configuration_space,
                                            new_array, param, neighbor, index)
                try:
                    new_configuration = Configuration(
                        self.incumbent.configuration_space, vector=new_array)
                    neighbourhood.append(new_configuration)
                    new_configuration.is_valid_configuration()
                    check_forbidden(self.cs.forbidden_clauses, new_array)
                    number_of_sampled_neighbors += 1
                    checked_neighbors.append(neighbor)
                    checked_neighbors_non_unit_cube.append(
                        new_configuration[param])
                except (ForbiddenValueError, ValueError) as e:
                    pass
                iteration += 1
        return checked_neighbors, checked_neighbors_non_unit_cube
    def _get_one_exchange_neighborhood_by_parameter(self):
        """
        Slight modification of ConfigSpace's get_one_exchange neighborhood. This orders the parameter values and samples
        more neighbors in one go. Further we need to rigorously check each and every neighbor if it is forbidden or not.
        """
        neighborhood_dict = {}
        params = list(self.incumbent.keys())
        self.logger.debug('params: ' + str(params))
        for index, param in enumerate(params):
            self.logger.info('Sampling neighborhood of %s' % param)
            array = self.incumbent.get_array()

            if not np.isfinite(array[index]):
                self.logger.info('>'.join(['-' * 50, ' Not active!']))
                continue
            if self.old_sampling:
                checked_neighbors, checked_neighbors_non_unit_cube = self._old_sampling_of_one_exchange_neighborhood(
                    param, array, index)
            else:
                neighbourhood = []
                checked_neighbors = []
                checked_neighbors_non_unit_cube = []
                hp = self.incumbent.configuration_space.get_hyperparameter(
                    param)
                num_neighbors = hp.get_num_neighbors(self.incumbent.get(param))
                self.logger.debug('\t' + str(num_neighbors))
                if num_neighbors == 0:
                    self.logger.debug('\tNo neighbors!')
                    continue
                elif np.isinf(num_neighbors):  # Continous Parameters
                    if hp.log:
                        base = np.e
                        log_lower = np.log(hp.lower) / np.log(base)
                        log_upper = np.log(hp.upper) / np.log(base)
                        neighbors = np.logspace(
                            log_lower,
                            log_upper,
                            self._continous_param_neighbor_samples,
                            endpoint=True,
                            base=base)
                    else:
                        neighbors = np.linspace(
                            hp.lower, hp.upper,
                            self._continous_param_neighbor_samples)
                    neighbors = list(
                        map(lambda x: hp._inverse_transform(x), neighbors))
                else:
                    neighbors = hp.get_neighbors(array[index], self.rng)
                for neighbor in neighbors:
                    if neighbor in checked_neighbors:
                        continue
                    new_array = array.copy()
                    new_array = change_hp_value(
                        self.incumbent.configuration_space, new_array, param,
                        neighbor, index)
                    try:
                        new_configuration = Configuration(
                            self.incumbent.configuration_space,
                            vector=new_array)
                        neighbourhood.append(new_configuration)
                        new_configuration.is_valid_configuration()
                        check_forbidden(self.cs.forbidden_clauses, new_array)
                        checked_neighbors.append(neighbor)
                        checked_neighbors_non_unit_cube.append(
                            new_configuration[param])
                    except (ForbiddenValueError, ValueError) as e:
                        pass
            self.logger.info('>'.join([
                '-' * 50,
                ' Found {:>3d} valid neighbors'.format(len(checked_neighbors))
            ]))
            self._sampled_neighbors += len(checked_neighbors) + 1
            sort_idx = list(
                map(lambda x: x[0],
                    sorted(enumerate(checked_neighbors), key=lambda y: y[1])))
            if isinstance(self.cs.get_hyperparameter(param),
                          CategoricalHyperparameter):
                checked_neighbors_non_unit_cube = list(
                    np.array(checked_neighbors_non_unit_cube)[sort_idx])
            else:
                checked_neighbors_non_unit_cube = np.array(
                    checked_neighbors_non_unit_cube)[sort_idx]
            neighborhood_dict[param] = [
                np.array(checked_neighbors)[sort_idx],
                checked_neighbors_non_unit_cube
            ]
        return neighborhood_dict