Почему Binary Search алгоритм разделения и покорения?

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

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

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

Ответ 1

Книга

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

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

Ответ 2

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

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

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

Ответ 3

В стратегии разделения и завоевания:

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

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

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

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

В принципе, алгоритм двоичного поиска просто делит свое рабочее пространство (входной (упорядоченный) массив размера n) на половину на каждой итерации. Поэтому он определенно развертывает стратегию разделения и, как результат, временная сложность сводится к O (lg n). Таким образом, это покрывает "разделительную" часть.

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

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

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

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

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

Ответ 4

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

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

Ответ 5

По-видимому, некоторые люди считают бинарный поиск алгоритмом разделения и покоя, а некоторые нет. Я быстро googled три ссылки (все, кажется, связаны с академией), которые называют это алгоритмом 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 должен иметь по крайней мере первые две фазы этих трех:

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

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

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

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

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 достаточно мощным, а также кратким. Конечно, это ничего не доказывает:)

Ответ 6

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

Pseudocode для объяснения:

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) является частью завоевания. Большинство людей пропускают его, предоставляя индексы в более крупный список в качестве аргументов, и, следовательно, часто недоступны.

Ответ 7

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

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

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

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

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

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

Ответ 8

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

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

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

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

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

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

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

Ответ 9

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

Здесь цитата из wikipedia:

Название "divide and conquer" иногда применяется также к алгоритмам, которые сводят каждую проблему только к одной подзадаче, такой как алгоритм бинарного поиска для поиска записи в отсортированном списке.

Это говорит о том, что НЕ [обновление: неправильно продумать эту фразу:)] только одна часть разделения и покорения.

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

Ответ 10

Двоичный поиск - это алгоритм деления и покорения:

1) В алгоритмах Divide и Conquer мы пытаемся решить проблему, решая меньшую подзадачу (разделите часть) и используем решение для построения решения для нашей более крупной проблемы (Conquer).

2) Здесь наша задача - найти элемент в отсортированном массиве. Мы можем решить это, разрешив подобную подпункт. (Мы создаем дополнительные проблемы здесь, основываясь на решении, что поиск элемента меньше или больше среднего элемента). Таким образом, как только мы узнаем, что элемент не может существовать, безусловно, в одной половине, мы решаем аналогичную подзадачу в другой половине.

3) Таким образом, мы рекурсируем.

4) Часть завоевания здесь просто возвращает значение, возвращаемое вспомогательной проблемой, в начало рекурсивного дерева

Ответ 11

Дихотомика в информатике относится к выбору между двумя противоположными вариантами выбора между двумя различными альтернативами. Дихотомия - это любое расщепление целого на две неперекрывающиеся части, то есть это процедура, в которой целое разделено на две части. Это разбиение целого (или набора) на две части (подмножества), которые: 1. Совместно исчерпывающий: все должно принадлежать той или другой части, и 2. Взаимный эксклюзив: ничто не может принадлежать одновременно обеим частям.

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

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

Ответ 12

Я думаю, что это Decrease и Conquer.

Вот цитата из Википедии.

"Вместо этого было предложено уменьшить имя и победить класс с одной подзадачей"

http://en.wikipedia.org/wiki/Divide_and_conquer_algorithms#Decrease_and_conquer

По моему мнению, "Завоевать" часть заканчивается, когда вы находите целевой элемент двоичного поиска. Часть "Уменьшение" уменьшает пространство поиска.

Ответ 13

Алгоритмы двоичного поиска и тройного поиска основаны на методе уменьшения и покорения. Поскольку вы не делите проблему, вы фактически уменьшаете проблему, разделив ее на 2 (3 в тройном поиске).

Алгоритмы сортировки сортировки и быстрой сортировки могут быть приведены в качестве примеров техники Divide и Conquer. Вы делите проблему на две подзадачи и снова используете алгоритм для этих подзадач для сортировки массива. Но вы отбрасываете половину массива в двоичном поиске. Это означает, что вы уменьшите размер массива, а не разделите.

Ответ 14

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

Ответ 15

Алгоритм Divide and Conquer основан на 3 шагах следующим образом:

  • Деление
  • властвуй
  • Объединить

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

  • Разделить: сравнить x со средним
  • Conquer: Recurse в одном вспомогательном массиве. (Поиск x в этом массиве)
  • Объединить: это необязательно.