Алгоритм на месте - In-place algorithm

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

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

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

Примеры

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

 функция reverse (a [0..n - 1]) выделить b [0..n - 1] за я из 0 к n - 1 b [n - 1 - i]: = a [i] возвращаться б

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

 функция reverse_in_place (a [0..n-1]) за я из 0 к этаж ((n-2) / 2) tmp: = a [i] a [i]: = a [n - 1 - i] a [n - 1 - i]: = tmp

Другой пример: многие алгоритмы сортировки упорядочить массивы в отсортированном порядке на месте, включая: пузырьковая сортировка, гребенчатая сортировка, сортировка выбора, вставка сортировки, heapsort, и Сортировка оболочки. Для этих алгоритмов требуется всего несколько указателей, поэтому их пространственная сложность составляет О(бревно п).[1]

Быстрая сортировка работает на месте с данными, которые нужно отсортировать. Однако для быстрой сортировки требуется О(бревно п) указатели пространства стека для отслеживания подмассивов в его разделяй и властвуй стратегия. Следовательно, для быстрой сортировки требуется О(бревно2 п) дополнительное пространство. Хотя это непостоянное пространство технически исключает быструю сортировку из категории на месте, быстрая сортировка и другие алгоритмы, требующие только О(бревно п) дополнительные указатели обычно считаются оперативными алгоритмами.

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

Некоторые алгоритмы обработки текста, такие как подрезать и обратное может быть выполнено на месте.

По вычислительной сложности

В теория сложности вычислений, строгое определение локальных алгоритмов включает все алгоритмы с О(1) космическая сложность, класс DSPACE(1). Этот класс очень ограничен; это равно обычные языки.[2] Фактически, он даже не включает ни одного из перечисленных выше примеров.

Обычно мы рассматриваем алгоритмы в L, класс задач, требующих О(бревно п) дополнительное пространство, чтобы быть на месте. Этот класс больше соответствует практическому определению, так как позволяет использовать числа размера п как указатели или индексы. Однако это расширенное определение по-прежнему исключает быструю сортировку из-за ее рекурсивных вызовов.

Идентификация алгоритмов на месте с помощью L имеет некоторые интересные последствия; например, это означает, что существует (довольно сложный) алгоритм на месте, чтобы определить, существует ли путь между двумя узлами в неориентированный граф,[3] проблема, которая требует О(п) дополнительное пространство с использованием типичных алгоритмов, таких как поиск в глубину (бит посещения для каждого узла). Это, в свою очередь, дает на месте алгоритмы для таких проблем, как определение того, является ли граф двудольный или проверка того, имеют ли два графика одинаковое количество связанные компоненты. Видеть SL для дополнительной информации.

Роль случайности

Во многих случаях требования к пространству для алгоритма можно резко сократить, используя рандомизированный алгоритм. Например, предположим, что мы хотим знать, есть ли две вершины в графе п вершины находятся в одном связный компонент графа. Нет известного простого детерминированного локального алгоритма для определения этого, но если мы просто начнем с одной вершины и выполним случайная прогулка около 20п3 шагов, вероятность того, что мы наткнемся на другую вершину, при условии, что она находится в том же компоненте, очень высока. Точно так же существуют простые рандомизированные на месте алгоритмы для проверки простоты, такие как Тест на простоту Миллера-Рабина, а также есть простые алгоритмы рандомизированного факторинга на месте, такие как Алгоритм ро Полларда. Видеть RL и BPL для более подробного обсуждения этого явления.

В функциональном программировании

Функциональное программирование языки часто не одобряют или не поддерживают явные на месте алгоритмы, которые перезаписывают данные, поскольку это тип побочный эффект; вместо этого они позволяют создавать только новые данные. Однако хорошие компиляторы функционального языка часто распознают, когда создается объект, очень похожий на существующий, а затем старый отбрасывается, и оптимизируют это до простой мутации «под капотом».

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

Смотрите также

Рекомендации

  1. ^ Требуемое битовое пространство указателя равно О(бревно п), но размер указателя можно считать постоянным в большинстве приложений сортировки.
  2. ^ Мацей Лиськевич и Рюдигер Рейщук. Сложный мир под логарифмическим пространством. Структура в теории сложности конференцииС. 64-78. 1994. Online: p. 3, теорема 2.
  3. ^ Рейнгольд, Омер (2008), «Ненаправленное подключение в лог-пространстве», Журнал ACM, 55 (4): 1–24, Дои:10.1145/1391289.1391291, МИСТЕР  2445014, ECCC  TR04-094