Это фактически превратилось в интересный вопрос для меня, когда я посмотрел на ожидаемое время выполнения алгоритма, подобного быстрой сортировке, когда ожидаемое разделение на каждом уровне не 50/50.
Первый вопрос, на который я хотел ответить, был дляслучайные данные, что среднее разделение на каждом уровне.Конечно, оно должно быть больше 50% (для более крупного подразделения).Ну, учитывая массив размером N случайных значений, наименьшее значение имеет подразделение (1, N-1), второе наименьшее значение имеет подразделение (2, N-2) и т. Д. Я положил это вБыстрый скрипт:
split = 0
for x in range(10000):
split += float(max(x, 10000 - x)) / 10000
split /= 10000
print split
И получил ровно 0,75 в качестве ответа.Я уверен, что смогу показать, что это всегда точный ответ, но я хотел перейти к более сложной части.
Теперь, давайте предположим, что даже 25/75 разделение следует за прогрессом nlogn для некоторого неизвестного логарифмабаза.Это означает, что num_comparisons(n) = n * log_b(n)
, и вопрос заключается в том, чтобы найти b
с помощью статистических средств (поскольку я не ожидаю, что эта модель будет точной на каждом этапе).Мы можем сделать это с умным применением аппроксимации наименьших квадратов после того, как мы используем логарифмическую идентификацию, чтобы получить:
C(n) = n * log(n) / log(b)
, где теперь логарифм может иметь любую базу, если log(n)
и log(b)
использовать ту же базу.Это линейное уравнение, ожидающее некоторых данных!Поэтому я написал другой скрипт для генерации массива xs
, заполнил его C(n)
и ys
, заполнил его n*log(n)
и использовал numpy
, чтобы сообщить мне наклон этой наименьших квадратов, который я ожидаюравным 1 / log(b)
.Я запустил скрипт и получил b
внутри [2.16, 2.3]
в зависимости от того, как высоко я установил n
(я менял n от 100 до 100'000'000).Тот факт, что b
, кажется, меняется в зависимости от n
, показывает, что моя модель не точна, но я думаю, что это нормально для этого примера.
Чтобы ответить на ваш вопрос сейчас, с этими предположениями, мыможет решить для точки отсечения, когда: N * n/2 = n*log_2.3(n) + N * log_2.3(n)
.Я просто предполагаю, что бинарный поиск будет иметь ту же базу логарифма, что и метод сортировки для разбиения 25/75.Изолировав N
, вы получите:
N = n*log_2.3(n) / (n/2 - log_2.3(n))
Если число ваших поисков N
превышает количество в RHS (где n
- размер рассматриваемого массива), тогда оно будет более эффективнымотсортировать один раз и использовать двоичный поиск по этому.