Мастер класс по алгоритмам. Часть 1
DESCRIPTION
http://it-people.ru/master-klass-po-algoritmam-i-stukturam-dannyx/TRANSCRIPT
Мастер-класс по алгоритмам
Павел Егоровhttps://twitter.com/xoposhiy
Disclaimer
• 200 часов — примерно столько нужно для подготовки минимального специалиста по алгоритмам
• Длительность мастер-класса — 8 часов
Сложность алгоритмовC.N2 с различными константами
Кажется, что константа очень важна
C.N и C.N log(N) в сравнении с C.N2
Константа уходит далеко на второй план
Сложность алгоритмов
• Процессор устроен так, что разные операции стоят разное количество тиков.
• И даже стоимость одной операции может различаться в разы в зависимости от условий
• Константа не имеет смысла!• Принято писать O(N log N), игнорируя
константу
Асимптотическая сложность
Говорят, «сложность алгоритма O(f(n))», если количество операций подразумеваемого вычислителя начиная с некоторого достаточно большого n0 меньше, чем f(n)(с точностью до константы).
Боле строго:
∃C>0, n₀: n > n₀ → operations(n) < C∀ ⋅f(n)
Массив
• Массив: область памяти.• Операции: – a[i] = x – x = a[i]– a.Length
• Важно: нельзя увеличить размер массива
ЗадачаЦиклический сдвиг массива
Сдвинуть массив циклически на k.Идея: k раз сдвинуть массив циклически на 1
Сложность?
Правильное решение?
Циклический сдвиг массива
Циклический сдвиг массива
Reverse(array, 0, k-1); //O(k)Reverse(array, k, n-1); //O(n-k)Reverse(array, 0, n-1); // O(n)
Динамический массив
Хотим массив, но с дополнительной операцией Add(x)Идея: – Держать массив размером с запасом.– Помнить количество использованных
элементов этого массива– При исчерпании запаса — создавать новый
больший массив и копировать всё в него
Динамический массив
Add(x){ if (Count == array.Length) { var newArray = CreateNewArrayOfSize(array.Length+10); Copy(array, newArray); array = newArray; } array[Count++] = x;}for(int i=0; i<N; i++) list.Add(i);
O(N + 10 + 20 + 30 + … + N) = O(N + (10 + N) * N / 20)= O(N*N)
Динамический массив
Add(x){ if (Count == array.Length) { var newArray = CreateNewArrayOfSize(2*array.Length); Copy(array, newArray); array = newArray; } array[Count++] = x;}for(int i=0; i<N; i++) list.Add(i);
O(N + 2 + 4 + 8 + … + N) = O(N + 2*N)= O(N)
ЕЩЁ СТРУКТУРЫ ДАННЫХ
Бинарное дерево поиска
Хотим новую структуру данных Set!Операции:
Contains(x), Add(x) быстрее O(N)
Node {Node left, right;int value;
}
Сложность операций?
Бинарное дерево. Балансировка
Бинарное дерево поиска
На той же идее можно сделать и MapОперации:
Add(key, value)
value = Find(key)
Node {Node left, right;int key;string value;
}
Бинарное дерево поиска. Задача
Сделать эффективную (быстрее O(N)) операциюnode = GetNodeAt(index)
Сложность операции?
Node {Node left, right;int key;string value;int size;
}
Бинарное дерево поиска. Задача
Какова может быть сложность операции обхода всех узлов, начиная с первого узла с ключом left и заканчивая последним узлом с ключом right?
foreach(Node node in GetAll(left, right))
Write(node.value);
Node {
Node left, right;
int key;
string value;
}
Бинарное дерево поиска
Добавление пары (key, value)Поиск по ключуПоиск i-ого элемента
Перебор K последовательных элементов
O(log N)
O(K)
Хэш-таблица
Хэш-таблица
Добавление парыПоиск по ключу
Поиск i-ого элементаПеребор последовательных элементов
O(1)
O(N)
Hash vs Tree
0 2000000 4000000 6000000 8000000 100000000
1000
2000
3000
4000
5000
6000
7000Tree Hash
0 5000000 1000000002468
1012
Tree/Hash
C# 5.0 (Dictionary & SortedDictionary), i7 2GHz
Hash vs Treeint → int int → string string → string
Hash 0.5 3 6Tree 5 9 44
int → int int → string string → stringHash 0.7 3 8Tree 7 12 75
int → int int → string string → stringHash 250 Mb 660 Mb 930 MbTree 290 Mb 560 Mb 850 Mb
Расход памяти на 10М пар
Поиск 10М пар (в секундах)
Добавление 10М пар (в секундах)
C# 5.0 (Dictionary & SortedDictionary), i7 2GHz
Задачка 1
Показать всех друзей Пети, которые были на этой странице новостей.
Задачка 2
Произвести нечеткое сравнение двух текстов. Результат сравнения — число от 0 до 1:0 — не похожи, 1 — полностью совпадают
Задачка 3
Найти все товары, в описании которых встречаются все перечисленные теги.
SQL Select
SELECT friend1 FROM Friends WHERE friend2 = ‘134123’
Индекс по friend2 — это что?Дерево или хэш?Что ключ, а что значение?
Обычные SQL-индексы — деревья
B-Tree, B*Tree, B+Tree, …Оптимизируют работу с дискомОчень похожи по характеристикам на бинарные деревья.Держать все данные в памяти будет быстрее (MemCache, Redis, …)
SQL и индексы
8.5.3. How MySQL Uses Indexeshttp://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
SQL и понимание индексов
SELECT * FROM t WHERE a = 1;SELECT a FROM t WHERE a = 1;SELECT f1, f2, f3 FROM t WHERE f1='abc' AND f2=2SELECT top 10 a FROM t WHERE a > 1 ORDER BY a;SELECT * FROM t WHERE name LIKE 'abc%';SELECT * FROM t WHERE name LIKE '%abc';SELECT * FROM t WHERE a > 100 AND b < 10;SELECT * FROM t WHERE a = 100 AND b < 10;SELECT * FROM t WHERE a > 100 AND b = 10;SELECT * FROM t WHERE f1='abc' AND f2 = 2;SELECT * FROM t WHERE f1='abc' AND f2=2
ORDER BY f3 DESC, f4 ASC
SELECT * FROM t WHERE f1='abc' OR f2=2;SELECT * FROM t WHERE DateAdd(f1, 7) = '2011-01-01';SELECT * FROM t WHERE f1 = DateAdd( '2011-01-01', -7)SELECT * FROM points
WHERE x BETWEEN 100 AND 200AND y BETWEEN 200 AND 400;
SELECT * FROM t1 JOIN t2 ON t1.cityname = t2.citynameSELECT * FROM parent
JOIN child ON child.parentId = parent.idWHERE parent.type = 'important';
JOIN + Индексыhttp://en.wikipedia.org/wiki/Join_(SQL)#Implementation
«Иные» запросы— иные индексы
— иные структуры данных
Полнотекстовый поиск
«котики порно скачать бесплатно»• [Исправление опечаток]• Лемматизация (кот порн скач бесплатн)• Синонимия (белочки sex download без смс)• Обратный индекс (слово → документы)• Ранжирование (сортировка результатов)
Ключевые слова: Lucene (Solr, Elasticsearch), Sphinx
Гео-поиск
«найди кафешку рядом со мной»SELECT * FROM Poi WHERE type="cafe"
AND Distance(location, me) < 1000R-Tree (rectangles tree), GeohashКлючевые слова:
MySQL spatial extensions,Spatial Index, Geometric types, PostGIS
Распределенные БД
Кластер, все данные в памяти →• Хэш-индексы — скорость• Деревянные индексы — порядок
Как обрабатывать запросы?
Домашнее задание 0Определить асимптотическую сложность алгоритма:
int F0(int n){
int x = 0;
for(int i=0; i<n; i++)
for(int j=1; j<n; j*=2)
x += i*j;
return x;
}
Домашнее задание 1Определить асимптотическую сложность алгоритма:
int F1(int n){int x = 0;for(int i=0; i<n; i++)
for(int j=i; j<n-i; j+=2)x += i*j;
return x;}
Домашнее задание 2
Определить асимптотическую сложность алгоритма:
int F2(int n){int x = 0;int j = 1;for(int i=1; i<n; i++) {
while (j<n && j%i !=0) j++;if (j<n) x += i*j;
}return x;
}
Домашнее задание 3*Дан алгоритм:
void Make(int n, bool flag){
if (n==0) return;for (int i=0; i<n; i++) Action(flag);Make((int)(A*n), flag);Make((int)(A*n), !flag);
}
Действие Action выполняется за константное время. Определить асимптотическую сложность алгоритма при A=1/2, A=1/3 и A=2/3
Домашнее задание 4
Могут происходить следующие события:• Добавление нового комментария• Удаление комментария• «Like» комментарию• Запросить K не удалённых комментариев,
которые менялись (добавлялись или лайкались) самыми последними.
Ещё о применении хэшей
Ключевые слова:полиномиальный хэш, rolling hash
Книги
Александр Шень (Free)
Online курсы
https://www.coursera.org/courses?orderby=upcoming&search=algorithms&cats=cs-theory
Сайты для тренировок
http://acm.timus.ru http://projecteuler.nethttp://www.sql-ex.ru/