Почему бинарный поиск является алгоритмом «разделяй и властвуй»? - PullRequest
17 голосов
/ 13 января 2012

Меня спросили, является ли бинарный поиск алгоритмом «разделяй и властвуй» на экзамене.Мой ответ был положительным, потому что вы разделили проблему на более мелкие подзадачи, пока не достигли своего результата.

Но экзаменаторы спросили, где в этом была роль победителя, но я не смог ответить.Они также не одобряли тот факт, что на самом деле это был алгоритм «разделяй и властвуй».

Но везде, где я хожу в Интернете, он говорит, что это так, поэтому я хотел бы знать, почему и где его часть покорения?

Ответы [ 15 ]

13 голосов
/ 13 января 2012

Книга

Data Structures and Algorithm Analysis in Java, 2nd edtition, Mark Allen Weiss

Говорит, что алгоритм D & C должен иметь два непересекающихся рекурсивных вызова.Т.е. как быстрая сортировка.Бинарный поиск не имеет этого, даже если он может быть реализован рекурсивно, поэтому я думаю, что это ответ.

9 голосов
/ 13 января 2012

Я думаю, что это не разделяй и властвуй, см. Первый абзац в http://en.wikipedia.org/wiki/Divide_and_conquer_algorithm

, рекурсивно разбивая проблему на две или более подзадачи, которые затем объединяются, чтобы дать решение

В бинарном поиске все еще есть только одна проблема, которая сводится к сокращению данных наполовину на каждом шаге, поэтому не требуется фаза завоевания (объединения) результатов.

4 голосов
/ 09 сентября 2016

В стратегии «разделяй и властвуй»:

1. Проблема разбита на части;

2.Каждую из этих частей атакуют / решают независимо, применяя алгоритм под рукой (в основном для этой цели используется рекурсия);

3. И затем решения каждого раздела / подразделения и объединенные / объединенные вместе, чтобы прийти к окончательному решению проблемы в целом (это относится к завоевать )

Пример, Быстрая сортировка, сортировка слиянием.

По сути, алгоритм двоичного поиска просто делит свое рабочее пространство (входной (упорядоченный) массив размера n) на половину в каждой итерации. Следовательно, это определенно развертывание стратегии Делить , и, как следствие, временная сложность уменьшается до O (LG N). Таким образом, это покрывает ее «разделить» часть.

Как можно заметить, окончательное решение получается из последнего сделанного сравнения, то есть, когда у нас остается только один элемент для сравнения. Бинарный поиск не объединяет и не объединяет решение.

Короче говоря, двоичный поиск делит размер проблемы (над которой он должен работать) на две части, но не находит решение на кусочки и, следовательно, нет возникает необходимость объединения решения!

Я знаю, что это слишком долго, но я надеюсь, что это поможет:)

Также вы можете получить представление от: https://www.khanacademy.org/computing/computer-science/algorithms/binary-search/a/running-time-of-binary-search

Также я только сейчас понял, что этот вопрос был задан давно! Мой плохой!

2 голосов
/ 08 сентября 2017

В дополнение к @ посту Кенчи алгоритмы DnC имеют несколько общих / общих свойств;они:

  1. делят исходный экземпляр проблемы на набор его меньших подэлементов;
  2. независимо решают каждый подпунктэкземпляр;
  3. объединяет меньшие / независимые решения подэкземпляра для создания единого решения для большего / оригинального экземпляра

Проблема с бинарным поиском заключается в том, что он не действительно даже генерирует набор независимых подэлементов, которые должны быть решены, согласно шагу 1;это только упрощает исходную проблему путем окончательного отбрасывания разделов, которые ему не интересны. Другими словами, это только уменьшает размер проблемы, и это настолько далеко, насколько это возможно.

Предполагается, что алгоритм DnC не только идентифицирует / решает меньшие экземпляры исходной задачи независимо друг от друга, но также использует этот набор частично независимых решений для «построения» единого решения для более крупного экземпляра задачи какв целом.

В книге Основы алгоритмики , Г. Брассард, П. Бретли сказано следующее (выделено жирным шрифтом, курсив в оригинале):

Это, вероятно, самое простое приложение «разделяй и властвуй», настолько простое, что строго говоря, это приложение упрощения , а не «разделяй и властвуй» : решение для любого достаточно большого экземпляра сводится к решению одного меньшего, в данном случае половинного размера.

Раздел 7.3 Двоичный поиск в стр.226 .

2 голосов
/ 13 января 2012

Очевидно, что некоторые считают двоичный поиск алгоритмом «разделяй и властвуй», а некоторые - нет. Я быстро погуглил три ссылки (кажется, все они связаны с научными кругами), которые называют его алгоритмом D & C: http://www.cs.berkeley.edu/~vazirani/algorithms/chap2.pdf http://homepages.ius.edu/rwisman/C455/html/notes/Chapter2/DivConq.htm http://www.csc.liv.ac.uk/~ped/teachadmin/algor/d_and_c.html

Я думаю, что по общему мнению, алгоритм D & C должен иметь по крайней мере первые две фазы из этих трех:

  • разделить, то есть решить, как вся проблема разделяется на подзадачи;
  • Завоевать, т.е. решить каждую из подзадач независимо;
  • [необязательно] объединять, то есть объединять результаты независимых вычислений вместе.

