Лекция 13: Трудноразрешимые задачи. NP-полнота.
-
Upload
mikhail-kurnosov -
Category
Education
-
view
491 -
download
4
Transcript of Лекция 13: Трудноразрешимые задачи. NP-полнота.
Лекция 11:
Методы разработки
алгоритмов
Курносов Михаил Георгиевич
к.т.н. доцент Кафедры вычислительных систем
Сибирский государственный университет
телекоммуникаций и информатики
http://www.mkurnosov.net
Контроль
2
1. Что такое остовное дерево (Spanning tree)?
2. Что такое остовное дерево минимальной стоимости
(Minimum spanning tree)?
3. Какие алгоритмы построения остовных деревьев
минимальной стоимости Вам известны?
4. Приведите примеры практического использования
задачи о построении остовного дерева минимальной
стоимости.
Основные методы разработки алгоритмов
33
� Метод грубой силы (brute force, исчерпывающий поиск –
полный перебор).
� Декомпозиция (decomposition, “разделяй и властвуй”)
� Уменьшение размера задачи (“уменьшай и властвуй”)
� Преобразование (“преобразуй и властвуй”)
� Жадные алгоритмы (greedy algorithms)
� Динамическое программирование (dynamic programming)
� Поиск с возвратом (backtracking)
� Локальный поиск (local search)
Метод грубой силы (brute force)
44
� Метод грубой силы – решение “в лоб”.
� Основан на прямом подходе к решению задачи.
Опирается на определения понятий, используемых в
постановке задачи.
Пример. Задач возведения числа a в неотрицательную
степень n.
По определению an = a · a ·… · a
n
Метод грубой силы (brute force)
55
function pow(a, n)
pow = 1
for i = 1 to n do
pow = pow * a
end for
end function
Из определения следует простейший алгоритм
T = O(n)
Метод грубой силы (brute force)
66
Примеры алгоритмов, основанных на методе грубой силы:
� Умножение матриц по определению
� Поиск наибольшего/наименьшего элемента в списке
� Сортировка выбором (Selection sort)
� Пузырьковая сортировка (Bubble sort)
� Поиск подстроки в строке методом грубой силы
� Поиск пары ближайших точек на плоскоси
� …
function strcmp(s, p)
n = strlen(s)
m = strlen(p)
for i = 1 to n – m do
j = 1
while j <= m and s[i + j - 1] = p[j] do
j = j + 1
end while
if j > m then
return i
end if
end for
end function
Поиск подстроки в строке (String match)
77
H e l l o W o r l d
l o W o
s
p
i = 4
Поиск подстроки p в строке s методом грубой силы:
Поиск пары ближайших точек (Closest points)
88
� Задача. Во множестве n точек необходимо найти
две, расстояние между которыми минимально
(точки ближе других друг к другу).
� Координаты всех точек известны: Pi = (xi, yi).
� Расстояние d(i, j) между парой точек вычисляется
как евклидово:
d(i, j) = sqrt((xi – xj)2 + (yi – yj)
2)
function SearchClosestPoints()
dmin = Infinity
for i = 1 to n – 1 do
for j = i + 1 to n do
d = sqrt((x[i] – x[j])^2 +
(y[i] – y[j])^2)
if d < dmin then
dmin = d
imin = i
jmin = j
end if
end for
end for
return imin, jmin
end function
Поиск пары ближайших точек (Closest points)
99
Какова вычислительная
сложность алгоритма?
T = O(n2)
Метод декомпозиции (Decomposition)
1010
� Метод декомпозиции (decomposition method,
метод “разделяй и властвуй” – “divide and conquer”).
� Структура алгоритмов, основанных на этом методе:
1. Задача разбивается на несколько меньших
экземпляров той же задачи.
2. Решаются сформированные меньшие экземпляры
задачи (обычно рекурсивно).
3. При необходимости решение исходной задачи
формируется как комбинация решений меньших
экземпляров задачи.
Вычисление суммы чисел
1111
� Задача. Вычислить сумму чисел a0, a1, .., an – 1.
� Алгоритм на основе метода грубой силы
(brute force, по определению):
function sum(a[0, n - 1])
sum = 0
for i = 0 to n - 1 do
sum = sum + a[i]
end for
end functionT = O(n)
Вычисление суммы чисел
1212
� Задача. Вычислить сумму чисел a0, a1, .., an – 1.
� Алгоритм на основе метода декомпозиции:�� + ⋯ + ���� = �� + ⋯ + � � ⁄ �� + � � ⁄ + … + ����4 + 5 + 1 + 9 + 13 + 11 + 7 = (4 + 5 + 1) + (9 + 13 + 11 + 7) =
= (4 + (5 + 1)) + ((9 + 13) + (11 + 7)) = 50
int sum(int *a, int l, int r)
{
int k;
if (l == r)
return a[l];
k = (r - l + 1) / 2;
return sum(a, l, l + k - 1) +
sum(a, l + k, r);
}
int main()
{
s = sum(a, 0, N - 1);
}
Вычисление суммы чисел (декомпозиция)
1313
Вычисление суммы чисел (декомпозиция)
1414
[0, 6]
[0, 2] [3, 6]
[0, 0] [1, 2]
[1, 1] [2, 2]
[3, 4]
[3, 3] [4, 4]
[5, 6]
[5, 5] [6, 6]
4 + 5 + 1 + 9 + 13 + 11 + 7 = (4 + 5 + 1) + (9 + 13 + 11 + 7) =
= (4 + (5 + 1)) + ((9 + 13) + (11 + 7)) = 50
Структура рекурсивных вызовов функции sum(0, 6)
int pow_decomp(int a, int n)
{
int k;
if (n == 1)
return a;
k = n / 2;
return pow_decomp(a, k) * pow_decomp(a, n - k);
}
Возведение числа а в степень n
1515
� Задача. Возвести число a неотрицательную степень n.
Алгоритм на основе метода декомпозиции:
� = �� �⁄ ∙ � � �⁄ , � > 1�, � = 1T = O(n)
Метод декомпозиции (Decomposition)
1616
� В общем случае задача размера n делится на экземпляры
задачи размера n / b, из которых a требуется решить
(b > 1, a ≥ 0).
� Время T(n) работы алгоритмы, основанного на методе
декомпозиции есть
T(n) = aT(n / b) + f(n), (*)
где f(n) – функция, учитывающая затраты времени на
разделение задачи на экземпляры и комбинирование их
решений.
Рекуррентное соотношение (*) –
это обобщённое рекуррентное уравнение декомпозиции
(general divide-and-conquer recurrence)
Метод декомпозиции (Decomposition)
1717
� Теорема. Если в обобщённом рекуррентном уравнении
декомпозициифункция f(n) = Θ(nd), где d ≥ 0, то
� � = � � �� , если� < �� ,� �� log � , если� = �� ,� �#$%&' , если� > �� .
Анализ алгоритма суммирования чисел
1818
Алгоритм суммирования n чисел:
� b = 2 (интервал делим на 2 части)
� а = 2 (обе части обрабатываем)
� f(n) = 1
(трудоемкость разделения интервала на 2 подмножества
и слияние результатов (операция “+”)выполняется за
время O(1))
T(n) = 2T(n / 2) + 1
Так как, f(n) = 1 = Θ(n0), то d = 0, следовательно по теореме
� � = � �#$%)� = � �
Метод декомпозиции (Decomposition)
1919
Примеры алгоритмов, основанных на методе декомпозиции:
� Сортировка слиянием (Mergesort)
� Быстрая сортировка (QuickSort)
� Бинарный поиск (Binary search)
� Обход двоичного дерева (Tree traverse)
� Решение задачи о поиске пары ближайших точек
� Решение задачи о поиске выпуклой оболочки
� Умножение матриц алгоритмом Штрассена
� …
Сортировка слиянием (Mergesort)
2020
function MergeSort(a[0, n - 1])
if n > 1 then
k = n / 2
Copy(a[0, k - 1], b[0, k - 1])
Copy(a[k, n - 1], c[0, k - 1])
MergeSort(b)
MergeSort(c)
Merge(b, c, a)
end if
end function
Сортировка слиянием (Mergesort)
2121
function Merge(b[p], c[q], a[n])
i = j = k = 0
while i < p and j < q do
if b[i] ≤ c[j] then
a[k] = b[i]
i = i + 1
else
a[k] = c[j]
j = j + 1
end if
k = k + 1
end while
if i = p then
Copy(c[j, q - 1], a[k, p + q - 1])
else
Copy(b[i, p - 1], a[k, p + q - 1])
end if
end function
Анализ алгоритма сортировки слиянием
2222
� b = 2 (массив делим на 2 части)
� а = 2 (обе части обрабатываем)
� f(n) = Tmerge(n) – количество сравнений в процессе слияния
массивов. В худшем случае Tmerge(n) = n – 1
T(n) = 2T(n / 2) + n – 1
Так как, f(n) = n– 1 = Θ(n), то d = 1, следовательно по
теореме � � = � �� log � = � � log �Теоретический минимум трудоемксоти алгоритмов сортировки,
основанных на сравнениях, есть log� �! ≈ �log� � − 1.44�
Пакет gnuplot
2323
100000 0.018952
200000 0.035840
300000 0.054507
400000 0.073788
500000 0.093617
600000 0.113488
700000 0.132952
800000 0.152574
900000 0.173556
1000000 0.193220
Файл mergesort.dat
Пакет gnuplot
2424
set terminal pngcairo size 800,480 enhanced
set output 'mergesort.png'
set key top left
set grid
set format y "%.6f"
set xlabel "Number of elements" font "Times, 16"
set format x "%.0f"
set ylabel "Execution time (sec)" font "Times, 16"
set xtics 100000 font "Times, 12"
set ytics font "Times, 12"
plot "mergesort.dat" using 1:2 title "MergeSort"\
with linespoints ls 1,\
"quicksort.dat" using 1:2 title "QuickSort“\
with linespoints ls 2
Файл graph.pt
Пакет gnuplot
2525
$ gnuplot ./graph.pt
Задание
2626
� Оценить трудоемкость алгоритма быстрой сортировки
с использованием обобщённого рекуррентного уравнения
декомпозиции (Levitin, С. 174).