Лекция 13: Трудноразрешимые задачи. NP-полнота

Preview:

Citation preview

Лекция 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).

Recommended