<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>http://digida.mgpu.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=93.85.0.0%2F16</id>
	<title>Поле цифровой дидактики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="http://digida.mgpu.ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=93.85.0.0%2F16"/>
	<link rel="alternate" type="text/html" href="http://digida.mgpu.ru/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/93.85.0.0/16"/>
	<updated>2026-10-18T06:48:06Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>http://digida.mgpu.ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B2%D1%8B%D0%B1%D0%BE%D1%80%D0%B0&amp;diff=4644</id>
		<title>Алгоритм выбора</title>
		<link rel="alternate" type="text/html" href="http://digida.mgpu.ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%B2%D1%8B%D0%B1%D0%BE%D1%80%D0%B0&amp;diff=4644"/>
		<updated>2017-11-06T01:08:53Z</updated>

		<summary type="html">&lt;p&gt;93.85.57.46: итерацией&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;В [[информатика|информатике]] &#039;&#039;&#039;алгоритм выбора&#039;&#039;&#039; — это [[алгоритм]] для нахождения &#039;&#039;k&#039;&#039;-го по величине элемента в [[массив (программирование)|массиве]] (такой элемент называется &#039;&#039;&#039;&#039;&#039;k-й порядковой статистикой&#039;&#039;&#039;&#039;&#039;). Частными случаями этого алгоритма являются нахождение [[Минимальный элемент|минимального элемента]], [[Максимальный элемент|максимального элемента]] и [[Медиана (статистика)|медианы]]. Существует алгоритм, который гарантированно решает задачу выбора k-го по величине элемента за O(&#039;&#039;n&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
