- •Содержание
- •Введение.
- •1. Основы анализа алгоритмов
- •1.1. Сравнительные оценки алгоритмов
- •1.2. Элементарные операции в формальной системе
- •1.3. Классы входных данных
- •1.4. Классификация алгоритмов по виду функции трудоемкости
- •1.5. Классификация скоростей роста. Асимптотический анализ функций
- •1. Оценка (тета)
- •2. Оценка о (о большое)
- •3. Оценка (Омега)
- •1.6. Эффективность рекурсивных алгоритмов
- •1.7. Анализ программ
- •1.8. Вопросы для самоконтроля
- •Классификация алгоритмов по виду функции трудоемкости.
- •2. Алгоритмы поиска и выборки
- •2.1. Последовательный поиск
- •2.2. Двоичный поиск
- •2.3. Задача выборки
- •2.4. Вопросы для самоконтроля
- •3.Алгоритмы сортировки
- •3.1. Сортировка трех чисел по месту
- •3.2. Сортировка вставками
- •3.3. Пузырьковая сортировка
- •3.4. Сортировка Шелла.
- •3.5. Корневая сортировка
- •3.6. Сортировка методом индексов
- •3.7. Быстрая сортировка (алгоритм Хоара)
- •3.8. Вопросы для самоконтроля
- •Сортировка Шелла.
- •Сортировка методом индексов.
- •4. Алгоритмы на графах
- •4.1. Основные понятия теории графов
- •4.2. Структуры данных для представления графов
- •4.3. Алгоритмы обхода вершин графа
- •4.3.1. Обход в глубину
- •4.3.2. Обход в ширину
- •4.4. Поиск остовного дерева минимального веса
- •4.4.1. Алгоритм Дейкстры – Прима
- •4.4.2. Алгоритм Крускала
- •4.5. Алгоритм поиска кратчайшего пути
- •4.6. Вопросы для самоконтроля
- •Структуры данных для представления графов.
- •5. Численные методы
- •5.1. Вычисление значений многочленов
- •5.2. Умножение матриц
- •5.2.1 Стандартный алгоритм умножения матриц
- •5.2.2. Умножение матриц по Винограду
- •5.2.3. Умножение матриц по Штрассену
- •5.3. Вопросы для самоконтроля
- •Стандартный алгоритм умножения матриц.
- •6. Алгоритмы сравнения с образцами
- •6.1. Сравнение строк
- •6.2. Алгоритм Кнута – Морриса – Пратта
- •6.3. Алгоритм Бойера - Мура
- •6.4. Вопросы для самоконтроля
- •7. Вычислительная геометрия
- •7.1. Основные понятия
- •7.2. Векторное произведение векторов
- •7.2.1. Ориентированная площадь треугольника
- •7 .3. Задача о выпуклой оболочке
- •7.3.1. Алгоритм Грэхема
- •7.3.2. Алгоритм Джарвиса
- •7.3.3. Рекурсивный алгоритм
- •7.4. Вопросы для самоконтроля
- •8. Задачи класса np
- •8.1. Примеры np-полных задач
- •8.1.1. Задача о коммивояжере
- •8.1.2. Задача о раскраске графа
- •8.1.3. Раскладка по ящикам
- •8.1.4 Упаковка рюкзака
- •8.1.5. Задача о суммах элементов подмножества
- •8.1.6. Задача о планировании работ
- •8.2. Приближенные эвристические решения nр-полных задач.
- •8.2.1. Жадные приближенные алгоритмы
- •8.2.2. Приближения в задаче коммивояжера
- •8.2.3. Приближения в задаче о раскладке по ящикам
- •8.2.4. Приближения в задаче об упаковке рюкзака
- •8.3. Вопросы для самопроверки
- •Приближения в задаче об упаковке рюкзака.
- •9. Динамическое программирование
- •Часть1--------------------
- •10. Метод ветвей и границ
- •Вопросы к зачету
- •Классификация алгоритмов по виду функции трудоемкости.
- •Приближения в задаче об упаковке рюкзака.
- •Динамическое программирование
- •Метод ветвей и границ. Литература
5.2.3. Умножение матриц по Штрассену
Алгоритм Штрассена работает с квадратными матрицами. На самом деле он настолько эффективен, что иногда разумно расширить матрицы до квадратных, и при этом он все равно дает выигрыш, превышающий расходы на введение дополнительных элементов.
Для умножения 2х2 матриц алгоритм Штрассена использует семь формул. Эти формулы чрезвычайно неестественны, и, к сожалению, в оригинальной статье Штрассена не объясняется, как он пришел к ним. Замечательно, что как сами формулы, так и их использование не требует, чтобы умножение элементов матрицы было коммутативным. Это означает, в частности, что сами эти элементы могут быть матрицами, а, значит, алгоритм Штрассена можно применять рекурсивно. Вот формулы Штрассена:
x1=(G1,1+G2,2) (H1,1+H2,2) x2=(G2,1+G2,2) H1,1 x3=G1,1(H1,2-H2,2) x4=G2,2(H2,1-H1,1) |
x5=(G1,1+G2,2) H2,2 x6=(G2,1-G1,1)(H1,1+H1,2) x7=(G2,1-G2,2)(H2,1+H2,2) |
Теперь элементы матрицы R могут вычисляться по формулам
R1,1=x1+x4-x5+x7; R2,1=x2+x4; |
R1,2=x3+x5; R2,2=x1+x3-x2+x6. |
Анализ общего случая показывает, что число умножений при перемножении двух NN матриц приблизительно равно N2.81, а число сложений 6N2.81-6N2.
На практике алгоритм Штрассена применяется редко: его использование требует аккуратного отслеживания рекурсии. Важность его состоит в том, что это первый алгоритм, с помощью которого умножение матриц требует менее, чем О(N3) операций.
Сводная таблица оценок алгоритмов для умножения квадратных матриц размером NN:
|
Умножений |
Сложений |
Стандартный алгоритм |
N3 |
N3-N2 |
Алгоритм Винограда |
(N3+2N2)/2 |
(3N3+4N2-4N)/2 |
Алгоритм Штрассена |
N2.81 |
6N2.81-6N2. |
5.3. Вопросы для самоконтроля
Вычисление значений многочленов стандартным способом.
Вычисление значений многочленов по схеме Горнера.
Стандартный алгоритм умножения матриц.
Особенности умножения матриц по Винограду.
Основная идея алгоритма Штрассена для умножения матриц.
6. Алгоритмы сравнения с образцами
Поиск подстроки в длинном тексте - важный элемент текстовых редакторов. Поиск по образцу можно применять не только в текстовых строках, но и для поиска битовых или байтовых строк в двоичном файле. Так, например, осуществляется поиск вирусов в памяти компьютера.
В программе обработки текстов обычно имеется функция проверки синтаксиса, которая не только обнаруживает неправильно написанные слова, но и предлагает варианты их правильного написания.
6.1. Сравнение строк
Необходимо найти первое вхождение некоторой подстроки в длинном тексте.
Стандартный алгоритм начинает со сравнения первого символа текста с первым символом подстроки. Если они совпадают, то происходит переход ко второму символу текста и подстроки.
При совпадении сравниваются следующие символы. Так продолжается до тех пор, пока не окажется, что подстрока целиком совпала с отрезком текста, или пока не встретятся несовпадающие символы.
В первом случае задача решена, во втором - мы сдвигаем указатель текущего положения в тексте на 1 символ и заново начинаем сравнение.
Пример 6.1 Поиск подстроки (РЫБАК) в соответствующем тексте.
Текст РЫБА РЫБАКА ВИДИТ
подстрока РЫБАК
Р |
ы |
б |
а |
|
р |
ы |
б |
а |
к |
а |
|
в |
и |
д |
и |
т |
|
|
р |
ы |
б |
а |
к |
|
|
|
|
|
|
|
|
|
|
|
|
1 проход, 5 сравнений |
|
|
р |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 проход, 1 сравнение |
|
|
|
р |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 проход, 1 сравнение |
|
|
|
|
р |
|
|
|
|
|
|
|
|
|
|
|
|
|
4 проход, 1 сравнение |
|
|
|
|
|
р |
|
|
|
|
|
|
|
|
|
|
|
|
5 проход, 1 сравнение |
|
|
|
|
|
|
р |
ы |
б |
а |
к |
|
|
|
|
|
|
|
6 проход, 5 сравнений |
|
Итого: |
14 сравнений, слово найдено |
SimpleSearch (Text, Substring)
// PS - указатель текущего сравнения символа в подстроке
// PT - указатель текущего сравн. символа в тексте
// Start - указатель на начало сравнения в тексте
pS = 1; pt = 1; Start = 1
Start
While pT length (text) and pS length (substring) do
if text(pt) = substr(pS) then // есть очередное совпадение
pt = pt + 1; pS = pS + 1
else // начато сравнение заново с текущим символом
start = start +1; pt = start; pS = 1
end if
end while
if ps > length (substr)
then return (start) // совпадение найдено
else return (0) // совпадение не найдено
endif
Наилучший случай тот, где искомое слово встречается с самого первого символа строки и fА (N)= NS сравнений, где NS - длина подстроки
Наихудший случай - при каждом проходе совпадают все символы, кроме последнего (например, в строке «хххх…х» искать «хххху»). В этом случае число сравнений fА (N)=(NT-NS+1)NS, где NT – длина строки текста.
Асимптотическая оценка сложности простого алгоритма – О(NT* NS).
Проблема стандартного алгоритма заключается в том, что он затрачивает много усилий впустую. Если сравнение начала подстроки уже произошло, то полученную информацию можно использовать для того, чтобы определить позицию следующего сравнения. Например, в вышеприведенном примере в искомой подстроке буква «Р» встречается 1 раз. Мы сделали 5 сравнений при первом проходе, получили отрицательный результат, следовательно, можно сразу сдвинуть точку Start на 5 (пять!) позиций вправо.