Второй этап - завоевание - должен рекурсивно применять ту же технику для решения подзадачи путем разделения на еще более мелкие подзадачи и т. Д. На практике, однако, часто используется некоторый порог для ограничения рекурсивного подхода, так как для задач небольшого размера другой подход может быть быстрее. Например, реализации быстрой сортировки часто используют, например, пузырьковая сортировка, когда размер части массива для сортировки становится небольшим.

Третья фаза может быть неактивной, и, по моему мнению, она не дисквалифицирует алгоритм как D & C. Типичным примером является рекурсивная декомпозиция for -петля, где все итерации работают исключительно с независимыми элементами данных (то есть без сокращения какой-либо формы). Это может показаться бесполезным на первый взгляд, но на самом деле это очень мощный способ, например, выполнять цикл параллельно и использовать такие платформы, как Cilk и Intel TBB.

Возвращаясь к исходному вопросу: давайте рассмотрим некоторый код, который реализует алгоритм (я использую C ++; извините, если это не тот язык, который вам удобен):

int search( int value, int* a, int begin, int end ) {
  // end is one past the last element, i.e. [begin, end) is a half-open interval.
  if (begin < end)
  {
    int m = (begin+end)/2;
    if (value==a[m])
      return m;
    else if (value<a[m])
      return search(value, a, begin, m);
    else
      return search(value, a, m+1, end);
  }
  else // begin>=end, i.e. no valid array to search
    return -1;
}

Здесь разделяющая часть - int m = (begin+end)/2;, а все остальное - часть завоевателя. Алгоритм явно написан в рекурсивной форме D & C, хотя берется только одна из ветвей. Однако его также можно записать в форме цикла:

int search( int value, int* a, int size ) {
  int begin=0, end=size;
  while( begin<end ) {
    int m = (begin+end)/2;
    if (value==a[m])
      return m;
    else if (value<a[m])
      end = m;
    else
      begin = m+1;
  }
  return -1;
}

Я думаю, что это довольно распространенный способ реализации бинарного поиска с помощью цикла; Я намеренно использовал те же имена переменных, что и в рекурсивном примере, так что общность легче увидеть. Поэтому мы можем сказать, что снова вычисление средней точки является частью деления, а остальная часть тела цикла является частью завоевателя.

Но, конечно, если ваши экзаменаторы думают иначе, может быть трудно убедить их, что это D & C.

Обновление: мне только что пришло в голову, что если бы я разработал общую реализацию алгоритма D & C, основанную на скелете, я бы, конечно, использовал бинарный поиск в качестве одного из тестов на пригодность API, чтобы проверить, является ли API достаточно мощным, а также кратким. Конечно это ничего не доказывает:)

2 голосов
/ 13 января 2012

Часть деления, конечно, делит множество на две половины.

Часть завоевателя определяет, есть ли и на какой позиции в обработанной части найденный элемент.

1 голос
/ 22 ноября 2015

Алгоритм Разделяй и властвуй основан на 3 шагах следующим образом:

  1. Разделить
  2. властвуй
  3. Объединить

Задача двоичного поиска может быть определена как поиск x в отсортированном массиве A [n]. По данным этой информации:

  1. Разделить: сравнить х со средним
  2. Завоевать: рекурсировать в одном подмассиве. (Нахождение x в этом массиве)
  3. Объединить: не нужно.
1 голос
/ 14 января 2012

A правильный алгоритм «разделяй и властвуй» потребует обработки обеих частей.

Следовательно, многие люди будут не вызывать двоичный поиск в алгоритме «разделяй и властвуй», это действительно делит проблему, но отбрасывает вторую половину.

Но, скорее всего, ваши экзаменаторы просто хотели увидеть, как вы спорите.(Хорошие) экзамены не о фактах, а о том, как вы реагируете, когда задача выходит за рамки исходного материала.

Так что ИМХО правильным ответом было бы:

Хорошотехнически, он состоит только из шага разделения, но ему нужно завоевать только половину первоначальной задачи, тогда как другая половина уже тривиально сделана.

Кстати: есть хорошая вариация QuickSort,называется QuickSelect, который фактически использует эту разницу, чтобы получить в среднем O(n) медианный алгоритм поиска.Это как бы QuickSort - но опускается только в ту половину, которая ему интересна.

1 голос
/ 13 января 2012

Двоичный поиск сложно описать с помощью функции «разделяй и властвуй», поскольку шаг завоевания не является явным. Результатом алгоритма является индекс иглы в стоге сена, и чистая реализация D & C возвращает индекс иглы в наименьшем стоге сена (0 в списке из одного элемента) и затем рекурсивно добавляет смещения в большие стога сена, которые были разделены на этапе деления.

Псевдокод для объяснения:

function binary_search has arguments needle and haystack and returns index
    if haystack has size 1
       return 0
    else 
        divide haystack into upper and lower half
        if needle is smaller than smallest element of upper half
            return 0 + binary_search needle, lower half
        else
            return size of lower half + binary_search needle, upper half

Дополнение (0 + или size of lower half) является частью завоевателя. Большинство людей пропускают его, предоставляя индексы в виде большого списка в качестве аргументов, и поэтому он часто недоступен.

0 голосов
/ 26 мая 2015

Нет, бинарный поиск не разделяй и не властвуй. Да, бинарный поиск уменьшается и побеждает. Я полагаю, что алгоритмы «разделяй и властвуй» имеют эффективность O (n log (n)), а алгоритмы уменьшения и завоевания - O (log (n)). Разница в том, нужно ли вам оценивать обе части разделения в данных или нет.

...