== Выбор с помощью сортировки ==&lt;br /&gt;
Задачу выбора можно свести к [[Алгоритм сортировки|сортировке]]. В самом деле, можно упорядочить массив, а затем взять нужный по счету элемент. Это эффективно в том случае, когда выбор нужно делать многократно: тогда можно отсортировать массив за O(&#039;&#039;n&#039;&#039; log &#039;&#039;n&#039;&#039;) и затем выбирать из него элементы. Однако если выбор нужно произвести однократно, данный алгоритм может оказаться неоправданно долгим.&lt;br /&gt;
&lt;br /&gt;
== Линейный алгоритм для нахождения минимума (максимума) ==&lt;br /&gt;
Очевидно, как за линейное время найти минимум (максимум) в данном массиве:&lt;br /&gt;
&lt;br /&gt;
* Изначально присвоить &amp;lt;math&amp;gt;min = a[0];&amp;lt;/math&amp;gt;&lt;br /&gt;
* Для каждого элемента &amp;lt;math&amp;gt;a[i]&amp;lt;/math&amp;gt; выполнить: если &amp;lt;math&amp;gt;min &amp;gt; a[i]&amp;lt;/math&amp;gt;, присвоить &amp;lt;math&amp;gt;min = a[i]&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Линейный в среднем алгоритм для нахождения &#039;&#039;k&#039;&#039;-й порядковой статистики ==&lt;br /&gt;
Существует алгоритм для нахождения &#039;&#039;k&#039;&#039;-й порядковой статистики, основанный на [[Quicksort|алгоритме быстрой сортировки]] и работающий за O(&#039;&#039;n&#039;&#039;) в среднем.&lt;br /&gt;
&lt;br /&gt;
Идея алгоритма заключается в том, что массив разбивается на две части относительно случайно (равновероятно) выбранного элемента — в одну часть попадают элементы, меньшие, чем выбранный, в другую — остальные (эта операция выполняется за &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;, по её окончанию выбранный элемент находится в позиции &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;). Если в первой части оказалось ровно &amp;lt;math&amp;gt;k-1&amp;lt;/math&amp;gt; элементов (&amp;lt;math&amp;gt;j=k&amp;lt;/math&amp;gt;), то выбранный элемент является искомым, если &amp;lt;math&amp;gt;j&amp;gt;k&amp;lt;/math&amp;gt;, то алгоритм выполняется рекурсивно для первой части массива, иначе — для второй (в последнем случае для следующей итерации от &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; отнимается &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt;). Рекурсивные вызовы приводят к экспоненциально уменьшающемуся с каждой итерацией размеру обрабатываемого массива, и по этой причине время выполнения алгоритма составляет &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм BFPRT (линейный детерминированный) ==&lt;br /&gt;
&#039;&#039;&#039;BFPRT-Алгоритм&#039;&#039;&#039; позволяет найти &#039;&#039;k&#039;&#039;-ю порядковую статистику гарантированно за O(&#039;&#039;n&#039;&#039;). Назван в честь своих изобретателей: Manual &#039;&#039;&#039;B&#039;&#039;&#039;lum, Robert W. &#039;&#039;&#039;F&#039;&#039;&#039;loyd, Vaughan R. &#039;&#039;&#039;P&#039;&#039;&#039;ratt, Ronald L. &#039;&#039;&#039;R&#039;&#039;&#039;ivest и Robert Endre &#039;&#039;&#039;T&#039;&#039;&#039;arjan. Используется при достаточно длинном списке элементов, свыше 800 элементов.&lt;br /&gt;
&lt;br /&gt;
=== Принцип действия ===&lt;br /&gt;
Ввод: число &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;, обозначающее &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-й элемент.&lt;br /&gt;
&lt;br /&gt;
# Список делится на подмножества элементов, по 5 элементов в каждом (кроме последнего подмножества). Число элементов в подмножествах может превышать 5 и должно быть в любом случае нечётным. Однако если делить список на подмножества из 3 элементов, время работы не будет линейным.&lt;br /&gt;
# Каждое подмножество сортируется с помощью подходящего [[алгоритм сортировки|алгоритма сортировки]].&lt;br /&gt;
# Пусть &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; — множество медиан, образовавшихся в подмножествах после сортировки. Рекурсивно находится медиана в &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; — медиана медиан. Назовем её &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;.&lt;br /&gt;
#* Результирующая после 3 шага структура, имеет следующую особенность:&lt;br /&gt;
#** Четверть всех элементов в любом случае имеет ключ &amp;lt;math&amp;gt; &amp;lt; s&amp;lt;/math&amp;gt;. (Подмножество множества &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;)&lt;br /&gt;
#** Четверть всех элементов в любом случае имеет ключ &amp;lt;math&amp;gt; &amp;gt; s&amp;lt;/math&amp;gt;. (Подмножество множества &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt;)&lt;br /&gt;
# Теперь список разбивается относительно медианы s на 2 подмножества &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt;. При этом нужно сравнить с s только половину всех элементов, так как две четверти элементов уже отсортированы относительно s. В результате каждое из подмножеств &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt; содержит максимально 3/4 всех элементов (минимально — 1/4 всех элементов).&lt;br /&gt;
# Если:&lt;br /&gt;
#* &amp;lt;math&amp;gt;i = |S_1| + 1&amp;lt;/math&amp;gt;, то искомый элемент найден — это медиана медиан &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt;&lt;br /&gt;
#* &amp;lt;math&amp;gt;i \leq |S_1|&amp;lt;/math&amp;gt;, то алгоритм вызывается рекурсивно на множестве &amp;lt;math&amp;gt;S_1&amp;lt;/math&amp;gt;&lt;br /&gt;
#* в любом другом случае, алгоритм вызывается рекурсивно на множестве &amp;lt;math&amp;gt;S_2&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Гарантированное время работы ===&lt;br /&gt;
При каждом [[рекурсия|рекурсивном вызове]], алгоритм позволяет отбросить минимум четверть всех элементов. Это обеспечивает верхнюю оценку на гарантированное линейное время работы для [[Детерминированный алгоритм|детерминированного алгоритма]], так как оно выражается рекуррентным соотношением &amp;lt;math&amp;gt;T(n) = O(n) + T\left({\frac{n}{5}}\right) + T\left({\frac{7}{10}n}\right)&amp;lt;/math&amp;gt;. В общем случае, если подмножества имеют размер &amp;lt;math&amp;gt;2k+1&amp;lt;/math&amp;gt;, время работы выражается как &amp;lt;math&amp;gt;T(n) = O(n) + T\left({\frac{n}{2k+1}}\right) + T\left({\frac{3k+1}{4k+2}n}\right)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
* {{книга&lt;br /&gt;
|автор = Volker Heun&lt;br /&gt;
|заглавие = Основные Алгоритмы&lt;br /&gt;
|оригинал = Grundlegende Algorithmen&lt;br /&gt;
|ссылка = &lt;br /&gt;
|издание = 1-е изд&lt;br /&gt;
|место =  Мюнхен&lt;br /&gt;
|издательство = Vieweg Verlag&lt;br /&gt;
|год = 2000&lt;br /&gt;
|страницы = 86&lt;br /&gt;
|isbn = 3-528-03140-9&lt;br /&gt;
}}&lt;br /&gt;
* [http://people.csail.mit.edu/rivest/BlumFloydPrattRivestTarjan-TimeBoundsForSelection.pdf Time Bounds for Selection by Manual Blum, Robert W. Floyd, Vaughan Pratt, Ronald L. Rivest, and Robert E. Tarjan. Journal of Computer and System Sciences 7,4 August 1973, 448—460] {{ref-en}}&lt;br /&gt;
&lt;br /&gt;
[[Категория:Алгоритмы поиска]]&lt;/div&gt;</summary>
		<author><name>93.85.57.46</name></author>
	</entry>
</feed>