├── .gitignore ├── 2015-2016_lections ├── lection_1 │ └── lection_1.tex ├── lection_10 │ └── lection_10.tex ├── lection_11 │ └── lection_11.tex ├── lection_12 │ └── lection_12.tex ├── lection_13 │ └── lection_13.tex ├── lection_14 │ └── lection_14.tex ├── lection_18 │ ├── createlistofedges.py │ ├── lection_18.out │ ├── lection_18.tex │ ├── list.py │ ├── listofedges.py │ ├── matrix.py │ ├── readlist.py │ └── readmatrix.py ├── lection_19 │ ├── lection_19.out │ ├── lection_19.tex │ └── voyajer.py ├── lection_2 │ └── lection_2.tex ├── lection_20 │ ├── big.png │ ├── binary tree search.py │ ├── binary tree.py │ ├── binarytree.py │ ├── lection_20.out │ ├── lection_20.tex │ ├── node.py │ └── small.png ├── lection_21 │ ├── 7-1.py │ ├── 7-2.py │ ├── lection_21.out │ └── lection_21.tex ├── lection_23 │ ├── au.py │ ├── lection_23.out │ └── lection_23.tex ├── lection_24 │ ├── lection_24.out │ └── lection_24.tex ├── lection_25 │ ├── lection_25.out │ └── lection_25.tex ├── lection_26 │ ├── lection_26.out │ └── lection_26.tex ├── lection_3 │ └── lection_3.tex ├── lection_4 │ └── lection_4.tex ├── lection_5 │ └── lection_5.tex ├── lection_6 │ └── lection_6.tex ├── lection_7 │ └── lection_7.tex ├── lection_8 │ └── lection_8.tex └── lection_9 │ └── lection_9.tex ├── DBMP_MIPT-2016-2017 ├── Figures │ └── Pic.md ├── Lecture_Notes │ └── README.md └── Tex_Source │ ├── Lecture_1 │ └── Tex_files.md ├── LICENSE ├── Makefile ├── README.md ├── lection_16 └── lection_16.tex ├── lection_17 ├── graph.jpg └── lection_17.tex ├── lection_18 ├── alg1.jpg ├── alg2.jpg ├── alg3.jpg ├── alg4.jpg ├── alg5.jpg ├── alg6.jpg ├── alg7.jpg ├── alg8.jpg ├── alg9.jpg ├── graph1.jpg ├── kos1.jpg ├── kos2.jpg ├── kos3.jpg ├── lection_18.tex ├── most.jpg └── sharnir.jpg ├── lection_19 ├── Animated_BFS.gif ├── frame-0.png ├── frame-1.png ├── frame-2.png ├── frame-3.png ├── frame-4.png ├── frame-5.png ├── frame-6.png ├── frame-7.png ├── frame-8.png ├── frame-9.png └── lection_19.tex ├── lection_20 └── lection_20.tex ├── lection_21 ├── germany.png └── lection_21.tex ├── lection_22 ├── graph_derevo.pdf ├── graph_derevo.pdf_tex ├── graph_derevo.png ├── graph_derevo.svg └── lection_22.tex ├── lection_23 ├── class Tree.py └── lection_23.tex ├── lection_24 └── lection_24.tex ├── lection_25 └── lection_25.tex ├── lection_26 └── lection_26.tex ├── lection_27 └── lection_27.tex └── rst_test ├── howto.txt ├── lab3.rst.example └── lab3.tex /.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.log 3 | *.gz 4 | *.out 5 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_10/lection_10.tex: -------------------------------------------------------------------------------- 1 | % !TeX spellcheck = russian_english 2 | % !TeX encoding = UTF-8 3 | \documentclass[a4paper, fleqn]{article} 4 | 5 | \usepackage{indentfirst} % Красная строка 6 | \usepackage[T2A]{fontenc} % Поддержка русских букв 7 | \usepackage[utf8]{inputenc} % Кодировка utf8 8 | \usepackage[russian]{babel} % руссификация 9 | \usepackage{amssymb} % дополнительные символы 10 | \usepackage{textcomp} % дополнительные текстовые символы 11 | \usepackage{amsmath} % матрицы 12 | \usepackage{listings} 13 | % листинги 14 | \lstset{language=Python, tabsize=4, language=Python} 15 | 16 | 17 | \textwidth = 16 cm 18 | \oddsidemargin= 0 cm 19 | \evensidemargin= 1 cm 20 | 21 | 22 | % \abovedisplayskip = 0 pt %.2\abovedisplayskip 23 | % \belowdisplayskip = .2\belowdisplayskip 24 | % \abovedisplayshortskip=.2\abovedisplayshortskip 25 | % \belowdisplayshortskip=.2\belowdisplayshortskip 26 | % \topsep= 0 pt 27 | 28 | % \setlength{\mathindent}{1.2 cm} 29 | % \setlength{\topsep}{0 pt} 30 | % \setlength{\abovedisplayskip}{0 pt} 31 | 32 | % \clubpenalty = 5000 % запрет висячих строк 33 | % \widowpenalty = 5000 34 | \binoppenalty=10000 35 | \relpenalty=10000 36 | 37 | % собственные команды и окружения 38 | 39 | \newenvironment{example}[1][]{\medskip \noindent \textbf{Пример. #1}\par \nopagebreak}{\medskip \par} % окружение-"пример" 40 | 41 | 42 | \title{Лекция \textnumero\,10} 43 | % {\huge \vspace{3 cm}}} 44 | 45 | \author{Т.\,Ф. Хирьянов} 46 | 47 | \date{} 48 | 49 | \begin{document} 50 | \maketitle 51 | 52 | \section*{Динамическое программирование} 53 | 54 | % мой листинг 55 | %\texttt{ 56 | % \begin{tabbing} 57 | % \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 58 | % р 59 | % \end{tabbing} 60 | % } 61 | 62 | %04:00 63 | 64 | У рекурсивной функции вычисления числа Фибоначчи очень большая асимптотическая сложность ($2^n$). При этом для человека это не слишком сложная задача при наличии листка бумаги и ручки. Это отличие обусловлено тем, что человек, начинает подсчет не с числа с номером $n$, а с первого числа и идет по порядку. Тем самым он идет от простой задачи к сложной, а не наоборот, как реализованно в рекурсивном алгоритме. В этом заключается подход динамического программирования. В качестве примера рассмотрим решение той же задачи с его помощью. 65 | 66 | Функция \texttt{fib}, получающая на вход номер числа Фибоначчи, который необходимо вывести, создает список необходимого размера, начинающийся с 0 и 1. Затем в цикле находятся последовательно все числа Фибоначчи, начиная со второго и заканчивая $n$. Для этого используется очевидная рекуррентная формула \texttt{F[i] = F[i - 1] + F[i - 2]}. 67 | 68 | \texttt{ 69 | \begin{tabbing} 70 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 71 | def fib(n):\\ 72 | \> F = [0, 1] + [0]*(n - 1)\\ 73 | \> for i in range(2, n + 1):\\ 74 | \> \> F[i] = F[i - 1] + F[i - 2]\\ 75 | \> return F[n] 76 | \end{tabbing} 77 | } 78 | 79 | Может показаться, что данное решение значительно проигрывает рекурсивному по объему используемой памяти, однако это не так, потому что при каждом вызове рекурсивной функции на стек кладется текущий номер числа и адрес возврата. Поэтому количество необходимой памяти в процессе работы программы становится пропорционально $2n$. В случае динамического программирования памяти требуется меньше. Можно даже улучшить программу, запоминая только последние два числа. Время выполнения программы также пропорционально $n$. 80 | 81 | 82 | 83 | 84 | 85 | \subsection*{Кузнечик} 86 | 87 | % 10:15 88 | Допустим, что кузнечик прыгает от нулевой клетки до клетки с номером $n$. При этом за один прыжок, он может преодолеть одну или две клетки. Необходимо посчитать количество возможных траекторий. Допустим, что в клетку с номером $i-2$ можно попасть $N_{i-2}$ способами, а в клетку с номером $i-1$ -- $N_{i-1}$ способами, тогда очевидно, что количество траекторий до i-й клетки равно $N_{i-1} + N_{i-2}$. Используя этот факт и решение задачи о нахождении n-ого числа Фибоначчи, получим требуемый алгоритм, в котором вычисляются количества траекторий до каждой i-й клетки и хранятся последовательно в списке K. 89 | % 14:40 90 | \texttt{ 91 | \begin{tabbing} 92 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 93 | K = [0, 1] + [0]*(n - 1)\\ 94 | for i in range(2, n + 1):\\ 95 | \> \> K[i] = K[i - 1] + K[i - 2]\\ 96 | print(K[n]) 97 | \end{tabbing} 98 | } 99 | По своей сути это очень похожие задачи. 100 | % 16:30 101 | \subsection*{Количество траекторий с запрещенными клетками} 102 | 103 | Можно усложнить предыдущую задачу, запретив кузнечику прыгать на некоторые клетки. Для этого нужно создать специальный список запрещенных клеток, например, присвоив i-й клетке значение 0, если в нее можно прыгнуть и 1, если это запрещено. Далее, как и в предыдущей программе, создается массив К, в котором для каждой клетки хранится количество траекторий до нее. Отличие состоит лишь в том, что если i-я клетка запрещенная, то количество траекторий до нее равно нулю. 104 | \texttt{ 105 | \begin{tabbing} 106 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 107 | Denied = [0, 0, 1, 0, 0, 1, 0, 0, ... 1, 0, 0]\\ 108 | n = int(input())\\ 109 | K =[0, 1] + [None]*(n - 1)\\ 110 | for i in range(2, n + 1):\\ 111 | \> if Denied[i]:\\ 112 | \> \> K[i] = 0\\ 113 | \> else:\\ 114 | \> \> K[i] = K[i - 1] + K[i - 2] 115 | \end{tabbing} 116 | } 117 | 118 | % 22:50 119 | \subsection*{Задача о минимальной стоимости} 120 | 121 | % 29:30 122 | Допустим условно, что за нахождение в каждой клетке взимается определенная сумма денег. Необходимо определить минимальную сумму, которую требуется заплатить, чтобы добраться до нужной клетки. Для этого по аналогии с предыдущим примером задается список цен нахождения в каждой клетке Price, и список С, в который для каждой клетки будет задаваться минимальная стоимость ее достижения. Очевидно, что стоимость достижения i-й клетки будет равна сумме стоимости нахождения в ней и минимальной из стоимостей достижения соседних клеток. 123 | 124 | В данной задаче возникает вопрос, какая именно траектория обладает наименьшей стоимостью. Для этого можно заполнять массив Path номерами клеток, через которые проходила искомая траектория. При этом нужно двигаться с конца, каждый раз выбирая ту клетку из двух, стоимость прибывания в которой меньше. Полученный массив Path в конце работы программы следует перевернуть. 125 | \texttt{ 126 | \begin{tabbing} 127 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 128 | Price = [10, 20, 5, 3, ...]\\ 129 | n = int(input())\\ 130 | C = [0]*(n + 1)\\ 131 | C[0] = Price[0]\\ 132 | C[1] = C[0] + Price[1]\\ 133 | for i in range(2, n + 1):\\ 134 | \> C[i] = Price[i] + min(C[i - 1], C[i - 2])\\ 135 | print(C[n])\\ 136 | \\ 137 | Path = [n]\\ 138 | while Path[-1] != 0:\\ 139 | \> i = Path[-1]\\ 140 | \> if C[i - 1] < C[i - 2]:\\ 141 | \> \> Path.append(i - 1)\\ 142 | \> else:\\ 143 | \> \> Path.append(i - 2)\\ 144 | Path = Path[::-1] 145 | \end{tabbing} 146 | } 147 | 148 | % перерыв 149 | 150 | % король 151 | % 00:00 152 | 153 | % 03:30 154 | 155 | \subsection*{Исполнитель король} 156 | 157 | Похожим исполнителем является \emph{король}, который может шагать по шахматной доске вниз, вправо и по диагонали (однако при этом он не может ходить назад). Фигура начинает шагать из верхнего левого угла. Можно поставить аналогичную задачу нахождения кратчайшей траектории до конкретной клетки. Для этого необходимо сначала обработать клетки на верхней и левой границах. Создадим двумерный список К, размера $n\times m$ заполненный нулями. Затем с помощью двух циклов укажем количество траекторий до крайних клеток. Очевидно, что в условиях данной задачи оно будет равно 1. Для остальных клеток очевидно существует больше траекторий. Действительно до каждой из них можно добраться из трех соседних клеток: сверху, слева или по диагонали. Поэтому количество траекторий до клетки в i-ой строке и в j-ом столбце равно сумме количеств траекторий до каждой из тех трех соседних клеток. Пробежавшись по всем оставшимся клеткам в двойном цикле, заполним список K необходимыми значениями. В конце можно вывести количество траекторий до любой клетки, например, для клетки в нижнем правом углу. 158 | \texttt{ 159 | \begin{tabbing} 160 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 161 | m = int(input())\\ 162 | r = int(input())\\ 163 | K = [[0]*m for i in range(n)]\\ 164 | for i in range(n):\\ 165 | \> K[i][0] = 1\\ 166 | for j in range(m):\\ 167 | \> K[0][j] = 1\\ 168 | for i in range(1, n):\\ 169 | \> for j in range(1, m):\\ 170 | \> \> K[i][j] = K[i - 1][j - 1] + K[i - 1][j] + K[i][j - 1]\\ 171 | print(K[n - 1][m - 1]) 172 | \end{tabbing} 173 | } 174 | 175 | % 13:30 176 | 177 | % 15:00 178 | \subsection*{Наибольшая общая подпоследовательность} 179 | 180 | % 16:15 рисунок 2 последовательности 181 | Допустим имеются два числовых списка A и B одинаковой длины. Требуется найти и вывести $F_{ij}$ -- длину наибольшей общей подпоследовательности срезов А[:i+1] и B[:j+1]. Когда эта величина уже посчитана для индексов i-1 и j-1, остается сравнить $A_i$ и $B_j$. Если они равны, то очевидно общая подпоследовательность станет больше на единицу. Иначе будет выбрана наибольшая из $F[i - 1][j]$ и $F[i][j - 1]$. 182 | % 24:00 183 | \texttt{ 184 | \begin{tabbing} 185 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 186 | n = len(A)\\ 187 | m = len(B)\\ 188 | F = [[0]*(m + 1) for i in range(n + 1)]\\ 189 | for i in range(1, n + 1):\\ 190 | \> for j in range(1, m + 1):\\ 191 | \> \> if A[i - 1] == B[j - 1]: \> \> \# i символ А и j символ B\\ 192 | \> \> \> F[i][j] = F[i - 1][j - 1] + 1\\ 193 | \> \> else:\\ 194 | \> \> \> F[i][j] = max(F[i - 1][j], F[i][j - 1])\\ 195 | print(F[n][m]) 196 | \end{tabbing} 197 | } 198 | 199 | % СНОСКА: Ссылка на дополнительный материал 200 | 201 | \subsection*{Наибольшая возрастающая подпоследовательность} 202 | 203 | % 32:00 204 | Допустим, что существует список А, и необходимо узнать $F_i$ -- длину наибольшей возрастающей подпоследовательности до i-ого элемента включительно. Поэтому $F[0] = 0$. Будем последовательно заполнять список F. При этом если для элемента i списка А найдется меньший его элемент j среди элементов с номерами, меньшими i, и при этом $F[j] > F[i]$, то нужно обновить значение $F[i]$. После этого нужно будет включить элемент $А[i]$ в эту подпоследовательность, а значит, увеличить $F[i]$ на единицу. 205 | % 35:00 206 | \texttt{ 207 | \begin{tabbing} 208 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 209 | F = [0]*len(A)\\ 210 | for i in range(len(A)):\\ 211 | \> for j in range(i):\\ 212 | \> \> if A[j] < A[i] $\backslash$\\ 213 | \> \> \> and F[j] > F[i]:\\ 214 | \> \> \> F[i] = F[j]\\ 215 | \> F[i] += 1\\ 216 | print(max(F)) 217 | \end{tabbing} 218 | } 219 | 220 | \end{document} 221 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_11/lection_11.tex: -------------------------------------------------------------------------------- 1 | % !TeX spellcheck = russian_english 2 | % !TeX encoding = UTF-8 3 | \documentclass[a4paper, fleqn]{article} 4 | 5 | \usepackage{indentfirst} % Красная строка 6 | \usepackage[T2A]{fontenc} % Поддержка русских букв 7 | \usepackage[utf8]{inputenc} % Кодировка utf8 8 | \usepackage[russian]{babel} % руссификация 9 | \usepackage{amssymb} % дополнительные символы 10 | \usepackage{textcomp} % дополнительные текстовые символы 11 | \usepackage{amsmath} % матрицы 12 | \usepackage{listings} 13 | % листинги 14 | \lstset{language=Python, tabsize=4, language=Python} 15 | 16 | 17 | \textwidth = 16 cm 18 | \oddsidemargin= 0 cm 19 | \evensidemargin= 1 cm 20 | 21 | 22 | % \abovedisplayskip = 0 pt %.2\abovedisplayskip 23 | % \belowdisplayskip = .2\belowdisplayskip 24 | % \abovedisplayshortskip=.2\abovedisplayshortskip 25 | % \belowdisplayshortskip=.2\belowdisplayshortskip 26 | % \topsep= 0 pt 27 | 28 | % \setlength{\mathindent}{1.2 cm} 29 | % \setlength{\topsep}{0 pt} 30 | % \setlength{\abovedisplayskip}{0 pt} 31 | 32 | % \clubpenalty = 5000 % запрет висячих строк 33 | % \widowpenalty = 5000 34 | \binoppenalty=10000 35 | \relpenalty=10000 36 | 37 | % собственные команды и окружения 38 | 39 | \newenvironment{example}[1][]{\medskip \noindent \textbf{Пример. #1}\par \nopagebreak}{\medskip \par} % окружение-"пример" 40 | 41 | 42 | \title{Лекция \textnumero\,11} 43 | % {\huge \vspace{3 cm}}} 44 | 45 | \author{Т.\,Ф. Хирьянов} 46 | 47 | \date{} 48 | 49 | \begin{document} 50 | \maketitle 51 | 52 | \subsection*{Быстрая сортировка Хоара} 53 | 54 | % 3:30 55 | Допустим, что необходимо упорядочить солдат в строю по их росту. Решение данной задачи с помощью быстрой сортировки Хоара начинается с того, что выбирается произвольный солдат и весь строй разделяется на три группы по отношению к нему: тех, кто ниже ростом, тех, кто одинакового с ним роста и тех, кто выше. Получается, что люди во второй группе, уже отсортированы внутри нее. К тому же первая вторая и третья группы упорядоченны между собой. Однако внутри первой и третьей группы люди могут быть неупорядоченны. Осталось рекурсивно применить к этим группам тот же самый алгоритм. 56 | 57 | Из сказанного следует, что данная рекурсивная сортировка относится к алгоритмам типа <<разделяй и влавствуй>>, а также то, что массив данных сортируется на прямом ходу рекурсии. Подробный анализ показывает, что приведенный метод в худшем случае имеет асимптотику $O(N^2)$, однако вероятностно, в некотором <<среднем случае>> $O(N\cdot\log_2{N})$. 58 | 59 | Рассмотрим для наглядности реализацию, в которой для этих трех групп создаются новые списки (хотя можно обойтись и без этого). 60 | Сначала обрабатывается крайний случай рекурсии, который заключается в том, что список из не более одного элемента уже отсортирован. 61 | Затем с помощью библиотечной функции \texttt{choice} выбираем произвольный элемент, который будет выполнять роль барьера. Сравнивая с ним остальные элементы списка A, создаем с помощью генераторов три новых списка \texttt{left, middle, right}. К первому и третьему рекурсивно применяем тот же алгоритм. В конце работы программы возвращаем конкатинированный список. 62 | 63 | 64 | \texttt{ 65 | \begin{tabbing} 66 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 67 | from random import choice\\ 68 | def hoar\_sort(A):\\ 69 | \> if len(A) <= 1:\\ 70 | \> \> return A\\ 71 | \> barrier = choice(A)\\ 72 | \> left = [x for x in A if x < barrier]\\ 73 | \> middle = [x for x in A x == barrier]\\ 74 | \> right = [x for x in A x > barrier]\\ 75 | \> left = hoar\_sort(left)\\ 76 | \> right = hoar\_sort(right)\\ 77 | \> return left + middle + right 78 | \end{tabbing} 79 | } 80 | 81 | Стоит отметить, что важным преимуществом быстрой сортировки является ее универсальность, т.е. возможность ее применения к любым элементам, которые можно сравнивать между собой, даже если к ним не применимы арифметические операции, например, к строкам. 82 | 83 | \subsection*{Быстрая сортировка слиянием} 84 | 85 | % 27:30 86 | Представим, что студент распечатал внушительный отчет о проделанной лабораторной работе, однако из-за того, что форточка в комнате была открыта, ветер раскидал листки по комнате и перепутал их. Предположим, что двое соседей студента решили ему помочь и каждый, собрав произвольную стопку листов, упорядочил страницы в ней. Эти две отсортированные стопки они отдали студенту. Теперь задача студента сводится к тому, чтобы произвести <<слияние>> этих двух стопок. Он ставит их так, чтобы страницы с наименьшими номерами были в верху стоп. Таким образом студент все время видит две страницы, выбирает из них ту, у которой номер меньше и откладывает в третью стопу. 87 | 88 | Тем самым обработан крайний случай, когда уже имеется две отсортированных части списка. Последние можно получить рекурсивно. Для этого нужно, чтобы для каждой из них также существовали их отсортированные части. 89 | Легко заметить, что сортировка происходит на обратном ходу рекурсии. Асимптотика такого алгоритма равна $O(N\cdot\log_2{N})$, однако он потребляет $O(N)$ дополнительной памяти. 90 | 91 | Для реализации данного алгоритма потребуется сперва создать функцию слияния \texttt{merge}, которая по двум отсортированным спискам A и B возвращает их общий упорядоченный список Res. По аналогии с описанным выше методом поэлементно пробегаются оба списка, пока каждый из них не закончится. 92 | \texttt{ 93 | \begin{tabbing} 94 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 95 | def merge(A, B):\\ 96 | \> Res = []\\ 97 | \> i = 0\\ 98 | \> j = 0\\ 99 | \> while i < len(A) and j < len(B):\\ 100 | \> \>if A[i] < B[j]:\\ 101 | \> \> \> Res.append(A[i])\\ 102 | \> \> \> i += 1\\ 103 | \> \> else:\\ 104 | \> \> \> Res.append(B[j])\\ 105 | \> \> \> j += 1\\ 106 | \> Res += A[i:] + B[j:] \> \> \> \# один из срезов обязательно пуст\\ 107 | \> return Res 108 | \end{tabbing} 109 | } 110 | 111 | Теперь реализуем функцию \texttt{merge\_sort(A)}. Крайним будет случай, когда список A состоит из не более одного элемента. Тогда можно считать, что список уже отсортирован, однако если в нем больше элементов, то левую <<половину>> сохраняем в список \texttt{left}, а правую в список \texttt{right}. Далее для них выполняем те же самые действия рекурсивно. Стоит обратить внимание, что сортировка осуществляется на обратном ходу рекурсии, когда списки \texttt{left} и \texttt{right} подвергаются слиянию. 112 | \texttt{ 113 | \begin{tabbing} 114 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 115 | def merge\_sort(A):\\ 116 | \> if len(A) <= 1:\\ 117 | \> \> return A\\ 118 | \> left = A[:len(A) // 2]\\ 119 | \> right = A[len(A) // 2:]\\ 120 | \> left = merge\_sort(left)\\ 121 | \> right = merge\_sort(right)\\ 122 | \> return merge(left, right) 123 | \end{tabbing} 124 | } 125 | 126 | \subsection*{Пирамидальная сортировка} 127 | 128 | % 52:30 129 | Данная сортировка использует специальную структуру данных <<пирамида>> (или <<куча>>), в которой самое большое число оказывается всегда на ее вершине. При добавлении нового числа в кучу, оно оказывается в самом низу пирамиды и затем поднимается по ступеням вверх, меняясь местами с меньшими числами, расположенными выше, пока не достигнут необходимой. Затем когда пирамида заполнена (с помощью библиотечной функции \texttt{heapify}), числа начинают извлекать из нее (\texttt{heappop}) и добавлять в список \texttt{Res}, пока куча не опустеет. При этом пирамида будет перестраиваться, и наибольшее из оставшихся чисел снова будет оказываться на вершине. 130 | \texttt{ 131 | \begin{tabbing} 132 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 133 | from heapq import* 134 | def heap\_sort(A):\\ 135 | \> heapify(A)\\ 136 | \> Res = []\\ 137 | \> while len(A) != 0:\\ 138 | \> \> x = heappop(A)\\ 139 | \> \> Res.append(x)\\ 140 | \> return Res 141 | \end{tabbing} 142 | } 143 | 144 | Пирамида устроена таким образом, что количество ступеней равно $log_2{N}$, а добавление и извлечение числа также пропорционально этой величине. В целом асимптотика алгоритма становится равной $O(N\cdot\log_2{N})$. 145 | 146 | Однако последней сортировки есть серьезный недостаток -- она неустойчива. 147 | 148 | \subsection*{Устойчивость сортировки} 149 | 150 | % 1:08:00 151 | Сортировка называется устойчивой, если равные друг другу элементы остаются в исходном порядке. 152 | 153 | 154 | \end{document} 155 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_12/lection_12.tex: -------------------------------------------------------------------------------- 1 | % !TeX spellcheck = russian_english 2 | % !TeX encoding = UTF-8 3 | \documentclass[a4paper, fleqn]{article} 4 | 5 | \usepackage{indentfirst} % Красная строка 6 | \usepackage[T2A]{fontenc} % Поддержка русских букв 7 | \usepackage[utf8]{inputenc} % Кодировка utf8 8 | \usepackage[russian]{babel} % руссификация 9 | \usepackage{amssymb} % дополнительные символы 10 | \usepackage{textcomp} % дополнительные текстовые символы 11 | \usepackage{amsmath} % матрицы 12 | \usepackage{listings} 13 | % листинги 14 | \lstset{language=Python, tabsize=4, language=Python} 15 | 16 | 17 | \textwidth = 16 cm 18 | \oddsidemargin= 0 cm 19 | \evensidemargin= 1 cm 20 | 21 | 22 | % \abovedisplayskip = 0 pt %.2\abovedisplayskip 23 | % \belowdisplayskip = .2\belowdisplayskip 24 | % \abovedisplayshortskip=.2\abovedisplayshortskip 25 | % \belowdisplayshortskip=.2\belowdisplayshortskip 26 | % \topsep= 0 pt 27 | 28 | % \setlength{\mathindent}{1.2 cm} 29 | % \setlength{\topsep}{0 pt} 30 | % \setlength{\abovedisplayskip}{0 pt} 31 | 32 | % \clubpenalty = 5000 % запрет висячих строк 33 | % \widowpenalty = 5000 34 | \binoppenalty=10000 35 | \relpenalty=10000 36 | 37 | % собственные команды и окружения 38 | 39 | \newenvironment{example}[1][]{\medskip \noindent \textbf{Пример. #1}\par \nopagebreak}{\medskip \par} % окружение-"пример" 40 | 41 | 42 | \title{Лекция \textnumero\,12} 43 | % {\huge \vspace{3 cm}}} 44 | 45 | \author{Т.\,Ф. Хирьянов} 46 | 47 | \date{} 48 | 49 | \begin{document} 50 | \maketitle 51 | 52 | \subsection*{Объектно-ориентированное программирование} 53 | 54 | Объектно-ориентированное программирование держится на трех китах. Это 55 | \begin{enumerate} 56 | \item Инкапсуляция 57 | \item Полиморфизм 58 | \item Наследование 59 | \end{enumerate} 60 | 61 | Модульная парадигма является частью инкапсуляции и заключается в объединении в группы функций с некоторым общим назначением (например, в один модуль удобно собрать функции, задействованные в вводе и интерпретации данных). Такая парадигма широко распространена в не объектно-ориентированных языках программирования. 62 | 63 | Следующим шагом к инкапсуляции является введение \emph{классов} Это структуры (типы) данных, которые обладают определенными \emph{атрибутами}, а также \emph{методами} -- функциями с помощью которых осуществляется доступ к атрибутам. 64 | 65 | Возможно существование нескольких экземпляров класса -- объектов. Так могут существовать два объекта: заяц Вася и заяц Дима. Оба они будут являться экземплярами класса заяц (Rabbit). Заяц имеет два свойства (атрибута): размер (size) и сытость (sytost). К ним можно обратиться с помощью методов класса: set\_size, устанавливающего определенный размер size, get\_size, возвращающего значение size, и feed, увеличивающего сытость. Все эти функции имеют обязательный аргумент self, стоящий на первом месте. Он является ссылкой на экземпляр класса, и должен быть обязательно указан в описании метода (только так метод <<поймет>>, для которого экземпляра класса он вызван). 66 | \texttt{ 67 | \begin{tabbing} 68 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 69 | class Rabbit:\\ 70 | \> size = None\\ 71 | \> sytost = 0\\ 72 | \> def set\_size(self, size):\\ 73 | \> \> self.size = size\\ 74 | \> def get\_size(self):\\ 75 | \> \> return self.size\\ 76 | \> def feed(self, meal):\\ 77 | \> \> self.sytost += calorii(meal) 78 | \end{tabbing} 79 | } 80 | 81 | Стоит отметить, что обращаться к атрибутам и манипулировать ими удобнее не на прямую, а с помощью методов класса. Тогда можно производить действия с атрибутами, используя понятный интерфейс, не задумываясь, как именно они осуществляются. Из приведенного ниже примера ясно, что кролика a покормили морковкой. При этом мы не знаем, что это подразумевает под собой. 82 | \texttt{ 83 | \begin{tabbing} 84 | \hspace{8mm}\=\=\hspace{3cm}\=\kill 85 | a = Rabbit()\\ 86 | b = Rabbit()\\ 87 | a.feed(carrot) \> \> \> \# Rabbit.feed(a, carrot) 88 | \end{tabbing} 89 | } 90 | 91 | \subsection*{Полиморфизм в Python} 92 | 93 | В питоне невозможно перегружать функции. В рассмотренном ниже примере происходит не перегрузка, а переопределение функции f -- старое определение пропадает. 94 | \texttt{ 95 | \begin{tabbing} 96 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 97 | def f(x):\\ 98 | \> return x*x\\ 99 | def f(x, y):\\ 100 | \> return x*y 101 | \end{tabbing} 102 | } 103 | Для того чтобы обойти это препятствие можно воспользоваться значениями по умолчанию. Допустим, что функция f должна возвращать произведение двух поданных на вход чисел и квадрат числа, если подано лишь одно число. Для обработки последней ситуации удобно определить по умолчанию один из аргументов значением None. 104 | \texttt{ 105 | \begin{tabbing} 106 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 107 | def f(x, y=None):\\ 108 | \> if y == None:\\ 109 | \> \> y = x\\ 110 | \> return x*y 111 | \end{tabbing} 112 | } 113 | Можно однако использовать аргументы разного типа. И внутри функции определить, как вести себя с теми или иными объектами. Этим и достигается полиморфизм в Python. 114 | 115 | \subsection*{setter и getter} 116 | 117 | Создадим класс студента. У него необходимо создать атрибуты возраст и имя, причем они должны определяться автоматически при создании объекта класса student. Это делается с помощью специального метода-конструктора \_\_init\_\_. Для того чтобы сделать доступ к атрибуту извне нежелательным, его имя должно начинаться с символа <<\_>> (тогда данного атрибута не будет видно в списке атрибутов класса). Доступ к атрибуту обычно осуществляется с помощью функции <>, которая имеет такое же название, что и атрибута и перед ее определением написано \texttt{@property}. Для того чтобы установить желаемое значение аргумента, правильнее использовать setter. Его определение аналогично. 118 | \texttt{ 119 | \begin{tabbing} 120 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4.5cm}\=\kill 121 | class Student:\\ 122 | \> def \_\_init\_\_(self, age, name):\> \> \> \# Конструктор\\ 123 | \> \> self.\_age = age\\ 124 | \> \> self.\_name = name\\ 125 | \> def aging(self):\\ 126 | \> \> self.\_age += 1\\ 127 | \> \> print('Ура! Мне', self.\_age, 'лет!')\\ 128 | \> @property\\ 129 | \> def age(self): \> \> \> \# <> (свойство)\\ 130 | \> return self.\_age\\ 131 | \> @age.setter\\ 132 | \> def age(self, age):\\ 133 | \> \> self.age = age 134 | \end{tabbing} 135 | } 136 | Тогда можно возвратить значение атрибута показанным ниже способом (здесь осуществляется не прямой доступ к атрибуту, а с помощью функции getter) 137 | \texttt{ 138 | \begin{tabbing} 139 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 140 | a = Student(17, 'Вася')\\ 141 | a.age = 18 \> \> \> \# Нельзя!\\ 142 | x = a.age 143 | \end{tabbing} 144 | } 145 | 146 | \subsection*{Определение функций} 147 | Важно отметить, что к объектам класса можно приписывать новые атрибуты уже после определения класса. 148 | Так как любая функция является объектом класса функций, то и для нее можно создать атрибуты. Например, атрибут p функции productor можно задать уже после объявления функции. Причем она будет работать только после этого. 149 | \texttt{ 150 | \begin{tabbing} 151 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{2cm}\=\kill 152 | def productor(x):\\ 153 | \> return x*productor.p\\ 154 | productor.p = 5\\ 155 | print(productor(2)) \> \> \> \> \# 10 156 | \end{tabbing} 157 | } 158 | Рассмотрим класс двумерного вектора Vector2D. Допустим мы хотим сложить два вектора не с помощью некоторой функции, а привычным способом (c = a + b). Для этого нужно определить специальную функцию \_\_add\_\_. Таким же образом можно организовать умножение (\_\_mul\_\_). Необходимо однако различать скалярное произведение и умножение вектора на число. Это делается с помощью проверки принадлежности (isInstance) объекта тому или иному типу (или его прямому потомку). 159 | \texttt{ 160 | \begin{tabbing} 161 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 162 | class Vector2D:\\ 163 | \> def \_\_init\_\_(self, x=0, y=0):\\ 164 | \> \> self.\_x = x\\ 165 | \> \> self.\_y = y\\ 166 | \> def \_\_add\_\_(self, other):\\ 167 | \> \> x = self.\_x + other.\_x\\ 168 | \> \> y = self.\_y + other.\_y\\ 169 | \> \> return Vector2D(x, y)\\ 170 | \> def \_\_mul\_\_(self, other):\\ 171 | \> \> if isInstance(other, Vector2D):\\ 172 | \> \> \> return self.\_x *other.\_x + self.\_y *other.\_y\\ 173 | \> \> else:\\ 174 | \> \> \> return Vector2D(self.\_x * other, self.\_y * other) 175 | \end{tabbing} 176 | } 177 | \subsection*{range} 178 | Допустим, что нужно создать итератор, который бы не сразу создавал весь список, а возвращал бы один элемент и останавливался на паузу. Например, нужно генерировать геометрическую прогрессию. Это можно осуществить следующим образом. Приведенная ниже функция является функцией-генератором. Вместо return используется yield. 179 | \texttt{ 180 | \begin{tabbing} 181 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 182 | def geom\_range(start, stop, d):\\ 183 | \> x = start\\ 184 | \> while x < stop:\\ 185 | \> \> yield x\\ 186 | \> \> x *= d 187 | \end{tabbing} 188 | } 189 | Затем данную функцию можно использовать как итератор. 190 | \texttt{ 191 | \begin{tabbing} 192 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 193 | for x in geom\_range(1, 1025, 2):\\ 194 | \> print(x) 195 | \end{tabbing} 196 | } 197 | Многие функции умеют работать с данными итераторами. 198 | \texttt{ 199 | \begin{tabbing} 200 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 201 | g\_num = dict(zip(range(0, 11), geom\_range(1, 1025, 2))\\ 202 | x, y, z = list(map(int, input().split())\\ 203 | x, y, z = [int(x) for x in input().split()] 204 | \end{tabbing} 205 | } 206 | \subsection*{Списки level up} 207 | Очевидно, что в списках могут храниться другие списки. Однако в действительности там хранятся ссылки на объекты. В приведенном ниже примере последний элемент списка и вовсе хранит ссылку на сам список. 208 | \texttt{ 209 | \begin{tabbing} 210 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 211 | a = [1]\\ 212 | a.append(a) \> \> \> \# [1, *]\\ 213 | x = a\\ 214 | for i in range(10):\\ 215 | \> print(x[0])\\ 216 | \> x = x[1]\\ 217 | \end{tabbing} 218 | } 219 | Данный алгоритм может быть основой для структуры данных, представляющей собой систему вложенных списков, таких что последний элемент n - 1 списка содержит ссылку на n список. Это \emph{односвязный} список. Его преимущество состоит в том, что сложность включения нового элемента, например, в середину списка составляет O(1), в отличие от О(N) для массива. 220 | 221 | \end{document} 222 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_13/lection_13.tex: -------------------------------------------------------------------------------- 1 | % !TeX spellcheck = russian_english 2 | % !TeX encoding = UTF-8 3 | \documentclass[a4paper, fleqn]{article} 4 | 5 | \usepackage{indentfirst} % Красная строка 6 | \usepackage[T2A]{fontenc} % Поддержка русских букв 7 | \usepackage[utf8]{inputenc} % Кодировка utf8 8 | \usepackage[russian]{babel} % руссификация 9 | \usepackage{amssymb} % дополнительные символы 10 | \usepackage{textcomp} % дополнительные текстовые символы 11 | \usepackage{amsmath} % матрицы 12 | \usepackage{listings} 13 | % листинги 14 | \lstset{language=Python, tabsize=4, language=Python} 15 | 16 | 17 | \textwidth = 16 cm 18 | \oddsidemargin= 0 cm 19 | \evensidemargin= 1 cm 20 | 21 | 22 | % \abovedisplayskip = 0 pt %.2\abovedisplayskip 23 | % \belowdisplayskip = .2\belowdisplayskip 24 | % \abovedisplayshortskip=.2\abovedisplayshortskip 25 | % \belowdisplayshortskip=.2\belowdisplayshortskip 26 | % \topsep= 0 pt 27 | 28 | % \setlength{\mathindent}{1.2 cm} 29 | % \setlength{\topsep}{0 pt} 30 | % \setlength{\abovedisplayskip}{0 pt} 31 | 32 | % \clubpenalty = 5000 % запрет висячих строк 33 | % \widowpenalty = 5000 34 | \binoppenalty=10000 35 | \relpenalty=10000 36 | 37 | % собственные команды и окружения 38 | 39 | \newenvironment{example}[1][]{\medskip \noindent \textbf{Пример. #1}\par \nopagebreak}{\medskip \par} % окружение-"пример" 40 | 41 | 42 | \title{Лекция \textnumero\,13} 43 | % {\huge \vspace{3 cm}}} 44 | 45 | \author{Т.\,Ф. Хирьянов} 46 | 47 | \date{} 48 | 49 | \begin{document} 50 | \maketitle 51 | 52 | \subsection*{Очередь (queue)} 53 | 54 | Очередь -- это структура данных, в которую можно добавлять элемент в ее конец и извлекать элемент из ее начала. Одним из простых видов очереди является FIFO (First Input -- First Out). В такой очереди первый вошедший элемент является первым претендентом на выход. 55 | 56 | Очередь требуется, когда наблюдается недостаток ресурсов. Например, если некоторая программа не может обрабатывать больше двадцати запросов в секунду, то на двадцать первый запрос очередь переполнится, т.е. запросы перестанут попадать в нее. 57 | 58 | В стандартной библиотеке Python есть модуль queue, который позволяет создавать очередь и работать с нею. 59 | 60 | %19:00 61 | Создается очередь, как и любой объект класса, с помощью вызова конструктора Queue. Ему можно передать количество элементов, которые можно хранить в памяти одновременно. Можно узнать пуста ли очередь с помощью метода empty и проверить на полноту, используя метод full (они возвращают правду или ложь). Чтобы положить элемент в очередь нужно воспользоваться методом put, а для того чтобы извлечь -- get. 62 | 63 | \texttt{ 64 | \begin{tabbing} 65 | \hspace{8mm}\=\hspace{2cm}\=\kill 66 | import queue\\ 67 | q = Queue(10) \> \> \# очередь из 10 элементов\\ 68 | q.empty()\\ 69 | q.full\\ 70 | q.put(item)\\ 71 | q.get() 72 | \end{tabbing} 73 | } 74 | 75 | Попробуем реализовать класс Queue, используя двусвязный список, с максимальным количеством звеньев, равным количеству элементов в очереди. Реализуем конструктор. По умолчанию очередь создается пустой, и начало (\_begin) и конец (\_end) указывают на None; максимальное количество элементов (N\_max) можно задать в конструкторе, однако по умолчанию оно равно нулю; еще один атрибут (N) -- это текущее количество элементов в очереди. 76 | 77 | Методы empty и full реализуются очевидным образом. 78 | Во время выполнения операции добавления нового элемента в случае, когда очередь уже полна, будет вызвана ошибка. Более того, если очередь пуста, то операция будет работать иначе, чем когда в очереди уже есть элементы. Так как список двусвязный, то необходимо связать не только новый первый элемент со старым, но и наоборот. 79 | 80 | Если очередь пуста, то метод извлечения элемента get вызовет ошибку. Если она не пуста, то последний элемент можно извлечь. При этом необходимо сначало сохранить ссылку на этот элемент, прежде чем у предпоследнего элемента в качестве ссылки на последний указать None. Важно обратить внимание, что сборщик мусора удалит элемент, только когда на него не останется ни одной ссылки. В случае когда в очереди был всего один элемент, необходимо также удалить ссылку на него как на начало очереди. 81 | 82 | 83 | \texttt{ 84 | \begin{tabbing} 85 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 86 | class Queue:\\ 87 | \> def \_\_init\_\_(self, N=0):\\ 88 | \> \> self.\_begin = None\\ 89 | \> \> self.\_end = None\\ 90 | \> \> self.\_N\_max = N\\ 91 | \> \> self.\_N = N\\ 92 | \\ 93 | \> def empty(self):\\ 94 | \> \> return self.\_N == 0\\ 95 | \\ 96 | \> def full (self):\\ 97 | \> \> return self.\_N == self.\_N\_max if self.\_N\_max != 0 else False\\ 98 | \\ 99 | \> def put(self, item):\\ 100 | \> \> if self.full():\\ 101 | \> \> \> raise Error() \> \# вызов ошибки при переполнении\\ 102 | \> \> if self.empty():\\ 103 | \> \> \> self.\_begin = self.\_end = [None, item, None]\\ 104 | \> \> \> \# ставим None, так как предыдущего и следующего звена нет\\ 105 | \> \> else:\\ 106 | \> \> \> new\_node = (None, item, self.\_begin)\\ 107 | \> \> \> self.\_begin = new\_node\\ 108 | \> \> \> \# теперь новый первый элемент связан со старым первым элементом\\ 109 | \> \> \> self.\_begin[2][0] = self.\_begin\\ 110 | \> \> \> \# теперь старый первый элемент связан с новым первым элементом\\ 111 | \> \> self.\_N += 1 \> \> \# количество элементов увеличилось на единицу\\ 112 | \\ 113 | \> def get(self):\\ 114 | \> \> if self.empty():\\ 115 | \> \> \> raise Error()\\ 116 | \> \> item = self.\_end[1]\\ 117 | \> \> \> \# теперь последний элемент сохранен\\ 118 | \> \> self.\_end = self.\_end[0]\\ 119 | \> \> \> \# теперь последним является ранее предпоследний элемент\\ 120 | \> \> if self.\_end == None: \> \> \# т.е. был всего один элемент\\ 121 | \> \> \> self.\_begin = None\\ 122 | \> \> else:\\ 123 | \> \> \> self.\_end[2] = None \> \# так как он теперь последний\\ 124 | \> \> \> \# теперь ссылка на последний элемент будет утеряна во всех случаях\\ 125 | \> \> self.\_N -= 1 126 | \end{tabbing} 127 | } 128 | 129 | \subsection*{Куча (heap)} 130 | 131 | Куча или пирамида представляет собой двоичное дерево, в котором самый большой элемент находится на самом верху. Каждый элемент пирамиды пронумерован в порядке сверху вниз и слева направо. На самой верхней ступени один элемент, на второй -- два, на третьей -- четыре и т.д. Нулевой элемент является родительским для первого и второго, первый -- для третьего и четвертого, второй -- для пятого и шестого. В общем случае для элемента с индексом i родительским является элемент индексом j = (i - 1) // 2. Тем самым пирамиду можно хранить в виде обычного списка: место элемента в пирамиде будет определяться его индексом. В пирамиде поддерживается следующая упорядоченность: каждый дочерний элемент не больше родительского. Если количество элементов равно нулю или одному, то, очевидно, ничего делать не требуется, однако если их больше, то при добавлении нового элемента (обычно в конец списка) нужно определить место последнего в родительской цепочке, сравнивая их и, если потребуется, меняя местами. 132 | 133 | В качестве примера реализуем класс Heap только лишь с конструктором и методом вставки нового элемента put. 134 | \texttt{ 135 | \begin{tabbing} 136 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 137 | class Heap:\\ 138 | \> def \_\_init\_\_(self):\\ 139 | \> \> self.\_m = []\\ 140 | \> def put(self, item):\\ 141 | \> \> self.\_m.append(item)\\ 142 | \> \> i = len(self.\_m) - 1\\ 143 | \> \> j = (i - 1) // 2\\ 144 | \> \> while i != 0 and self.\_m[i] > self.\_m[j]:\\ 145 | \> \> \> self.\_m[i], self.\_m[j] = self.\_m[j], self.\_m[i]\\ 146 | \> \> \> i = j\\ 147 | \> \> \> j = (i - 1) // 2 148 | \end{tabbing} 149 | } 150 | 151 | \subsection*{Очередь LIFO или стек(stack)} 152 | 153 | Стек представляет собой очередь, в которой последний вошедший является первым претендентом на выход (Last In -- First Out). Для стека характерны метод пополнения стека push и метод извлечения последним вошедшего элемента pop, чья реализация является очевидной. 154 | \texttt{ 155 | \begin{tabbing} 156 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 157 | class Stack:\\ 158 | \> def \_\_init\_\_(self):\\ 159 | \> \> self.\_m = []\\ 160 | \> def push(self, item):\\ 161 | \> \> self.\_m.append(item)\\ 162 | \> def pop(self):\\ 163 | \> \> top = self.\_m[-1]\\ 164 | \> \> self.\_m.pop()\\ 165 | \> \> return top 166 | \end{tabbing} 167 | } 168 | Стек применяется для правильного взаимоотношения вызываемых функций (стек вызовов). 169 | 170 | \subsection*{Исключения} 171 | В процессе работы программы часто возникают исключительные случаи. Например, это может быть деление на ноль или некорректный ввод (вместо цифры случайно нажимается клавиша с буквой). 172 | Для обработки исключений существует блок try ... except. 173 | \texttt{ 174 | \begin{tabbing} 175 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 176 | def f():\\ 177 | \> try:\\ 178 | \> \> \# команды нормального выполнения\\ 179 | \> except:\\ 180 | \> \> \# команды исключения 181 | \end{tabbing} 182 | } 183 | 184 | После except можно указать, какую конкретную ошибку следует обрабатывать (например, TypeError или ZeroDivisionError). Можно также указать несколько обработчиков для разных типов ошибок (это напоминает блок if ... elif ... elif ... else). 185 | 186 | Если несколько функций вызывают одна другую, то каждая из них может обрабатывать какие-нибудь из возможных ошибок. При возникновении ошибки, она будет <<искать>> свой обработчик, двигаясь по стеку вызовов от самой последней вызванной функции до первой, пока не натолкнется на него. Если же этого не произойдет, то будет осуществлен выход из всей программы с сообщением о конкретной ошибке. 187 | \end{document} 188 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_14/lection_14.tex: -------------------------------------------------------------------------------- 1 | % !TeX spellcheck = russian_english 2 | % !TeX encoding = UTF-8 3 | \documentclass[a4paper, fleqn]{article} 4 | 5 | \usepackage{indentfirst} % Красная строка 6 | \usepackage[T2A]{fontenc} % Поддержка русских букв 7 | \usepackage[utf8]{inputenc} % Кодировка utf8 8 | \usepackage[russian]{babel} % руссификация 9 | \usepackage{amssymb} % дополнительные символы 10 | \usepackage{textcomp} % дополнительные текстовые символы 11 | \usepackage{amsmath} % матрицы 12 | \usepackage{listings} 13 | % листинги 14 | \lstset{language=Python, tabsize=4, language=Python} 15 | 16 | 17 | \textwidth = 16 cm 18 | \oddsidemargin= 0 cm 19 | \evensidemargin= 1 cm 20 | 21 | 22 | % \abovedisplayskip = 0 pt %.2\abovedisplayskip 23 | % \belowdisplayskip = .2\belowdisplayskip 24 | % \abovedisplayshortskip=.2\abovedisplayshortskip 25 | % \belowdisplayshortskip=.2\belowdisplayshortskip 26 | % \topsep= 0 pt 27 | 28 | % \setlength{\mathindent}{1.2 cm} 29 | % \setlength{\topsep}{0 pt} 30 | % \setlength{\abovedisplayskip}{0 pt} 31 | 32 | % \clubpenalty = 5000 % запрет висячих строк 33 | % \widowpenalty = 5000 34 | \binoppenalty=10000 35 | \relpenalty=10000 36 | 37 | % собственные команды и окружения 38 | 39 | \newenvironment{example}[1][]{\medskip \noindent \textbf{Пример. #1}\par \nopagebreak}{\medskip \par} % окружение-"пример" 40 | 41 | 42 | \title{Лекция \textnumero\,13} 43 | % {\huge \vspace{3 cm}}} 44 | 45 | \author{Т.\,Ф. Хирьянов} 46 | 47 | \date{} 48 | 49 | \begin{document} 50 | \maketitle 51 | 52 | \subsection*{Хэширование. Хэш-функция} 53 | 54 | Представим себе экзамен. У каждого студента есть зачетная книжка. Семинарист подписал каждому конкретному студенту конкретный билет. Студенты положили свои зачетки на стол в произвольном порядке. Получилось два списка: фамилий и номеров билетов. Ставится задача вложить в каждую зачетку соответствующий билет и оценить сложность решения для различных алгоритмов (количество студентов равно N). 55 | 56 | Первый способ состоит в том, что для каждой следующей зачетки просматриваются все оставшиеся фамилии. Это полный перебор, и его сложность $O(N^2)$. 57 | 58 | Второй способ состоит в том, что можно отсортировать оба списка по ключам. Тогда асимптотика соответствует скорости сортировки (например, может быть достигнута скорость $O(N\cdot\ln_2{N})$). 59 | 60 | Однако наиболее эффективным является третий способ. Записать все фамилии и соответствующие им билеты в словарь (dict), где ключем является фамилия, а значением -- номер билета. Сложность создания словаря составит $O(N)$, а сложность поиска в нем -- $O(1)$ (т.е. за конечное количество операций не зависящих от количества элементов).\\ 61 | 62 | Рассмотрим другую задачу. Каким образом лучше всего организовать телефонную книгу, чтобы быстрее всего по номеру определить абонента? 63 | 64 | Один из способов -- отсортировать кортежи (номер, фамилия) по номерам. Тогда задача решится бинарным поиском и сложность составит $O(\ln_2{N})$. Это хороший способ, однако не идеальный. 65 | 66 | Пусть например есть записная книжка из 100 страниц. Тогда каждого нового абонента можно записывать на страницу с номером, равным остатку от деления номера абонента на 100 (т.е. запись <<12345 -- Вася>> попадет на 45 страницу). 67 | Такой подход называется \emph{хэшированием}: ключу (номеру) сопоставляется хэш-функция (остаток от деления). 68 | \subsection*{Коллизии} 69 | 70 | Так как у пятизначных номеров (в разобраном выше примере) мощность ключей - $10^5$, а мощность множества индексов (количество страниц) $10^2$, то, очевидно, возможна \emph{коллизия} -- на одну страницу попадут несколько номеров. 71 | Если одной хэш-функции соответствует очень много ключей то имеет место массовая коллизия. Поэтому для для хэш-функций существует следующее требование: для близко лежащих значений они должны давать существенно различные результаты. Еще одним требованием является скорость работы хэш-функции. Если она низкая, то хэширование теряет свое преимущество. 72 | 73 | Есть два пути разрешения коллизий: открытая и закрытая хэш-таблицы. В первом случае разрешается записывать несколько номеров на странице -- получается словарь списков. Во втором случае это запрещается и <<лишние>> номера записываются в следующую ячейку. 74 | 75 | Если нарисовать асимптотику скорости поиска в открытой хэш-таблице от количества хранимых данных, то вначале она будет константой, а по мере приближения к максимальному количеству ячеек будут возникать коллизии и время поиска будет увеличиваться; когда это значение будет пройдено асимптотика станет линейной. 76 | 77 | Для закрытой хэш-таблицы зависимость практически аналогична, однако по достижении максимума больше в нее будет нельзя ничего добавить. 78 | 79 | \subsection*{Открытая хэш-таблица} 80 | 81 | Описанную выше открытую хэш-таблицу можно реализовать следующим образом. 82 | \texttt{ 83 | \begin{tabbing} 84 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{6cm}\=\kill 85 | Class MyDict:\\ 86 | \> N\_max = 100 \> \> \> \# максимальный размер таблицы\\ 87 | \\ 88 | \> def add(self, key, value):\\ 89 | \> \> i = hash(key) \% N\_max \\ 90 | \> \> j = 0\\ 91 | \> \> while j < len(self.\_M[i]): \> \> \> \# пока i-й список не закончился\\ 92 | \> \> \> if self.\_M[i][j][0] == key: \> \> \# ключ j-ого кортежа в i-ом списке.\\ 93 | \> \> \> \> self.\_M[i][j] = (key, value) \> \# перезаписываем значение для ключа\\ 94 | \> \> \> \> break\\ 95 | \> \> else: \> \> \> \# вышли из цикла, но break не было\\ 96 | \> \> \> self.\_M[i].append((key, value)) \> \> \# можно записать пару ключ-значение\\ 97 | \\ 98 | \> def \_\_init\_\_(self, lst=[]):\\ 99 | \> \> self.\_M = [ [] for I in range(N\_max)] \> \> \> \# список пустых списков\\ 100 | \> \> for i, value in lst: \hspace{1cm} \# бежит по парам ключ-значение поданного списка\\ 101 | \> \> \> self.add(key, value) 102 | \end{tabbing} 103 | } 104 | \texttt{ 105 | \begin{tabbing} 106 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3.5cm}\=\kill 107 | \> def get(self, key):\\ 108 | \> \> i = hash(key) \% N\_max\\ 109 | \> \> for k, v in self.\_M[i]: \> \> \> \# поиск в i-ом списке пар\\ 110 | \> \> \> if k == key:\\ 111 | \> \> \> \> return v\\ 112 | \> \> \> return None \>\> \# хотя лучше вызвать исключение 113 | \end{tabbing} 114 | } 115 | \texttt{ 116 | \begin{tabbing} 117 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{5cm}\=\kill 118 | \> def del(self, key):\\ 119 | \> \> i = hash(key) \% N\_max \\ 120 | \> \> j = 0\\ 121 | \> \> while j < len(self.\_M[i]): \>\>\> \# пока i-й список не закончился\\ 122 | \> \> \> if self.\_M[i][j][0] == key: \>\> \# ключ j-ого кортежа в i-ом списке.\\ 123 | \> \> \> \> self.\_M[i].pop(j) \hspace{1cm} \> \# удаляем пару ключ-значение\\ 124 | \> \> \> \> return\\ 125 | \> \> raise KeyError() \hspace{1cm} \> \> \> \# если удалять нечего 126 | \end{tabbing} 127 | } 128 | 129 | \end{document} 130 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_18/createlistofedges.py: -------------------------------------------------------------------------------- 1 | edges = [] 2 | for vertex in G: 3 | for neighbour in G(vertex): 4 | edges.append(vertex, neighbour) 5 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_18/lection_18.out: -------------------------------------------------------------------------------- 1 | \BOOKMARK [1][-]{section.1}{\376\377\004\041\004\077\004\076\004\101\004\076\004\061\004\113\000\040\004\077\004\100\004\065\004\064\004\101\004\102\004\060\004\062\004\073\004\065\004\075\004\070\004\117\000\040\004\063\004\100\004\060\004\104\004\060\000\040\004\062\000\040\004\077\004\060\004\074\004\117\004\102\004\070}{}% 1 2 | \BOOKMARK [2][-]{subsection.1.1}{\376\377\004\041\004\077\004\070\004\101\004\076\004\072\000\040\004\100\004\065\004\061\004\065\004\100}{section.1}% 2 3 | \BOOKMARK [2][-]{subsection.1.2}{\376\377\004\034\004\060\004\102\004\100\004\070\004\106\004\060\000\040\004\101\004\074\004\065\004\066\004\075\004\076\004\101\004\102\004\070}{section.1}% 3 4 | \BOOKMARK [2][-]{subsection.1.3}{\376\377\004\041\004\077\004\070\004\101\004\076\004\072\000\040\004\101\004\062\004\117\004\067\004\075\004\076\004\101\004\102\004\070}{section.1}% 4 5 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_18/lection_18.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage{amsmath,amssymb,amsfonts,amsthm} 3 | \usepackage{tikz} 4 | \usepackage [utf8] {inputenc} 5 | \usepackage [T2A] {fontenc} 6 | \usepackage[russian]{babel} 7 | \usepackage{cmap} 8 | \usepackage{listings} 9 | \usepackage{color} 10 | 11 | \definecolor{mygreen}{rgb}{0,0.6,0} 12 | \definecolor{mygray}{rgb}{0.5,0.5,0.5} 13 | \definecolor{mymauve}{rgb}{0.58,0,0.82} 14 | 15 | \lstdefinestyle{customc}{ 16 | belowcaptionskip=1\baselineskip, 17 | breaklines=true, 18 | frame=L, 19 | xleftmargin=\parindent, 20 | language=Python, 21 | showstringspaces=false, 22 | basicstyle=\footnotesize\ttfamily, 23 | keywordstyle=\bfseries\color{green!40!black}, 24 | commentstyle=\itshape\color{purple!40!black}, 25 | identifierstyle=\color{blue}, 26 | stringstyle=\color{orange}, 27 | } 28 | 29 | 30 | \lstset{escapechar=@,style=customc} 31 | 32 | % Так ссылки в PDF будут активны 33 | \usepackage[unicode]{hyperref} 34 | 35 | % вы сможете вставлять картинки командой \includegraphics[width=0.7\textwidth]{ИМЯ ФАЙЛА} 36 | % получается подключать, как минимум, файлы .pdf, .jpg, .png. 37 | \usepackage{graphicx} 38 | % Если вы хотите явно указать поля: 39 | \usepackage[margin=1in]{geometry} 40 | % Или если вы хотите задать поля менее явно (чем больше DIV, тем больше места под текст): 41 | % \usepackage[DIV=10]{typearea} 42 | 43 | \usepackage{fancyhdr} 44 | 45 | \newcommand{\bbR}{\mathbb R}%теперь вместо длинной команды \mathbb R (множество вещественных чисел) можно писать короткую запись \bbR. Вместо \bbR вы можете вписать любую строчку букв, которая начинается с '\'. 46 | \newcommand{\eps}{\varepsilon} 47 | \newcommand{\bbN}{\mathbb N} 48 | \newcommand{\dif}{\mathrm{d}} 49 | 50 | \pagestyle{fancy} 51 | \makeatletter % сделать "@" "буквой", а не "спецсимволом" - можно использовать "служебные" команды, содержащие @ в названии 52 | \fancyhead[L]{\footnotesize Информатика\\ Внимание: конспект не проверялся преподавателями —- всегда используйте рекомендуемую литературу при подготовке к экзамену!}%Это будет написано вверху страницы слева 53 | \fancyhead[R]{} 54 | \fancyfoot[L]{}%имя автора будет написано внизу страницы слева 55 | \fancyfoot[R]{\thepage}%номер страницы —- внизу справа 56 | \fancyfoot[C]{ Замечания и предложения просьба писать на \href{mailto:pulsar@phystech.edu}{pulsar@phystech.edu}}%по центру внизу страницы пусто 57 | 58 | \renewcommand{\maketitle}{% 59 | \noindent{\bfseries\scshape\large\@title\ \mdseries\upshape}\par 60 | \noindent {\large\itshape\@author} 61 | \vskip 2ex} 62 | \makeatother 63 | \def\dd#1#2{\frac{\partial#1}{\partial#2}} 64 | \def\ddd#1#2#3{\frac{\partial^2#1}{\partial#2\partial#3}} 65 | 66 | \title{Графы. I} 67 | \author{Тимофей Хирьянов} 68 | \date{27 февраля 2016 г.} 69 | 70 | \begin{document} 71 | \maketitle 72 | \section{Способы представления графа в памяти} 73 | Существует три основных способа представления графа в памяти: 74 | \begin{enumerate} 75 | \item Список ребер 76 | \item Матрица смежности 77 | \item Список связности 78 | \end{enumerate} 79 | На практике граф обычно представляется в виде списка ребер. Ниже вы видите представления одного и того же графа разными способами. 80 | 81 | \subsection{Список ребер} 82 | \lstinputlisting[language=Python]{listofedges.py} 83 | Считывание списка ребер в список тривиально, поэтому опустим его. 84 | 85 | \subsection{Матрица смежности} 86 | \lstinputlisting[language=Python]{matrix.py} 87 | Считывание списка ребер в матрицу смежности: 88 | \lstinputlisting[language=Python]{readmatrix.py} 89 | 90 | \subsection{Список связности} 91 | \lstinputlisting[language=Python]{list.py} 92 | \newpage 93 | Перейдем от списка связности к списку ребер: 94 | \lstinputlisting[language=Python]{createlistofedges.py} 95 | Считывание списка ребер в список связности: 96 | \lstinputlisting[language=Python]{readlist.py} 97 | 98 | \end{document} 99 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_18/list.py: -------------------------------------------------------------------------------- 1 | N = 5 2 | G = {0: {1, 2, 4}, 3 | 1: {0, 2, 4}, 4 | 2: {0, 1, 3}, 5 | 3: {2, 4}, 6 | 4: {0, 1, 3}} 7 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_18/listofedges.py: -------------------------------------------------------------------------------- 1 | N = 5 2 | edges = {[0, 1], [0, 2], 3 | [0, 4], [1, 3], 4 | [1, 4], [2, 3], 5 | [3, 4] } 6 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_18/matrix.py: -------------------------------------------------------------------------------- 1 | N = 5 2 | M = [[0, 1, 1, 0, 1], 3 | [1, 0, 1, 0, 1], 4 | [1, 1, 0, 1, 0], 5 | [0, 0, 1, 0, 1], 6 | [1, 1, 0, 1, 0]] 7 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_18/readlist.py: -------------------------------------------------------------------------------- 1 | N = int(input()) 2 | G = {} 3 | k = int(input()) 4 | for i in range(k): 5 | a, b = [int for x in input().split()] 6 | if a not in G: 7 | G[a] = {b} 8 | else: 9 | G[a].insert(b) 10 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_18/readmatrix.py: -------------------------------------------------------------------------------- 1 | k = int(input()) 2 | M = [[0]*N for i in range(N)] 3 | for i in range(k): 4 | a, b = input().split() 5 | a, b = int(a), int(b) 6 | M[a][b] = 1 7 | M[b][a] = 1 8 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_19/lection_19.out: -------------------------------------------------------------------------------- 1 | \BOOKMARK [1][-]{section.1}{\376\377\004\027\004\060\004\064\004\060\004\107\004\060\000\040\004\055\004\071\004\073\004\065\004\100\004\060}{}% 1 2 | \BOOKMARK [1][-]{section.2}{\376\377\004\027\004\060\004\064\004\060\004\107\004\060\000\040\004\023\004\060\004\074\004\070\004\073\004\114\004\102\004\076\004\075\004\060}{}% 2 3 | \BOOKMARK [1][-]{section.3}{\376\377\004\027\004\060\004\064\004\060\004\107\004\060\000\040\004\076\000\040\004\072\004\070\004\102\004\060\004\071\004\101\004\072\004\076\004\074\000\040\004\077\004\076\004\107\004\102\004\060\004\073\004\114\004\076\004\075\004\065}{}% 3 4 | \BOOKMARK [1][-]{section.4}{\376\377\004\027\004\060\004\064\004\060\004\107\004\060\000\040\004\072\004\076\004\074\004\074\004\070\004\062\004\076\004\117\004\066\004\065\004\100\004\060}{}% 4 5 | \BOOKMARK [2][-]{subsection.4.1}{\376\377\004\034\004\065\004\102\004\076\004\064\000\040\004\077\004\076\004\073\004\075\004\076\004\063\004\076\000\040\004\077\004\065\004\100\004\065\004\061\004\076\004\100\004\060}{section.4}% 5 6 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_19/lection_19.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage{amsmath,amssymb,amsfonts,amsthm} 3 | \usepackage{tikz} 4 | \usepackage [utf8] {inputenc} 5 | \usepackage [T2A] {fontenc} 6 | \usepackage[russian]{babel} 7 | \usepackage{cmap} 8 | \usepackage{listings} 9 | \usepackage{color} 10 | 11 | \definecolor{mygreen}{rgb}{0,0.6,0} 12 | \definecolor{mygray}{rgb}{0.5,0.5,0.5} 13 | \definecolor{mymauve}{rgb}{0.58,0,0.82} 14 | 15 | \lstdefinestyle{customc}{ 16 | belowcaptionskip=1\baselineskip, 17 | breaklines=true, 18 | frame=L, 19 | xleftmargin=\parindent, 20 | language=Python, 21 | showstringspaces=false, 22 | basicstyle=\footnotesize\ttfamily, 23 | keywordstyle=\bfseries\color{green!40!black}, 24 | commentstyle=\itshape\color{purple!40!black}, 25 | identifierstyle=\color{blue}, 26 | stringstyle=\color{orange}, 27 | } 28 | 29 | 30 | \newtheorem{defenition}{Определение} 31 | \newtheorem{theorem}{Теорема} 32 | \newtheorem{problem}{Задача} 33 | 34 | \lstset{escapechar=@,style=customc} 35 | 36 | % Так ссылки в PDF будут активны 37 | \usepackage[unicode]{hyperref} 38 | 39 | % вы сможете вставлять картинки командой \includegraphics[width=0.7\textwidth]{ИМЯ ФАЙЛА} 40 | % получается подключать, как минимум, файлы .pdf, .jpg, .png. 41 | \usepackage{graphicx} 42 | % Если вы хотите явно указать поля: 43 | \usepackage[margin=1in]{geometry} 44 | % Или если вы хотите задать поля менее явно (чем больше DIV, тем больше места под текст): 45 | % \usepackage[DIV=10]{typearea} 46 | 47 | \usepackage{fancyhdr} 48 | 49 | \newcommand{\bbR}{\mathbb R}%теперь вместо длинной команды \mathbb R (множество вещественных чисел) можно писать короткую запись \bbR. Вместо \bbR вы можете вписать любую строчку букв, которая начинается с '\'. 50 | \newcommand{\eps}{\varepsilon} 51 | \newcommand{\bbN}{\mathbb N} 52 | \newcommand{\dif}{\mathrm{d}} 53 | 54 | \pagestyle{fancy} 55 | \makeatletter % сделать "@" "буквой", а не "спецсимволом" - можно использовать "служебные" команды, содержащие @ в названии 56 | \fancyhead[L]{\footnotesize Информатика\\ Внимание: конспект не проверялся преподавателями —- всегда используйте рекомендуемую литературу при подготовке к экзамену!}%Это будет написано вверху страницы слева 57 | \fancyhead[R]{} 58 | \fancyfoot[L]{}%имя автора будет написано внизу страницы слева 59 | \fancyfoot[R]{\thepage}%номер страницы —- внизу справа 60 | \fancyfoot[C]{ Замечания и предложения просьба писать на \href{mailto:pulsar@phystech.edu}{pulsar@phystech.edu}}%по центру внизу страницы пусто 61 | 62 | \renewcommand{\maketitle}{% 63 | \noindent{\bfseries\scshape\large\@title\ \mdseries\upshape}\par 64 | \noindent {\large\itshape\@author} 65 | \vskip 2ex} 66 | \makeatother 67 | \def\dd#1#2{\frac{\partial#1}{\partial#2}} 68 | \def\ddd#1#2#3{\frac{\partial^2#1}{\partial#2\partial#3}} 69 | 70 | \title{Графы. III} 71 | \author{Тимофей Хирьянов} 72 | \date{27 февраля 2016 г.} 73 | 74 | \begin{document} 75 | \maketitle 76 | \section{Задача Эйлера} 77 | \begin{problem} 78 | Задача о кёнигсбергских мостах (нем. Königsberger Brückenproblem) --- старинная математическая задача, в которой спрашивалось, как можно пройти по всем семи мостам Кёнигсберга, не проходя ни по одному из них дважды. 79 | \end{problem} 80 | \begin{defenition} 81 | Эйлеров цикл — это цикл графа, проходящий через каждое ребро (дугу) графа ровно по одному разу. 82 | \end{defenition} 83 | \begin{defenition} 84 | Эйлеров граф — граф, содержащий эйлеров цикл. 85 | \end{defenition} 86 | \begin{defenition} 87 | Полуэйлеров граф — граф, содержащий эйлеров путь (цепь). 88 | \end{defenition} 89 | 90 | 91 | \begin{theorem} 92 | Граф является Эйлеровым $\Leftrightarrow$ кратность всех вершин четная. 93 | \end{theorem} 94 | \begin{theorem} 95 | Граф является полуэйлеровым $\Leftrightarrow$ кратность всех вершин четная, кроме двух. 96 | \end{theorem} 97 | 98 | Доказательство этих двух теорем опустим. 99 | 100 | 101 | \section{Задача Гамильтона} 102 | \begin{problem} 103 | Задача Гамильтона --- посетить каждую вершину ровно один раз. 104 | \end{problem} 105 | \begin{defenition} 106 | Гамильтонов граф --- граф, содержащий гамильтонов цикл. 107 | \end{defenition} 108 | \begin{defenition} 109 | Гамильтонов цикл --- цикл, содержащий все вершины данного графа. 110 | \end{defenition} 111 | \begin{defenition} 112 | Полугамильтонов граф --- граф, содержащий гамильтонов путь. 113 | \end{defenition} 114 | 115 | \section{Задача о китайском почтальоне} 116 | \begin{problem} 117 | Задача о китайском почтальоне --- посетить все ребра не менее одного раза, при этом так, чтобы суммарная длина траектории путь была минимальна. 118 | \end{problem} 119 | Чем эта задача похожа на задачу Эйлера? Тем, что мы посещаем ребра, а не вершины, каждое ребро обязаны посетить хотя бы один раз. 120 | Очевидно, что в случае если граф Эйлеров, то задача имеет однозначное решение: мы посещаем каждое ребро два раза. Но задача почтальона несколько шире --- мы можем посетить каждое ребро \emph{как минимум один раз}. 121 | То есть, по одному ребру можно проходить два раза. И вот тут возникает вопрос: по какому проходить два раза так, чтобы путь был \emph{наименьшим}. То есть наша задача --- сделать из неэйлерового графа хотя бы полуэйлеров. 122 | Эта задача нетривиальна. 123 | 124 | \section{Задача коммивояжера} 125 | \begin{problem} 126 | Найти оптимальный по длине гамильтонов цикл. 127 | \end{problem} 128 | 129 | Заметим, что в полносвязном графе задача Гамильтона не возникает, но имеет место задача коммивояжера. 130 | 131 | \subsection{Метод полного перебора} 132 | Можно перебрать все возможные пути, а потом из них выбрать наименьший.Этот алгоритм выполняется за $O(n!)$. 133 | Приведем решение задачи коммивояжера: 134 | \lstinputlisting[language=Python]{voyajer.py} 135 | 136 | 137 | 138 | 139 | \end{document} 140 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_19/voyajer.py: -------------------------------------------------------------------------------- 1 | def voyager(G, node, path = [], pathlen = 0, used = set()): 2 | global optimalpath, optimalpathlen 3 | if len(G) == len(used): 4 | if pathlen < optimalpathlen and node in G[path[-1]]: 5 | optimalpathlen = pathlen 6 | opltimalpath = path 7 | else: 8 | for neighbour in G[node]: 9 | if neighbour not in used: 10 | voyager(G, neighbour, path + [neighbour],pathlen + 11 | G[node][neighbour], used + {neighbour}) 12 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_20/big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/2015-2016_lections/lection_20/big.png -------------------------------------------------------------------------------- /2015-2016_lections/lection_20/binary tree search.py: -------------------------------------------------------------------------------- 1 | 5, 3, 8, 6, 9, 1, 2, 7, 4, 10 2 | 3 | class node: 4 | def __init__(self): 5 | self.key = key 6 | self.value = value 7 | self.left = None 8 | self.right = None 9 | 10 | 11 | def print_binary_tree(node): 12 | if not node: 13 | return 14 | print(print_binary_tree(node.left)) 15 | print(node.value) 16 | print(print_binary_tree(node.right) 17 | 18 | 19 | 20 | def tree_search(node, key): 21 | if not node: 22 | return NaN 23 | if node.key == key: 24 | return node 25 | if key < node.key: 26 | return tree_search(node.left, key) 27 | else: 28 | return tree.search(node.right, key) 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_20/binary tree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, key, value): 3 | self.key = key 4 | self.value = value 5 | self.left = None 6 | self.right = None 7 | self.parent = None 8 | 9 | class Tree: 10 | def __init__(self): 11 | self.root = None 12 | 13 | def print_tree(self): 14 | def print_subtree(node, prefix): 15 | if not node: 16 | return 17 | if node.right: 18 | print_subtree(node.right, ' '*len(prefix) + ' ┌') 19 | print(prefix, (node.key, node.value), sep='') 20 | if node.left: 21 | print_subtree(node.left, ' '*len(prefix) + ' └') 22 | if self.root: 23 | print_subtree(self.root, '') 24 | else: 25 | print('Empty tree!') 26 | 27 | def find_node_by_key(self, key): 28 | current = self.root 29 | while current and current.key != key: 30 | if key < current.key: 31 | current = current.left 32 | else: 33 | current = current.right 34 | return current 35 | 36 | def __getitem__(self, key): 37 | node = self.find_node_by_key() 38 | return node.value if node else None 39 | 40 | def add_node(self, node): 41 | if not self.root: 42 | self.root = node 43 | return 44 | current = self.root 45 | path = [current] 46 | while current.key != node.key: 47 | if node.key < current.key: 48 | if current.left: 49 | current = current.left 50 | path.append(current) 51 | else: 52 | current.left = node 53 | node.parent = current 54 | break 55 | else: 56 | if current.right: 57 | current = current.right 58 | else: 59 | current.right = node 60 | node.parent = current 61 | break 62 | current.value = node.value 63 | 64 | def add_pair(self, key, value): 65 | node = Node(key, value) 66 | self.add_node(node) 67 | 68 | def del_node(self, key): 69 | node = self.find_node_by_key(key) 70 | if not node: 71 | return # no key in tree 72 | if node.left: 73 | new_boss_node = node.left 74 | current = node.left 75 | while current.right: 76 | current = current.right 77 | current.right = node.right 78 | node.right.parent = current 79 | new_boss_node.parent = node.parent 80 | elif node.right: 81 | new_boss_node = node.right 82 | new_boss_node.parent = node.parent 83 | else: 84 | new_boss_node = None 85 | 86 | if node == self.root: 87 | self.root = new_boss_node 88 | else: 89 | if node == node.parent.left: 90 | node.parent.left = new_boss_node 91 | else: 92 | node.parent.right = new_boss_node 93 | 94 | if __name__ == '__main__': 95 | '''tree = Tree() 96 | for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]: 97 | tree.add_pair(x, ' ') 98 | tree.print_tree()''' 99 | 100 | tree = Tree() 101 | for x in [4, 2, 1, 3, 6, 5, 7]: 102 | tree.add_pair(x, x) 103 | tree.print_tree() 104 | tree.add_pair(3, 0) 105 | tree.print_tree() 106 | tree.del_node(2) 107 | tree.print_tree() 108 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_20/binarytree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, key, value): 3 | self.key = key 4 | self.value = value 5 | self.left = None 6 | self.right = None 7 | self.parent = None 8 | 9 | class Tree: 10 | def __init__(self): 11 | self.root = None 12 | 13 | def print_tree(self): 14 | def print_subtree(node, prefix): 15 | if not node: 16 | return 17 | if node.right: 18 | print_subtree(node.right, ' '*len(prefix) + ' |') 19 | print(prefix, (node.key, node.value), sep='') 20 | if node.left: 21 | print_subtree(node.left, ' '*len(prefix) + ' |') 22 | if self.root: 23 | print_subtree(self.root, '') 24 | else: 25 | print('Empty tree!') 26 | 27 | def find_node_by_key(self, key): 28 | current = self.root 29 | while current and current.key != key: 30 | if key < current.key: 31 | current = current.left 32 | else: 33 | current = current.right 34 | return current 35 | 36 | def __getitem__(self, key): 37 | node = self.find_node_by_key() 38 | return node.value if node else None 39 | 40 | def add_node(self, node): 41 | if not self.root: 42 | self.root = node 43 | return 44 | current = self.root 45 | path = [current] 46 | while current.key != node.key: 47 | if node.key < current.key: 48 | if current.left: 49 | current = current.left 50 | path.append(current) 51 | else: 52 | current.left = node 53 | node.parent = current 54 | break 55 | else: 56 | if current.right: 57 | current = current.right 58 | else: 59 | current.right = node 60 | node.parent = current 61 | break 62 | current.value = node.value 63 | 64 | def add_pair(self, key, value): 65 | node = Node(key, value) 66 | self.add_node(node) 67 | 68 | def del_node(self, key): 69 | node = self.find_node_by_key(key) 70 | if not node: 71 | return # no key in tree 72 | if node.left: 73 | new_boss_node = node.left 74 | current = node.left 75 | while current.right: 76 | current = current.right 77 | current.right = node.right 78 | node.right.parent = current 79 | new_boss_node.parent = node.parent 80 | elif node.right: 81 | new_boss_node = node.right 82 | new_boss_node.parent = node.parent 83 | else: 84 | new_boss_node = None 85 | 86 | if node == self.root: 87 | self.root = new_boss_node 88 | else: 89 | if node == node.parent.left: 90 | node.parent.left = new_boss_node 91 | else: 92 | node.parent.right = new_boss_node 93 | 94 | if __name__ == '__main__': 95 | 96 | tree = Tree() 97 | for x in [4, 2, 1, 3, 6, 5, 7]: 98 | tree.add_pair(x, x) 99 | tree.print_tree() 100 | tree.add_pair(3, 0) 101 | tree.print_tree() 102 | tree.del_node(2) 103 | tree.print_tree() 104 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_20/lection_20.out: -------------------------------------------------------------------------------- 1 | \BOOKMARK [1][-]{section.1}{\376\377\004\042\004\076\004\077\004\076\004\073\004\076\004\063\004\070\004\107\004\065\004\101\004\072\004\060\004\117\000\040\004\101\004\076\004\100\004\102\004\070\004\100\004\076\004\062\004\072\004\060}{}% 1 2 | \BOOKMARK [2][-]{subsection.1.1}{\376\377\004\020\004\073\004\063\004\076\004\100\004\070\004\102\004\074\000\040\004\032\004\060\004\075\004\060}{section.1}% 2 3 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_20/lection_20.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage{amsmath,amssymb,amsfonts,amsthm} 3 | \usepackage{tikz} 4 | \usepackage [utf8] {inputenc} 5 | \usepackage [T2A] {fontenc} 6 | \usepackage[russian]{babel} 7 | \usepackage{cmap} 8 | \usepackage{listings} 9 | \usepackage{color} 10 | 11 | \definecolor{mygreen}{rgb}{0,0.6,0} 12 | \definecolor{mygray}{rgb}{0.5,0.5,0.5} 13 | \definecolor{mymauve}{rgb}{0.58,0,0.82} 14 | 15 | \lstdefinestyle{customc}{ 16 | belowcaptionskip=1\baselineskip, 17 | breaklines=true, 18 | frame=L, 19 | xleftmargin=\parindent, 20 | language=Python, 21 | showstringspaces=false, 22 | basicstyle=\footnotesize\ttfamily, 23 | keywordstyle=\bfseries\color{green!40!black}, 24 | commentstyle=\itshape\color{purple!40!black}, 25 | identifierstyle=\color{blue}, 26 | stringstyle=\color{orange}, 27 | } 28 | 29 | 30 | \newtheorem{defenition}{Определение} 31 | \newtheorem{theorem}{Теорема} 32 | \newtheorem{problem}{Задача} 33 | 34 | \lstset{escapechar=@,style=customc} 35 | 36 | % Так ссылки в PDF будут активны 37 | \usepackage[unicode]{hyperref} 38 | 39 | % вы сможете вставлять картинки командой \includegraphics[width=0.7\textwidth]{ИМЯ ФАЙЛА} 40 | % получается подключать, как минимум, файлы .pdf, .jpg, .png. 41 | \usepackage{graphicx} 42 | % Если вы хотите явно указать поля: 43 | \usepackage[margin=1in]{geometry} 44 | % Или если вы хотите задать поля менее явно (чем больше DIV, тем больше места под текст): 45 | % \usepackage[DIV=10]{typearea} 46 | 47 | \usepackage{fancyhdr} 48 | 49 | \newcommand{\bbR}{\mathbb R}%теперь вместо длинной команды \mathbb R (множество вещественных чисел) можно писать короткую запись \bbR. Вместо \bbR вы можете вписать любую строчку букв, которая начинается с '\'. 50 | \newcommand{\eps}{\varepsilon} 51 | \newcommand{\bbN}{\mathbb N} 52 | \newcommand{\dif}{\mathrm{d}} 53 | 54 | \pagestyle{fancy} 55 | \makeatletter % сделать "@" "буквой", а не "спецсимволом" - можно использовать "служебные" команды, содержащие @ в названии 56 | \fancyhead[L]{\footnotesize Информатика\\ Внимание: конспект не проверялся преподавателями —- всегда используйте рекомендуемую литературу при подготовке к экзамену!}%Это будет написано вверху страницы слева 57 | \fancyhead[R]{} 58 | \fancyfoot[L]{}%имя автора будет написано внизу страницы слева 59 | \fancyfoot[R]{\thepage}%номер страницы —- внизу справа 60 | \fancyfoot[C]{ Замечания и предложения просьба писать на \href{mailto:pulsar@phystech.edu}{pulsar@phystech.edu}}%по центру внизу страницы пусто 61 | 62 | \renewcommand{\maketitle}{% 63 | \noindent{\bfseries\scshape\large\@title\ \mdseries\upshape}\par 64 | \noindent {\large\itshape\@author} 65 | \vskip 2ex} 66 | \makeatother 67 | \def\dd#1#2{\frac{\partial#1}{\partial#2}} 68 | \def\ddd#1#2#3{\frac{\partial^2#1}{\partial#2\partial#3}} 69 | 70 | \title{Графы. IV} 71 | \author{Тимофей Хирьянов} 72 | \date{27 февраля 2016 г.} 73 | 74 | \begin{document} 75 | \maketitle 76 | \begin{defenition} 77 | Ориентированный граф --- граф, у ребер которого есть начало и конец. 78 | \end{defenition} 79 | \begin{defenition} 80 | Сильно связный граф --- граф, в котором существует (ориентированный) путь из любой вершины в любую другую. 81 | \end{defenition} 82 | \section{Топологическая сортировка} 83 | \subsection{Алгоритм Кана} 84 | Пусть дан бесконтурный ориентированный простой граф. Через $A(v)$ обозначим множество вершин такихб из которых есть дуга в вершину $v$. 85 | Пусть P --- искомая последовательность вершин. 86 | \newline 87 | 88 | пока $|P| < |V|$:\newline 89 | выбрать любую $v$ такую, что $A(v) = $ и $v \notin P$\newline 90 | $P \Leftarrow P, v$\newline 91 | удалить $v$ из всех $A(u), u \neq v$ 92 | \newline 93 | 94 | 95 | Наличие хотя бы одного контура в графе приведёт к тому, что на определённой итерации цикла не удастся выбрать новую вершину v. 96 | \begin{defenition} 97 | Корневое дерево --- дерево с отмеченной вершиной. 98 | \end{defenition} 99 | \begin{defenition} 100 | Высота корневого дерева --- максимальное количество ребер в простом пути от корня к вершинам. 101 | \end{defenition} 102 | \begin{defenition} 103 | Двоичное дерево --- дерево, у каждой вершины не более чем два потомка. 104 | \end{defenition} 105 | 106 | Реализуем класс дерева. Для этого сделаем вспомогательный класс вершины с полями левой, правой и родительских вершин. В классе дерева реализуем метод распечатки дерева, поиска вершины по ключу, добавления и удаления вершины. Также будет полезным метод добавления пары вершин и ребра между ними. 107 | \lstinputlisting[language=Python]{binarytree.py} 108 | 109 | \begin{defenition} 110 | Несбалансированное дерево --- дерево с различной длинной поддеревьев. 111 | \end{defenition} 112 | Что делать в случае несбалансированного дерева? Нужно совершить правый поворот. 113 | \begin{defenition} 114 | Правый поворот --- изменение вершины дерева с сохранением упорядоченности. 115 | \end{defenition} 116 | В каждой вершине будем хранить <<меру дисбаланса>>. $D\in \left\lbrace-1, 0, 1 \right\rbrace$. Скажем, что $1, -1$ --- дисбаланс в одно ребро. И если дисбаланс, то есть разность длин поддеревьев, больше двух, то дерево требует балансировки. 117 | Определяется два типа вращения: большое и малое. Они могут быть как правыми, так и левыми. 118 | 119 | \begin{figure}[h] 120 | \begin{minipage}[h]{0.49\linewidth} 121 | \centering 122 | {\includegraphics[width=0.5\linewidth]{small} \\ Малое правое вращение} 123 | \end{minipage} 124 | \hfill 125 | \begin{minipage}[h]{0.49\linewidth} 126 | \centering 127 | {\includegraphics[width=0.5\linewidth]{big} \\ Большое правое вращение} 128 | \end{minipage} 129 | \caption{Иллюстрация вращений} 130 | \label{ris:image1} 131 | \end{figure} 132 | 133 | 134 | 135 | \end{document} 136 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_20/node.py: -------------------------------------------------------------------------------- 1 | def voyager(G, node, path = [], pathlen = 0, used = set()): 2 | global optimalpath, optimalpathlen 3 | if len(G) == len(used): 4 | if pathlen < optimalpathlen and node in G[path[-1]]: 5 | optimalpathlen = pathlen 6 | opltimalpath = path 7 | else: 8 | for neighbour in G[node]: 9 | if neighbour not in used: 10 | voyager(G, neighbour, path + [neighbour],pathlen + 11 | G[node][neighbour], used + {neighbour}) 12 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_20/small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/2015-2016_lections/lection_20/small.png -------------------------------------------------------------------------------- /2015-2016_lections/lection_21/7-1.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/2015-2016_lections/lection_21/7-1.py -------------------------------------------------------------------------------- /2015-2016_lections/lection_21/7-2.py: -------------------------------------------------------------------------------- 1 | def check(sub, s, i, pos): 2 | for i in range(len(sub)): 3 | if sub[i] != s[s+i]: 4 | return False 5 | return False 6 | 7 | 8 | def find_substring(s, sub): 9 | for pos in range(0, len(s)-len(sub)+2): 10 | for i in range(len(sub)): 11 | if check(sub, s, i, pos): 12 | return pos 13 | return -1 14 | 15 | 16 | def my_hash(s): 17 | h = 0 18 | for char in s: 19 | h += hash(char) 20 | return h 21 | 22 | 23 | def my_rehash(h, new, old): 24 | h = h-hash(old)+hash(new) 25 | return h 26 | 27 | 28 | def find_rabin_karp(s, sub): 29 | h_sub = my_hash(sub) 30 | h = my_hash(s[0:len(sub)]) 31 | if h == h.sub: 32 | if check(sub, s, 0): 33 | return 0 34 | for pos in range(1, len(s)-len(sub)+2): 35 | h = my_rehash(h, s[pos+len(sub)]) 36 | if h == h_sub: 37 | if check(sub, s, pos): 38 | return pos 39 | 40 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_21/lection_21.out: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/2015-2016_lections/lection_21/lection_21.out -------------------------------------------------------------------------------- /2015-2016_lections/lection_21/lection_21.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage{amsmath,amssymb,amsfonts,amsthm} 3 | \usepackage{tikz} 4 | \usepackage [utf8] {inputenc} 5 | \usepackage [T2A] {fontenc} 6 | \usepackage[russian]{babel} 7 | \usepackage{cmap} 8 | \usepackage{listings} 9 | \usepackage{color} 10 | 11 | \definecolor{mygreen}{rgb}{0,0.6,0} 12 | \definecolor{mygray}{rgb}{0.5,0.5,0.5} 13 | \definecolor{mymauve}{rgb}{0.58,0,0.82} 14 | 15 | \lstdefinestyle{customc}{ 16 | belowcaptionskip=1\baselineskip, 17 | breaklines=true, 18 | frame=L, 19 | xleftmargin=\parindent, 20 | language=Python, 21 | showstringspaces=false, 22 | basicstyle=\footnotesize\ttfamily, 23 | keywordstyle=\bfseries\color{green!40!black}, 24 | commentstyle=\itshape\color{purple!40!black}, 25 | identifierstyle=\color{blue}, 26 | stringstyle=\color{orange}, 27 | } 28 | 29 | 30 | \newtheorem{defenition}{Определение} 31 | \newtheorem{theorem}{Теорема} 32 | \newtheorem{problem}{Задача} 33 | 34 | \lstset{escapechar=@,style=customc} 35 | 36 | % Так ссылки в PDF будут активны 37 | \usepackage[unicode]{hyperref} 38 | 39 | % вы сможете вставлять картинки командой \includegraphics[width=0.7\textwidth]{ИМЯ ФАЙЛА} 40 | % получается подключать, как минимум, файлы .pdf, .jpg, .png. 41 | \usepackage{graphicx} 42 | % Если вы хотите явно указать поля: 43 | \usepackage[margin=1in]{geometry} 44 | % Или если вы хотите задать поля менее явно (чем больше DIV, тем больше места под текст): 45 | % \usepackage[DIV=10]{typearea} 46 | 47 | \usepackage{fancyhdr} 48 | 49 | \newcommand{\bbR}{\mathbb R}%теперь вместо длинной команды \mathbb R (множество вещественных чисел) можно писать короткую запись \bbR. Вместо \bbR вы можете вписать любую строчку букв, которая начинается с '\'. 50 | \newcommand{\eps}{\varepsilon} 51 | \newcommand{\bbN}{\mathbb N} 52 | \newcommand{\dif}{\mathrm{d}} 53 | 54 | \pagestyle{fancy} 55 | \makeatletter % сделать "@" "буквой", а не "спецсимволом" - можно использовать "служебные" команды, содержащие @ в названии 56 | \fancyhead[L]{\footnotesize Информатика\\ Внимание: конспект не проверялся преподавателями —- всегда используйте рекомендуемую литературу при подготовке к экзамену!}%Это будет написано вверху страницы слева 57 | \fancyhead[R]{} 58 | \fancyfoot[L]{}%имя автора будет написано внизу страницы слева 59 | \fancyfoot[R]{\thepage}%номер страницы —- внизу справа 60 | \fancyfoot[C]{ Замечания и предложения просьба писать на \href{mailto:pulsar@phystech.edu}{pulsar@phystech.edu}}%по центру внизу страницы пусто 61 | 62 | \renewcommand{\maketitle}{% 63 | \noindent{\bfseries\scshape\large\@title\ \mdseries\upshape}\par 64 | \noindent {\large\itshape\@author} 65 | \vskip 2ex} 66 | \makeatother 67 | \def\dd#1#2{\frac{\partial#1}{\partial#2}} 68 | \def\ddd#1#2#3{\frac{\partial^2#1}{\partial#2\partial#3}} 69 | 70 | \title{Поиск подстроки в строке} 71 | \author{Тимофей Хирьянов} 72 | \date{27 февраля 2016 г.} 73 | 74 | \begin{document} 75 | \maketitle 76 | Рассмотрим наивный поиск и алгоритм Рабина-Карпа. 77 | В наивном поиске поиск осуществляется простым наложением паттерна на текст, последовательно, начиная с первого символа. 78 | 79 | Алгоритм Рабина-Карпа пытается ускорить проверку эквивалентности образца с подстроками в тексте, используя хеш-функцию. Хеш-функция — это функция, преобразующая каждую строку в числовое значение, называемое хеш-значением (хеш); например, мы можем иметь хеш от строки «hello» равным 5. Алгоритм использует тот факт, что если две строки одинаковы, то и их хеш-значения также одинаковы. Таким образом, всё что нам нужно, это посчитать хеш-значение искомой подстроки и затем найти подстроку с таким же хеш-значением. 80 | 81 | Однако существуют две проблемы, связанные с этим. Первая состоит в том, что, так как существует очень много различных строк, между двумя различными строками может произойти коллизия — совпадение их хешей. В таких случаях необходимо посимвольно проверять совпадение самих подстрок, что занимает достаточно много времени, если данные подстроки имеют большую длину. При использовании достаточно хороших хеш-фунцкий коллизии случаются крайне редко, в результате среднее время поиска оказывается невелико. 82 | 83 | Еще одна проблема заключается в пересчете хеша. При навном пересчете затрачивается такое же время, как у более простых алгоритмов. Здесь же реализован кольцевой пересчет хеша, т.е. следующий символ добавляется в хеш, а последний убирается. 84 | \lstinputlisting[language=Python]{7-2.py} 85 | 86 | 87 | 88 | 89 | \end{document} 90 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_23/au.py: -------------------------------------------------------------------------------- 1 | line = input() 2 | state = 0 3 | for char in line: 4 | if state == 0: 5 | if char == 'a': 6 | state == 1 7 | elif state == 1: 8 | if char == 'b': 9 | state = 2 10 | elif char == 'a': 11 | state = 1 12 | else: 13 | state = 0 14 | elif state == 2: 15 | if char == 'c': 16 | state = 3 17 | elif char == 'a': 18 | state = 1 19 | else: 20 | state = 0 21 | elif state == 3: 22 | if char == 'd': 23 | state = 4 24 | elif char == 'a': 25 | state = 1 26 | else: 27 | state = 0 28 | print('Substring found!' if state == 4 else 'Substring not found.') 29 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_23/lection_23.out: -------------------------------------------------------------------------------- 1 | \BOOKMARK [1][-]{section.1}{\376\377\004\034\004\060\004\110\004\070\004\075\004\060\000\040\004\042\004\114\004\116\004\100\004\070\004\075\004\063\004\060}{}% 1 2 | \BOOKMARK [1][-]{section.2}{\376\377\004\032\004\076\004\075\004\065\004\107\004\075\004\113\004\071\000\040\004\060\004\062\004\102\004\076\004\074\004\060\004\102}{}% 2 3 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_23/lection_23.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage{amsmath,amssymb,amsfonts,amsthm} 3 | \usepackage{tikz} 4 | \usepackage [utf8] {inputenc} 5 | \usepackage [T2A] {fontenc} 6 | \usepackage[russian]{babel} 7 | \usepackage{cmap} 8 | \usepackage{listings} 9 | \usepackage{color} 10 | 11 | \definecolor{mygreen}{rgb}{0,0.6,0} 12 | \definecolor{mygray}{rgb}{0.5,0.5,0.5} 13 | \definecolor{mymauve}{rgb}{0.58,0,0.82} 14 | 15 | \lstdefinestyle{customc}{ 16 | belowcaptionskip=1\baselineskip, 17 | breaklines=true, 18 | frame=L, 19 | xleftmargin=\parindent, 20 | language=Python, 21 | showstringspaces=false, 22 | basicstyle=\footnotesize\ttfamily, 23 | keywordstyle=\bfseries\color{green!40!black}, 24 | commentstyle=\itshape\color{purple!40!black}, 25 | identifierstyle=\color{blue}, 26 | stringstyle=\color{orange}, 27 | } 28 | 29 | 30 | \newtheorem{defenition}{Определение} 31 | \newtheorem{theorem}{Теорема} 32 | \newtheorem{problem}{Задача} 33 | 34 | \lstset{escapechar=@,style=customc} 35 | 36 | % Так ссылки в PDF будут активны 37 | \usepackage[unicode]{hyperref} 38 | 39 | % вы сможете вставлять картинки командой \includegraphics[width=0.7\textwidth]{ИМЯ ФАЙЛА} 40 | % получается подключать, как минимум, файлы .pdf, .jpg, .png. 41 | \usepackage{graphicx} 42 | % Если вы хотите явно указать поля: 43 | \usepackage[margin=1in]{geometry} 44 | % Или если вы хотите задать поля менее явно (чем больше DIV, тем больше места под текст): 45 | % \usepackage[DIV=10]{typearea} 46 | 47 | \usepackage{fancyhdr} 48 | 49 | \newcommand{\bbR}{\mathbb R}%теперь вместо длинной команды \mathbb R (множество вещественных чисел) можно писать короткую запись \bbR. Вместо \bbR вы можете вписать любую строчку букв, которая начинается с '\'. 50 | \newcommand{\eps}{\varepsilon} 51 | \newcommand{\bbN}{\mathbb N} 52 | \newcommand{\dif}{\mathrm{d}} 53 | 54 | \pagestyle{fancy} 55 | \makeatletter % сделать "@" "буквой", а не "спецсимволом" - можно использовать "служебные" команды, содержащие @ в названии 56 | \fancyhead[L]{\footnotesize Информатика\\ Внимание: конспект не проверялся преподавателями —- всегда используйте рекомендуемую литературу при подготовке к экзамену!}%Это будет написано вверху страницы слева 57 | \fancyhead[R]{} 58 | \fancyfoot[L]{}%имя автора будет написано внизу страницы слева 59 | \fancyfoot[R]{\thepage}%номер страницы —- внизу справа 60 | \fancyfoot[C]{ Замечания и предложения просьба писать на \href{mailto:pulsar@phystech.edu}{pulsar@phystech.edu}}%по центру внизу страницы пусто 61 | 62 | \renewcommand{\maketitle}{% 63 | \noindent{\bfseries\scshape\large\@title\ \mdseries\upshape}\par 64 | \noindent {\large\itshape\@author} 65 | \vskip 2ex} 66 | \makeatother 67 | \def\dd#1#2{\frac{\partial#1}{\partial#2}} 68 | \def\ddd#1#2#3{\frac{\partial^2#1}{\partial#2\partial#3}} 69 | 70 | \title{Автоматы. Машина Тьюринга.} 71 | \author{Тимофей Хирьянов} 72 | \date{12 апреля 2016 г.} 73 | 74 | \begin{document} 75 | \maketitle 76 | \section{Машина Тьюринга} 77 | \begin{defenition} 78 | Машина Тьюринга (МТ) — математическая абстракция, представляющая вычислительную машину общего вида. 79 | \end{defenition} 80 | Была предложена Аланом Тьюрингом в 1936 году для формализации понятия алгоритма. 81 | 82 | Машина Тьюринга является расширением модели конечного автомата и, согласно тезису Чёрча — Тьюринга, способна имитировать (при наличии соответствующей программы) любую машину, действие которой заключается в переходе от одного дискретного состояния к другому. 83 | 84 | В состав Машины Тьюринга входит бесконечная в обе стороны лента, разделённая на ячейки, и управляющее устройство с конечным числом состояний. 85 | 86 | Управляющее устройство может перемещаться влево и вправо по ленте, читать и записывать в ячейки символы некоторого конечного алфавита. Выделяется особый пустой символ, заполняющий все клетки ленты, кроме тех из них (конечного числа), на которых записаны входные данные. 87 | 88 | В управляющем устройстве содержится таблица переходов, которая представляет алгоритм, реализуемый данной Машиной Тьюринга. Каждое правило из таблицы предписывает машине, в зависимости от текущего состояния и наблюдаемого в текущей клетке символа, записать в эту клетку новый символ, перейти в новое состояние и переместиться на одну клетку влево или вправо. Некоторые состояния Машины Тьюринга могут быть помечены как терминальные, и переход в любое из них означает конец работы, остановку алгоритма. 89 | 90 | \section{Конечный автомат} 91 | \begin{defenition} 92 | Конечный автомат — абстрактный автомат, число возможных внутренних состояний которого конечно. 93 | \end{defenition} 94 | Принято полагать, что конечный автомат начинает работу в состоянии $q_0$, последовательно считывая по одному символу входного слова (цепочки входных символов). Считанный символ переводит автомат в новое состояние в соответствии с функцией переходов. 95 | 96 | Читая входную цепочку символов x и делая переходы из состояния в состояние, автомат после прочтения последнего символа входного слова окажется в некотором состоянии $q'$. 97 | 98 | Если это состояние является заключительным, то говорят, что автомат допустил слово x. 99 | 100 | Конечные автоматы широко используются на практике, например, в синтаксических и лексических анализаторах, тестировании программного обеспечения на основе моделей. 101 | 102 | Реализуем алгоритм поиска подстроки <> в строке с помощью конечного автомата. 103 | \lstinputlisting[language=Python]{au.py} 104 | 105 | 106 | 107 | \end{document} 108 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_24/lection_24.out: -------------------------------------------------------------------------------- 1 | \BOOKMARK [1][-]{section.1}{\376\377\004\040\004\065\004\064\004\060\004\072\004\106\004\070\004\076\004\075\004\075\004\076\004\065\000\040\004\100\004\060\004\101\004\101\004\102\004\076\004\117\004\075\004\070\004\065\000\040\004\074\004\065\004\066\004\064\004\103\000\040\004\101\004\102\004\100\004\076\004\072\004\060\004\074\004\070}{}% 1 2 | \BOOKMARK [2][-]{subsection.1.1}{\376\377\004\022\004\070\004\064\004\113\000\040\004\076\004\110\004\070\004\061\004\076\004\072}{section.1}% 2 3 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_24/lection_24.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage{amsmath,amssymb,amsfonts,amsthm} 3 | \usepackage{tikz} 4 | \usepackage [utf8] {inputenc} 5 | \usepackage [T2A] {fontenc} 6 | \usepackage[russian]{babel} 7 | \usepackage{cmap} 8 | \usepackage{listings} 9 | \usepackage{color} 10 | 11 | \definecolor{mygreen}{rgb}{0,0.6,0} 12 | \definecolor{mygray}{rgb}{0.5,0.5,0.5} 13 | \definecolor{mymauve}{rgb}{0.58,0,0.82} 14 | 15 | \lstdefinestyle{customc}{ 16 | belowcaptionskip=1\baselineskip, 17 | breaklines=true, 18 | frame=L, 19 | xleftmargin=\parindent, 20 | language=Python, 21 | showstringspaces=false, 22 | basicstyle=\footnotesize\ttfamily, 23 | keywordstyle=\bfseries\color{green!40!black}, 24 | commentstyle=\itshape\color{purple!40!black}, 25 | identifierstyle=\color{blue}, 26 | stringstyle=\color{orange}, 27 | } 28 | 29 | 30 | \newtheorem{defenition}{Определение} 31 | \newtheorem{theorem}{Теорема} 32 | \newtheorem{problem}{Задача} 33 | 34 | \lstset{escapechar=@,style=customc} 35 | 36 | % Так ссылки в PDF будут активны 37 | \usepackage[unicode]{hyperref} 38 | 39 | % вы сможете вставлять картинки командой \includegraphics[width=0.7\textwidth]{ИМЯ ФАЙЛА} 40 | % получается подключать, как минимум, файлы .pdf, .jpg, .png. 41 | \usepackage{graphicx} 42 | % Если вы хотите явно указать поля: 43 | \usepackage[margin=1in]{geometry} 44 | % Или если вы хотите задать поля менее явно (чем больше DIV, тем больше места под текст): 45 | % \usepackage[DIV=10]{typearea} 46 | 47 | \usepackage{fancyhdr} 48 | 49 | \newcommand{\bbR}{\mathbb R}%теперь вместо длинной команды \mathbb R (множество вещественных чисел) можно писать короткую запись \bbR. Вместо \bbR вы можете вписать любую строчку букв, которая начинается с '\'. 50 | \newcommand{\eps}{\varepsilon} 51 | \newcommand{\bbN}{\mathbb N} 52 | \newcommand{\dif}{\mathrm{d}} 53 | 54 | \pagestyle{fancy} 55 | \makeatletter % сделать "@" "буквой", а не "спецсимволом" - можно использовать "служебные" команды, содержащие @ в названии 56 | \fancyhead[L]{\footnotesize Информатика\\ Внимание: конспект не проверялся преподавателями —- всегда используйте рекомендуемую литературу при подготовке к экзамену!}%Это будет написано вверху страницы слева 57 | \fancyhead[R]{} 58 | \fancyfoot[L]{}%имя автора будет написано внизу страницы слева 59 | \fancyfoot[R]{\thepage}%номер страницы —- внизу справа 60 | \fancyfoot[C]{ Замечания и предложения просьба писать на \href{mailto:pulsar@phystech.edu}{pulsar@phystech.edu}}%по центру внизу страницы пусто 61 | 62 | \renewcommand{\maketitle}{% 63 | \noindent{\bfseries\scshape\large\@title\ \mdseries\upshape}\par 64 | \noindent {\large\itshape\@author} 65 | \vskip 2ex} 66 | \makeatother 67 | \def\dd#1#2{\frac{\partial#1}{\partial#2}} 68 | \def\ddd#1#2#3{\frac{\partial^2#1}{\partial#2\partial#3}} 69 | 70 | \title{Расстояние Левенштейна.} 71 | \author{Тимофей Хирьянов} 72 | \date{19 апреля 2016 г.} 73 | 74 | \begin{document} 75 | \maketitle 76 | \section{Редакционное расстояние между строками} 77 | \subsection{Виды ошибок} 78 | \begin{enumerate} 79 | \item Замена символа 80 | \item Появление лишнего символа 81 | \item Удаление нужного символа 82 | \end{enumerate} 83 | \begin{defenition} 84 | Редакционное расстояние между двумя строками — это минимальное количество операций вставки одного символа, удаления одного символа и замены одного символа на другой, необходимых для превращения одной строки в другую. 85 | \end{defenition} 86 | 87 | $F(i,j)$ --- расстояние Левенштейна для $A[:i]$ и $B[:j]$. 88 | 89 | Очевидно, что $F(0, j)=j=F(j, 0)$. 90 | 91 | $F(i,j) = \begin{cases} 92 | F(i-1, j-1), \quad \text{если}\, A[i-1]=B[j-1] \\ 93 | \begin{cases} 94 | 1+F(i-1, j-1): \quad & \text{Стратегия замены} \\ 95 | 1+F(i-1, j): \quad & \text{Стратегия удаления} \\ 96 | 1+F(i, j-1): \quad & \text{Стратегия добавления} \\ 97 | \end{cases} 98 | \end{cases} 99 | $ 100 | 101 | 102 | 103 | \end{document} 104 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_25/lection_25.out: -------------------------------------------------------------------------------- 1 | \BOOKMARK [1][-]{section.1}{\376\377\004\042\004\065\004\073\004\065\004\063\004\100\004\060\004\104}{}% 1 2 | \BOOKMARK [1][-]{section.2}{\376\377\004\042\004\076\004\077\004\076\004\073\004\076\004\063\004\070\004\117\000\040\004\101\004\065\004\102\004\070}{}% 2 3 | \BOOKMARK [1][-]{section.3}{\376\377\000I\000P\000\040\000v\000.\0004}{}% 3 4 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_25/lection_25.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage{amsmath,amssymb,amsfonts,amsthm} 3 | \usepackage{tikz} 4 | \usepackage [utf8] {inputenc} 5 | \usepackage [T2A] {fontenc} 6 | \usepackage[russian]{babel} 7 | \usepackage{cmap} 8 | \usepackage{listings} 9 | \usepackage{color} 10 | 11 | 12 | \definecolor{mygreen}{rgb}{0,0.6,0} 13 | \definecolor{mygray}{rgb}{0.5,0.5,0.5} 14 | \definecolor{mymauve}{rgb}{0.58,0,0.82} 15 | 16 | \lstdefinestyle{customc}{ 17 | belowcaptionskip=1\baselineskip, 18 | breaklines=true, 19 | frame=L, 20 | xleftmargin=\parindent, 21 | language=Python, 22 | showstringspaces=false, 23 | basicstyle=\footnotesize\ttfamily, 24 | keywordstyle=\bfseries\color{green!40!black}, 25 | commentstyle=\itshape\color{purple!40!black}, 26 | identifierstyle=\color{blue}, 27 | stringstyle=\color{orange}, 28 | } 29 | 30 | 31 | \newtheorem{defenition}{Определение} 32 | \newtheorem{theorem}{Теорема} 33 | \newtheorem{problem}{Задача} 34 | 35 | \lstset{escapechar=@,style=customc} 36 | 37 | % Так ссылки в PDF будут активны 38 | \usepackage[unicode]{hyperref} 39 | 40 | % вы сможете вставлять картинки командой \includegraphics[width=0.7\textwidth]{ИМЯ ФАЙЛА} 41 | % получается подключать, как минимум, файлы .pdf, .jpg, .png. 42 | \usepackage{graphicx} 43 | % Если вы хотите явно указать поля: 44 | \usepackage[margin=1in]{geometry} 45 | % Или если вы хотите задать поля менее явно (чем больше DIV, тем больше места под текст): 46 | % \usepackage[DIV=10]{typearea} 47 | 48 | \usepackage{fancyhdr} 49 | 50 | \newcommand{\bbR}{\mathbb R}%теперь вместо длинной команды \mathbb R (множество вещественных чисел) можно писать короткую запись \bbR. Вместо \bbR вы можете вписать любую строчку букв, которая начинается с '\'. 51 | \newcommand{\eps}{\varepsilon} 52 | \newcommand{\bbN}{\mathbb N} 53 | \newcommand{\dif}{\mathrm{d}} 54 | 55 | \pagestyle{fancy} 56 | \makeatletter % сделать "@" "буквой", а не "спецсимволом" - можно использовать "служебные" команды, содержащие @ в названии 57 | \fancyhead[L]{\footnotesize Информатика\\ Внимание: конспект не проверялся преподавателями —- всегда используйте рекомендуемую литературу при подготовке к экзамену!}%Это будет написано вверху страницы слева 58 | \fancyhead[R]{} 59 | \fancyfoot[L]{}%имя автора будет написано внизу страницы слева 60 | \fancyfoot[R]{\thepage}%номер страницы —- внизу справа 61 | \fancyfoot[C]{ Замечания и предложения просьба писать на \href{mailto:pulsar@phystech.edu}{pulsar@phystech.edu}}%по центру внизу страницы пусто 62 | 63 | \renewcommand{\maketitle}{% 64 | \noindent{\bfseries\scshape\large\@title\ \mdseries\upshape}\par 65 | \noindent {\large\itshape\@author} 66 | \vskip 2ex} 67 | \makeatother 68 | \def\dd#1#2{\frac{\partial#1}{\partial#2}} 69 | \def\ddd#1#2#3{\frac{\partial^2#1}{\partial#2\partial#3}} 70 | 71 | \title{Основы компьютерных сетей} 72 | \author{Тимофей Хирьянов} 73 | \date{26 апреля 2016 г.} 74 | 75 | \begin{document} 76 | \maketitle 77 | \section{Телеграф} 78 | Один из важнейших вопросов современности --- как передавать информацию. Одним из первых способов передачи был телеграф. 79 | Его можно усовершенствовать. 80 | \paragraph{Аппаратный уровень} 81 | \begin{enumerate} 82 | \item Сопоставление 0 и 1. 83 | \item Маркеры начала и конца. 84 | \item Частота дискретизации. 85 | \item Обнаружение коллизии. 86 | \end{enumerate} 87 | Теперь попытаемся добавить еще одного абонента. 88 | \paragraph{Канальный уровень} 89 | \begin{enumerate} 90 | \item Позывные(MAC-адрес или физический адрес) 91 | \item Разбиение большого блока данных на части и сборка обратно. 92 | \item 93 | \end{enumerate} 94 | \section{Топология сети} 95 | \begin{enumerate} 96 | \item Общая шина. 97 | \item Пассивная звезда. Устройство в центре --- hub. 98 | \item Активная звезда. Устройство в центре --- switch. 99 | \item Дерево. 100 | \item Полносвязная топология. 101 | \item Кольцо. 102 | \end{enumerate} 103 | \section{IP v.4} 104 | \begin{defenition} 105 | IP-адрес --- 32-х битное десятичное число. 106 | \end{defenition} 107 | \paragraph{Канальный уровень} 108 | \begin{enumerate} 109 | \item Разрезание потока информации на пакеты. 110 | \item Нумерация и восстановление порядка при получении. 111 | \item Гарантия точности доставки. 112 | \item Протокол передачи данных: какое приложение должно взаимодействовать с пакетом. 113 | \item Количество переданных пакетов. 114 | \end{enumerate} 115 | \end{document} 116 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_26/lection_26.out: -------------------------------------------------------------------------------- 1 | \BOOKMARK [1][-]{section.1}{\376\377\004\043\004\100\004\076\004\062\004\075\004\070\000\040\004\076\004\100\004\063\004\060\004\075\004\070\004\067\004\060\004\106\004\070\004\070\000\040\004\074\004\076\004\064\004\065\004\073\004\070\000\040\000O\000S\000I\000\040\000I\000S\000O\000.}{}% 1 2 | \BOOKMARK [2][-]{subsection.1.1}{\376\377\004\037\004\076\004\073\004\114\004\067\004\076\004\062\004\060\004\102\004\065\004\073\004\114\004\101\004\072\004\070\004\071\000\040\004\103\004\100\004\076\004\062\004\065\004\075\004\114\000\040\000\050\000A\000p\000p\000l\000i\000c\000a\000t\000i\000o\000n\000\040\000L\000a\000y\000e\000r\000\051}{section.1}% 2 3 | \BOOKMARK [2][-]{subsection.1.2}{\376\377\004\037\004\100\004\065\004\064\004\101\004\102\004\060\004\062\004\070\004\102\004\065\004\073\004\114\004\101\004\072\004\070\004\071\000\040\004\103\004\100\004\076\004\062\004\065\004\075\004\114\000\040\000\050\000P\000r\000e\000s\000e\000n\000t\000a\000t\000i\000o\000n\000\040\000L\000a\000y\000e\000r\000\051}{section.1}% 3 4 | \BOOKMARK [2][-]{subsection.1.3}{\376\377\004\041\004\065\004\060\004\075\004\101\004\076\004\062\004\113\004\071\000\040\004\103\004\100\004\076\004\062\004\065\004\075\004\114\000\040\000\050\000s\000e\000s\000s\000i\000o\000n\000\040\000l\000a\000y\000e\000r\000\051}{section.1}% 4 5 | \BOOKMARK [2][-]{subsection.1.4}{\376\377\004\042\004\100\004\060\004\075\004\101\004\077\004\076\004\100\004\102\004\075\004\113\004\071\000\040\004\103\004\100\004\076\004\062\004\065\004\075\004\114\000\040\000\050\000t\000r\000a\000n\000s\000p\000o\000r\000t\000\040\000l\000a\000y\000e\000r\000\051}{section.1}% 5 6 | \BOOKMARK [2][-]{subsection.1.5}{\376\377\004\041\004\065\004\102\004\065\004\062\004\076\004\071\000\040\004\103\004\100\004\076\004\062\004\065\004\075\004\114\000\040\000\050\000N\000e\000t\000w\000o\000r\000k\000\040\000L\000a\000y\000e\000r\000\051}{section.1}% 6 7 | \BOOKMARK [2][-]{subsection.1.6}{\376\377\004\032\004\060\004\075\004\060\004\073\004\114\004\075\004\113\004\071\000\040\004\103\004\100\004\076\004\062\004\065\004\075\004\114\000\040\000\050\000D\000a\000t\000a\000\040\000L\000i\000n\000k\000\040\000l\000a\000y\000e\000r\000\051}{section.1}% 7 8 | \BOOKMARK [2][-]{subsection.1.7}{\376\377\004\044\004\070\004\067\004\070\004\107\004\065\004\101\004\072\004\070\004\071\000\040\004\103\004\100\004\076\004\062\004\065\004\075\004\114\000\040\000\050\000p\000h\000y\000s\000i\000c\000a\000l\000\040\000l\000a\000y\000e\000r\000\051}{section.1}% 8 9 | \BOOKMARK [1][-]{section.2}{\376\377\000D\000H\000C\000P\000-\004\101\004\065\004\100\004\062\004\065\004\100}{}% 9 10 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_26/lection_26.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage{amsmath,amssymb,amsfonts,amsthm} 3 | \usepackage{tikz} 4 | \usepackage [utf8] {inputenc} 5 | \usepackage [T2A] {fontenc} 6 | \usepackage[russian]{babel} 7 | \usepackage{cmap} 8 | \usepackage{listings} 9 | \usepackage{color} 10 | 11 | 12 | \definecolor{mygreen}{rgb}{0,0.6,0} 13 | \definecolor{mygray}{rgb}{0.5,0.5,0.5} 14 | \definecolor{mymauve}{rgb}{0.58,0,0.82} 15 | 16 | \lstdefinestyle{customc}{ 17 | belowcaptionskip=1\baselineskip, 18 | breaklines=true, 19 | frame=L, 20 | xleftmargin=\parindent, 21 | language=Python, 22 | showstringspaces=false, 23 | basicstyle=\footnotesize\ttfamily, 24 | keywordstyle=\bfseries\color{green!40!black}, 25 | commentstyle=\itshape\color{purple!40!black}, 26 | identifierstyle=\color{blue}, 27 | stringstyle=\color{orange}, 28 | } 29 | 30 | 31 | \newtheorem{defenition}{Определение} 32 | \newtheorem{theorem}{Теорема} 33 | \newtheorem{problem}{Задача} 34 | 35 | \lstset{escapechar=@,style=customc} 36 | 37 | % Так ссылки в PDF будут активны 38 | \usepackage[unicode]{hyperref} 39 | 40 | % вы сможете вставлять картинки командой \includegraphics[width=0.7\textwidth]{ИМЯ ФАЙЛА} 41 | % получается подключать, как минимум, файлы .pdf, .jpg, .png. 42 | \usepackage{graphicx} 43 | % Если вы хотите явно указать поля: 44 | \usepackage[margin=1in]{geometry} 45 | % Или если вы хотите задать поля менее явно (чем больше DIV, тем больше места под текст): 46 | % \usepackage[DIV=10]{typearea} 47 | 48 | \usepackage{fancyhdr} 49 | 50 | \newcommand{\bbR}{\mathbb R}%теперь вместо длинной команды \mathbb R (множество вещественных чисел) можно писать короткую запись \bbR. Вместо \bbR вы можете вписать любую строчку букв, которая начинается с '\'. 51 | \newcommand{\eps}{\varepsilon} 52 | \newcommand{\bbN}{\mathbb N} 53 | \newcommand{\dif}{\mathrm{d}} 54 | 55 | \pagestyle{fancy} 56 | \makeatletter % сделать "@" "буквой", а не "спецсимволом" - можно использовать "служебные" команды, содержащие @ в названии 57 | \fancyhead[L]{\footnotesize Информатика\\ Внимание: конспект не проверялся преподавателями —- всегда используйте рекомендуемую литературу при подготовке к экзамену!}%Это будет написано вверху страницы слева 58 | \fancyhead[R]{} 59 | \fancyfoot[L]{}%имя автора будет написано внизу страницы слева 60 | \fancyfoot[R]{\thepage}%номер страницы —- внизу справа 61 | \fancyfoot[C]{ Замечания и предложения просьба писать на \href{mailto:pulsar@phystech.edu}{pulsar@phystech.edu}}%по центру внизу страницы пусто 62 | 63 | \renewcommand{\maketitle}{% 64 | \noindent{\bfseries\scshape\large\@title\ \mdseries\upshape}\par 65 | \noindent {\large\itshape\@author} 66 | \vskip 2ex} 67 | \makeatother 68 | \def\dd#1#2{\frac{\partial#1}{\partial#2}} 69 | \def\ddd#1#2#3{\frac{\partial^2#1}{\partial#2\partial#3}} 70 | 71 | \title{Основы компьютерных сетей. II.} 72 | \author{Тимофей Хирьянов} 73 | \date{26 апреля 2016 г.} 74 | 75 | \begin{document} 76 | \maketitle 77 | \section{Уровни организации модели OSI ISO.} 78 | \subsection{Пользовательский уровень (Application Layer)} 79 | Пользовательский уровень — верхний уровень модели, обеспечивающий взаимодействие пользовательских приложений с сетью. 80 | Примеры:RDP, HTTP, SMTP, SNMP, POP3, FTP, XMPP, OSCAR, Modbus, SIP, TELNET 81 | \subsection{Представительский уровень (Presentation Layer)} 82 | Представительский уровень обеспечивает преобразование протоколов и кодирование/декодирование данных. Запросы приложений, полученные с прикладного уровня, на уровне представления преобразуются в формат для передачи по сети, а полученные из сети данные преобразуются в формат приложений. На этом уровне может осуществляться сжатие/распаковка или шифрование/дешифрование, а также перенаправление запросов другому сетевому ресурсу, если они не могут быть обработаны локально. 83 | 84 | Представительский уровень имеет дело не только с форматами и представлением данных, он также занимается структурами данных, которые используются программами. Таким образом, этот уровень обеспечивает организацию данных при их пересылке. 85 | 86 | Протоколы уровня представления: AFP — Apple Filing Protocol, ICA — Independent Computing Architecture, LPP — Lightweight Presentation Protocol, NCP — NetWare Core Protocol, NDR — Network Data Representation, XDR — eXternal Data Representation, X.25 PAD — Packet Assembler/Disassembler Protocol. 87 | 88 | \subsection{Сеансовый уровень (session layer)} 89 | Сеансовый уровень модели обеспечивает поддержание сеанса связи, позволяя приложениям взаимодействовать между собой длительное время. Уровень управляет созданием/завершением сеанса, обменом информацией, синхронизацией задач, определением права на передачу данных и поддержанием сеанса в периоды неактивности приложений. 90 | 91 | Протоколы сеансового уровня: ADSP (AppleTalk Data Stream Protocol), ASP (AppleTalk Session Protocol), H.245 (Call Control Protocol for Multimedia Communication), ISO-SP (OSI Session Layer Protocol (X.225, ISO 8327)), iSNS (Internet Storage Name Service), L2F (Layer 2 Forwarding Protocol), L2TP (Layer 2 Tunneling Protocol), NetBIOS (Network Basic Input Output System), PAP (Password Authentication Protocol), PPTP (Point-to-Point Tunneling Protocol), RPC (Remote Procedure Call Protocol), RTCP (Real-time Transport Control Protocol), SMPP (Short Message Peer-to-Peer), SCP (Session Control Protocol), ZIP (Zone Information Protocol), SDP (Sockets Direct Protocol). 92 | 93 | \subsection{Транспортный уровень (transport layer)} 94 | Транспортный уровень модели предназначен для обеспечения надёжной передачи данных от отправителя к получателю. При этом уровень надёжности может варьироваться в широких пределах. Существует множество классов протоколов транспортного уровня, начиная от протоколов, предоставляющих только основные транспортные функции (например, функции передачи данных без подтверждения приема), и заканчивая протоколами, которые гарантируют доставку в пункт назначения нескольких пакетов данных в надлежащей последовательности, мультиплексируют несколько потоков данных, обеспечивают механизм управления потоками данных и гарантируют достоверность принятых данных. Например, UDP ограничивается контролем целостности данных в рамках одной датаграммы, и не исключает возможности потери пакета целиком, или дублирования пакетов, нарушение порядка получения пакетов данных; TCP обеспечивает надёжную непрерывную передачу данных, исключающую потерю данных или нарушение порядка их поступления или дублирования, может перераспределять данные, разбивая большие порции данных на фрагменты и наоборот склеивая фрагменты в один пакет. 95 | 96 | Протоколы транспортного уровня: ATP (AppleTalk Transaction Protocol), CUDP (Cyclic UDP), DCCP (Datagram Congestion Control Protocol), FCP (Fiber Channel Protocol), IL (IL Protocol), NBF (NetBIOS Frames protocol), NCP (NetWare Core Protocol), SCTP (Stream Control Transmission Protocol), SPX (Sequenced Packet Exchange), SST (Structured Stream Transport), TCP (Transmission Control Protocol), UDP (User Datagram Protocol). 97 | \subsection{Сетевой уровень (Network Layer)} 98 | Сетевой уровень модели предназначен для определения пути передачи данных. Отвечает за трансляцию логических адресов и имён в физические, определение кратчайших маршрутов, коммутацию и маршрутизацию, отслеживание неполадок и «заторов» в сети. 99 | 100 | Протоколы сетевого уровня маршрутизируют данные от источника к получателю. Работающие на этом уровне устройства (маршрутизаторы) условно называют устройствами третьего уровня (по номеру уровня в модели OSI). 101 | 102 | Протоколы сетевого уровня: IP/IPv4/IPv6 (Internet Protocol), IPX (Internetwork Packet Exchange, протокол межсетевого обмена), X.25 (частично этот протокол реализован на уровне 2), CLNP (сетевой протокол без организации соединений), IPsec (Internet Protocol Security). Протоколы маршрутизации - RIP (Routing Information Protocol), OSPF (Open Shortest Path First). 103 | \subsection{Канальный уровень (Data Link layer)} 104 | Канальный уровень предназначен для обеспечения взаимодействия сетей на физическом уровне и контроля за ошибками, которые могут возникнуть. Полученные с физического уровня данные, представленные в битах, он упаковывает в кадры, проверяет их на целостность и, если нужно, исправляет ошибки (формирует повторный запрос поврежденного кадра) и отправляет на сетевой уровень. Канальный уровень может взаимодействовать с одним или несколькими физическими уровнями, контролируя и управляя этим взаимодействием. 105 | 106 | Спецификация IEEE 802 разделяет этот уровень на два подуровня: MAC (англ. media access control) регулирует доступ к разделяемой физической среде, LLC (англ. logical link control) обеспечивает обслуживание сетевого уровня. 107 | 108 | На этом уровне работают коммутаторы, мосты и другие устройства. Говорят, что эти устройства используют адресацию второго уровня (по номеру уровня в модели OSI). 109 | 110 | Протоколы канального уровня: ARCnet, ATM, Controller Area Network (CAN), Econet, IEEE 802.3 (Ethernet), Ethernet Automatic Protection Switching (EAPS), Fiber Distributed Data Interface (FDDI), Frame Relay, High-Level Data Link Control (HDLC), IEEE 802.2 (provides LLC functions to IEEE 802 MAC layers), Link Access Procedures, D channel (LAPD), IEEE 802.11 wireless LAN, LocalTalk, Multiprotocol Label Switching (MPLS), Point-to-Point Protocol (PPP), Point-to-Point Protocol over Ethernet (PPPoE), Serial Line Internet Protocol (SLIP, устарел), StarLan, Token ring, Unidirectional Link Detection (UDLD), x.25, ARP. 111 | \subsection{Физический уровень (physical layer)} 112 | Физический уровень (англ. physical layer) — нижний уровень модели, который определяет метод передачи данных, представленных в двоичном виде, от одного устройства (компьютера) к другому. Составлением таких методов занимаются разные организации, в том числе: Институт инженеров по электротехнике и электронике, Альянс электронной промышленности, Европейский институт телекоммуникационных стандартов и другие. Осуществляют передачу электрических или оптических сигналов в кабель или в радиоэфир и, соответственно, их приём и преобразование в биты данных в соответствии с методами кодирования цифровых сигналов. 113 | 114 | На этом уровне также работают концентраторы, повторители сигнала и медиаконвертеры. 115 | 116 | Функции физического уровня реализуются на всех устройствах, подключенных к сети. Со стороны компьютера функции физического уровня выполняются сетевым адаптером или последовательным портом. К физическому уровню относятся физические, электрические и механические интерфейсы между двумя системами. Физический уровень определяет такие виды сред передачи данных как оптоволокно, витая пара, коаксиальный кабель, спутниковый канал передач данных и т. п. Стандартными типами сетевых интерфейсов, относящимися к физическому уровню, являются: V.35, RS-232, RS-485, RJ-11, RJ-45, разъемы AUI и BNC. 117 | 118 | Протоколы физического уровня: IEEE 802.15 (Bluetooth), IRDA, EIA RS-232, EIA-422, EIA-423, RS-449, RS-485, DSL, ISDN, SONET/SDH, 802.11 Wi-Fi, Etherloop, GSM Um radio interface, ITU и ITU-T, TransferJet, ARINC 818, G.hn/G.9960. 119 | \section{DHCP-сервер} 120 | DHCP (англ. Dynamic Host Configuration Protocol — протокол динамической настройки узла) — сетевой протокол, позволяющий компьютерам автоматически получать IP-адрес и другие параметры, необходимые для работы в сети TCP/IP. Данный протокол работает по модели «клиент-сервер». Для автоматической конфигурации компьютер-клиент на этапе конфигурации сетевого устройства обращается к так называемому серверу DHCP и получает от него нужные параметры. Сетевой администратор может задать диапазон адресов, распределяемых сервером среди компьютеров. Это позволяет избежать ручной настройки компьютеров сети и уменьшает количество ошибок. Протокол DHCP используется в большинстве сетей TCP/IP. 121 | Протокол DHCP предоставляет три способа распределения IP-адресов: 122 | \begin{enumerate} 123 | \item Ручное распределение. При этом способе сетевой администратор сопоставляет аппаратному адресу (для Ethernet сетей это MAC-адрес) каждого клиентского компьютера определённый IP-адрес. Фактически, данный способ распределения адресов отличается от ручной настройки каждого компьютера лишь тем, что сведения об адресах хранятся централизованно (на сервере DHCP), и потому их проще изменять при необходимости.\\ 124 | \item Автоматическое распределение. При данном способе каждому компьютеру на постоянное использование выделяется произвольный свободный IP-адрес из определённого администратором диапазона. \\ 125 | \item Динамическое распределение. Этот способ аналогичен автоматическому распределению, за исключением того, что адрес выдаётся компьютеру не на постоянное пользование, а на определённый срок. Это называется арендой адреса. По истечении срока аренды IP-адрес вновь считается свободным, и клиент обязан запросить новый (он, впрочем, может оказаться тем же самым). Кроме того, клиент сам может отказаться от полученного адреса. 126 | \end{enumerate} 127 | 128 | \end{document} 129 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_6/lection_6.tex: -------------------------------------------------------------------------------- 1 | % !TeX spellcheck = russian_english 2 | % !TeX encoding = UTF-8 3 | \documentclass[a4paper, fleqn]{article} 4 | 5 | \usepackage{indentfirst} % Красная строка 6 | \usepackage[T2A]{fontenc} % Поддержка русских букв 7 | \usepackage[utf8]{inputenc} % Кодировка utf8 8 | \usepackage[russian]{babel} % руссификация 9 | \usepackage{amssymb} % дополнительные символы 10 | \usepackage{textcomp} % дополнительные текстовые символы 11 | \usepackage{amsmath} % матрицы 12 | \usepackage{listings} 13 | % листинги 14 | \lstset{language=Python, tabsize=4, language=Python} 15 | 16 | 17 | \textwidth = 16 cm 18 | \oddsidemargin= 0 cm 19 | \evensidemargin= 1 cm 20 | 21 | 22 | % \abovedisplayskip = 0 pt %.2\abovedisplayskip 23 | % \belowdisplayskip = .2\belowdisplayskip 24 | % \abovedisplayshortskip=.2\abovedisplayshortskip 25 | % \belowdisplayshortskip=.2\belowdisplayshortskip 26 | % \topsep= 0 pt 27 | 28 | % \setlength{\mathindent}{1.2 cm} 29 | % \setlength{\topsep}{0 pt} 30 | % \setlength{\abovedisplayskip}{0 pt} 31 | 32 | % \clubpenalty = 5000 % запрет висячих строк 33 | % \widowpenalty = 5000 34 | \binoppenalty=10000 35 | \relpenalty=10000 36 | 37 | % собственные команды и окружения 38 | 39 | \newenvironment{example}[1][]{\medskip \noindent \textbf{Пример. #1}\par \nopagebreak}{\medskip \par} % окружение-"пример" 40 | 41 | 42 | \title{Лекция \textnumero\,6} 43 | % {\huge \vspace{3 cm}}} 44 | 45 | \author{Т.\,Ф. Хирьянов} 46 | 47 | \date{} 48 | 49 | \begin{document} 50 | \maketitle 51 | 52 | \subsection*{Структурное программирование} 53 | 54 | Небольшие программы, имеющие порядка ста строк кода, обычно просты в понимании, однако чем больше она становится, тем сложнее уловить ее принцип работы, понять, что обозначает та или иная переменная, найти и исправить ошибку. Именно поэтому код программы должен быть структурирован. 55 | % 5:55 56 | 57 | \subsection*{Базовые принципы структурного программирования} 58 | 59 | % 09:25 60 | \begin{itemize} 61 | \item Программа состоит из 62 | \begin{enumerate} 63 | \item \emph{последовательного исполнения} 64 | \item \emph{ветвлений} 65 | \item \emph{циклов} 66 | \end{enumerate} 67 | \item Повторяющиеся участки кода оформляют в виде \emph{функций} 68 | \item Разработка программы осуществляется пошагово \emph{сверху-вниз} 69 | \end{itemize} 70 | 71 | В качестве иллюстрации можно рассмотреть следующую задачу. На вход поступают строки с автомобильным номерам и величиной скорости, с которой транспортное средство проезжает мимо поста ГИБДД. 72 | 73 | Патрульный останавливает машины, превысившие скорость 60 км/ч, и озвучивает размер взятки, которая зависит от <<привилегированности>> номера: если в номере все три цифры разные, то 100 рублей, если есть две одинаковые, то 200, если три, то 1000. При этом, когда в конце рабочего дня приезжает начальник, его не уличают в превышении скорости, даже если это случилось. Программа должна вывести <<зарплату>> постового за день. 74 | % 75 | \texttt{ 76 | \begin{tabbing} 77 | \hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 78 | A238BE 73 $\longrightarrow$ 100\\ 79 | B202CC 84 $\longrightarrow$ 200\\ 80 | B555PH 71 $\longrightarrow$ 1000\\ 81 | ...\\ 82 | A999AA 100 83 | \end{tabbing} 84 | } 85 | 86 | Приведенный ниже код данной программы написан с соблюдением положений структурного программирования. 87 | % 88 | \texttt{ 89 | \begin{tabbing} 90 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 91 | def solve\_task():\\ 92 | \> print(count\_salary())\\ 93 | \\ 94 | def count\_salary():\\ 95 | \> salary = 0\\ 96 | \> licence\_num, speed = input().split()\\ 97 | \> while not chief(licence\_num):\\ 98 | \> \> if float(speed) > 60:\\ 99 | \> \> \> salary += count\_tax(licence\_num)\\ 100 | \> \> licence\_num, speed = input().split()\\ 101 | \> return salary\\ 102 | \\ 103 | def chief(licence\_num):\\ 104 | \> return licence\_num == "A999AA"\\ 105 | \\ 106 | def count\_tax(licence\_num):\\ 107 | \> return 0 \# FIXME 108 | \end{tabbing} 109 | } 110 | Действительно, в нем код оформлен в функции, имеющие интуитивно понятные названия. Функция \texttt{solve\_task} выводит на экран зарплату. При этом она не подсчитывает ее - это выполняет функция \texttt{count\_salary()}. В последней используется переменная-счетчик \texttt{salary}, значение которой отражает текущий доход. В \texttt{licence\_num} и \texttt{speed} записываются соответственно номер и скорость автомобиля. Пока номера считываются в цикле, происходит анализ того, не принадлежит ли текущий номер начальнику и какой размер взятки запросить. Это осуществляется посредством вызова функций \texttt{chief} и \texttt{count\_tax}. 111 | 112 | Важно отметить, что вместо вызова \texttt{chief} можно было явно прописать в условии \texttt{licence\_num == "A999AA"}, однако от этого бы пострадала ясность и понятность кода. 113 | 114 | На этапе разработки можно лишь объявить некоторые функции, запрограммировав их так, что бы они возвращали корректное, хотя и неверное, значение (как в случае с \texttt{count\_tax}). 115 | % лучше сноской 116 | Для того чтобы впоследствии вернуться к доработке программы удобно пометить необходимые места кода комментарием \texttt{FIXME}. 117 | 118 | % 34:30 119 | Прежде чем начинать программировать, нужно спроектировать программу: определить, как будет осуществляться взаимодействие между функциями(какие данные будут подаваться на вход и что будет возвращаться). Все это лучше всего прописать в текстовой документации к программе, однако предварительно можно просто указать в многострочном комментарии в начале тела функции. Например, таким образом. 120 | % 41:00 121 | % 122 | \texttt{ 123 | \begin{tabbing} 124 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 125 | def count\_tax(licence\_num): \\ 126 | \> """ 2 numbers - 200\\ 127 | \> \> 3 numbers - 1000\\ 128 | \> \> else - 100 """\\ 129 | \> pass 130 | \end{tabbing} 131 | } 132 | % 50:40 133 | % 134 | \subsection*{Стек вызовов} 135 | 136 | Допустим, что существует программа А, в процессе выполнения которой вызывается функция B. В таком случае работа программы А должна быть приостановлена и начато выполнение функции В. При этом по окончании работы последней программа А должна возобновить свою работу с того места, где она была прервана. Для этого необходимо сохранить в стеке \emph{адрес возврата}. 137 | Если теперь уже в процессе выполнения функции В была вызвана функция С, то выполняются аналогичные действия. При этом адрес возврата к В кладется <<сверху>> предыдущего. 138 | 139 | После того, как выполнение функции С подойдет к концу, команда \emph{return} обеспечит возврат к необходимому месту и удалит соответствующий адрес из стека. При этом переменные, которые завела функция С для своей работы являются локальными и по окончании ее работы также удаляются - это важно иметь в виду при проектировании программы. 140 | 141 | % 56:00 142 | \subsection*{Именованные параметры} 143 | 144 | Если при вызове функции один или несколько из передаваемых параметров в большинстве случаев имеют определенные значения, то удобно указать их явно в заголовке функции. Тогда они станут значениями по умолчанию и их можно будет не прописывать, при вызове функции. В приведенной ниже функции, меняющей пробел на другой разделитель \texttt{sep}, указано значение по умолчанию последнего (\texttt{sep='.'}). 145 | % 146 | % 147 | \texttt{ 148 | \begin{tabbing} 149 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 150 | def my\_print(s, sep='.'):\\ 151 | \> res = ''\\ 152 | \> for symbol in s:\\ 153 | \> \> res += symbol + sep\\ 154 | \> print(res)\\ 155 | \\ 156 | my\_print('Hello') 157 | \end{tabbing} 158 | } 159 | Также именованные параметры при вызове можно менять местами. Однако для этого нужно указывать их явно. 160 | % 161 | \texttt{ 162 | \begin{tabbing} 163 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 164 | def f(x, y):\\ 165 | \> return x/y\\ 166 | \\ 167 | f(1, 2) \> \> \> \# f(x=1, y=2)\\ 168 | f(y=1, x=2) 169 | \end{tabbing} 170 | } 171 | В Python существует много \emph{итерируемых объектов}, по элементам которых можно пробегаться в цикле. Например, в приведенной ниже функции \texttt{x} пробегает все значения от нулевого до последнего элемента \texttt{A}, где \texttt{A} может являться как списком, так и строкой. 172 | % 173 | \texttt{ 174 | \begin{tabbing} 175 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 176 | m = 0\\ 177 | for x in A:\\ 178 | \> if x > m:\\ 179 | \> \> m = x 180 | \end{tabbing} 181 | } 182 | В данном примере слово <> будет выведено на экран побуквенно. 183 | % 184 | \texttt{ 185 | \begin{tabbing} 186 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 187 | for symbol in 'Hello':\\ 188 | \> print(symbol) 189 | \end{tabbing} 190 | } 191 | % 1:02:00 192 | \subsection*{Генерация списков} 193 | 194 | В Python есть очень удобная возможность создавать списки с помощью обхода элементов итерируемого объекта. Для этого нужно в квадратных скобках указать следующее.\\ 195 | \texttt{new\_A = [f(x) for x in A]}\\ 196 | где \texttt{f(x)} -- значение, сопоставляемое каждому \texttt{x} из итерируемого объекта \texttt{A}. 197 | 198 | В приведенном ниже примере список В будет содержать квадраты элементов списка \texttt{A}. Более того можно задать определенное условие, при котором элементы попадут в новый список, как при генерации \texttt{C} (попадут только четные). 199 | % 200 | \texttt{ 201 | \begin{tabbing} 202 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 203 | A = [int(x) for x in input().split()]\\ 204 | B = [x**2 for x in A]\\ 205 | C = [x for x in A if x \% 2 == 0] 206 | \end{tabbing} 207 | } 208 | В Python можно создавать и двумерные (и более) списки. В приведенном ниже примере в списке А окажутся два элемента -- списки, содержащие по три элемента. Доступ к элементу и его изменение осуществляется с помощью индексов. 209 | % 210 | \texttt{ 211 | \begin{tabbing} 212 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 213 | A = []\\ 214 | A.append([1, 2, 3])\\ 215 | A.append([4, 5, 6])\\ 216 | \# A[1][2] == 6\\ 217 | A[1][2] == 7 218 | \end{tabbing} 219 | } 220 | Для списков существует операция повторения (*) с синтаксисом \texttt{x = [a]*N} (здесь \texttt{x} будет списком, в котором число а повторено \texttt{N} раз). При этом каждый элемент А будет ссылаться на объект <<а>>. Если же создать список списков так, как показано в примере, то при изменении элемента одного из внутренних списков, соответствующая величина а в других также поменяется. 221 | % 222 | \texttt{ 223 | \begin{tabbing} 224 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 225 | N = int(input())\\ 226 | M = int(input())\\ 227 | A = [0]*N\\ 228 | B = [[0]*N]*M\\ 229 | \end{tabbing} 230 | } 231 | Чтобы избежать данной проблемы удобно использовать генератор вложенных списков, в котором в качестве значения элемента генерируемого списка выступает другой список тоже генерируемый. Например, таким образом можно создать таблицу умножения. 232 | % 233 | \texttt{ 234 | \begin{tabbing} 235 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 236 | A = [[0]*N for i in range(M)]\\ 237 | A = [[i*j for i in range(10)]\\ 238 | \> for j in range(10)] 239 | \end{tabbing} 240 | } 241 | % 242 | \texttt{ 243 | \begin{tabbing} 244 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 245 | A = [[0]*N for i in range(M)]\\ 246 | A = [[4*j + i for i in range(4)] for j in range(3)] 247 | \end{tabbing} 248 | } 249 | Или такого рода таблицу.\\ 250 | 251 | 252 | \begin{tabular}{|c|c|c|c|} 253 | \hline \rule[-2ex]{0pt}{5.5ex} 0& 1& 2& 3\\ 254 | \hline \rule[-2ex]{0pt}{5.5ex} 4& 5& 6& 7\\ 255 | \hline \rule[-2ex]{0pt}{5.5ex} 8& 9& 10& 11\\ 256 | \hline 257 | \end{tabular} 258 | \\ 259 | 260 | Полиморфизм в Python заключается в том, что типы параметров могут быть различны. Главное, чтобы с данными типами корректно работали команды тела функции. 261 | % 262 | \texttt{ 263 | \begin{tabbing} 264 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 265 | def plus(a, b):\\ 266 | return a + b\\ 267 | \\ 268 | plus (1, 2)\\ 269 | plus (1.5, 7.5)\\ 270 | plus ('ab', 'c') 271 | \end{tabbing} 272 | } 273 | % 1:20:00 274 | % 275 | По этой же самой причине список можно использовать вместо логического выражения: если список пуст - это будут интерпретироваться как ложь, иначе -- правда. 276 | \texttt{ 277 | \begin{tabbing} 278 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 279 | A = []\\ 280 | x = input()\\ 281 | while x != '0':\\ 282 | \> A.append(x)\\ 283 | \> x = input()\\ 284 | while A:\\ 285 | \> print(A.pop())\\ 286 | \end{tabbing} 287 | } 288 | 289 | \end{document} 290 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_7/lection_7.tex: -------------------------------------------------------------------------------- 1 | % !TeX spellcheck = russian_english 2 | % !TeX encoding = UTF-8 3 | \documentclass[a4paper, fleqn]{article} 4 | 5 | \usepackage{indentfirst} % Красная строка 6 | \usepackage[T2A]{fontenc} % Поддержка русских букв 7 | \usepackage[utf8]{inputenc} % Кодировка utf8 8 | \usepackage[russian]{babel} % руссификация 9 | \usepackage{amssymb} % дополнительные символы 10 | \usepackage{textcomp} % дополнительные текстовые символы 11 | \usepackage{amsmath} % матрицы 12 | \usepackage{listings} 13 | % листинги 14 | \lstset{language=Python, tabsize=4, language=Python} 15 | 16 | 17 | \textwidth = 16 cm 18 | \oddsidemargin= 0 cm 19 | \evensidemargin= 1 cm 20 | 21 | 22 | % \abovedisplayskip = 0 pt %.2\abovedisplayskip 23 | % \belowdisplayskip = .2\belowdisplayskip 24 | % \abovedisplayshortskip=.2\abovedisplayshortskip 25 | % \belowdisplayshortskip=.2\belowdisplayshortskip 26 | % \topsep= 0 pt 27 | 28 | % \setlength{\mathindent}{1.2 cm} 29 | % \setlength{\topsep}{0 pt} 30 | % \setlength{\abovedisplayskip}{0 pt} 31 | 32 | % \clubpenalty = 5000 % запрет висячих строк 33 | % \widowpenalty = 5000 34 | \binoppenalty=10000 35 | \relpenalty=10000 36 | 37 | % собственные команды и окружения 38 | 39 | \newenvironment{example}[1][]{\medskip \noindent \textbf{Пример. #1}\par \nopagebreak}{\medskip \par} % окружение-"пример" 40 | 41 | 42 | \title{Лекция \textnumero\,7} 43 | % {\huge \vspace{3 cm}}} 44 | 45 | \author{Т.\,Ф. Хирьянов} 46 | 47 | \date{} 48 | 49 | \begin{document} 50 | \maketitle 51 | 52 | \subsection*{Поиск корней функции} 53 | 54 | Данная задача не является тривиальной. Например, для функции 55 | \[f(x) = \sin{\frac{1}{x}}\] 56 | В сколь угодно малой окрестности нуля найдется бесконечное колличество нулей. Более того, в прикладных задачах поведение функции неизвестно, а значит, между любыми двумя точками она может несколько раз пересечь ось абсцисс. Поэтому для решения данной задачи необходимо использовать выводы из математического анализа, а именно лемму о промежуточных значениях непрерывной функции. Из нее следует, что если функция непрерывна на отрезке $[a, b]$, то на нем она обязательно принимает все значения от $f(a)$ до $f(b)$ (при условии, что $f(b) > f(a)$). Поэтому если найден такой отрезок, на котором функция непрерывна и имеет противоположные по знаку значения, то на этом отрезке функция обязательно имеет корень. 57 | % 05:18 58 | 59 | \subsection*{Биссекция} 60 | 61 | % 07:55 62 | Для описанной выше ситуации существует алгоритм, который позволяет сколь угодно точно определить корень функции. Идея алгоритма биссекции заключается в следующем. Вычисляется значение функции в середине отрезка. Если оно равно нулю, то корень найден, если больше либо меньше нуля, то производится сужение отрезка, содержащего корень. Действительно из постановки задачи следует, что $f(a)*f(b) < 0$. Следовательно либо $f(a)*f(c) < 0$, либо $f(c)*f(b) < 0$. Допустим, что верно первое. Тогда нужно заменить правую границу $b$ отрезка $[a, b]$ на с. Получившийся отрезок $[a, c]$ вдвое меньше и удовлетворяет всем условиям задачи, а значит, с ним можно провести такие же действия. Из этого следует, что искомый корень после $n$ таких итераций будет находится, например, в середине текущего отрезка с точностью до половины последнего. Задание необходимой точности обеспечивает выход из цикла. 63 | % мой листинг 64 | %\ttfamily{ 65 | % \begin{tabbing} 66 | % \hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 67 | % 68 | % \end{tabbing} 69 | %} 70 | \texttt{ 71 | \begin{tabbing} 72 | \hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 73 | f\_a = f(a)\\ 74 | f\_b = f(b)\\ 75 | while abs(b - a) > eps*2:\\ 76 | \> c = (a + b)/2\\ 77 | \> f\_c = f(c)\\ 78 | \> if f\_c*f\_a < 0:\\ 79 | \> \> b = c \> \# a = a\\ 80 | \> elif f\_c*f\_a > 0:\\ 81 | \> \> a = c \> \# b = b\\ 82 | \> else:\\ 83 | \> \> break 84 | \end{tabbing} 85 | } 86 | \subsection*{Поиск в списке} 87 | % 17:30 88 | Если производить поиск конкретного значения в неупорядоченном списке, то будет осуществляться последовательный перебор его элементов и количество операций будет сравнимо с $N$. Однако если список упорядочен по неубыванию, то можно воспользоваться аналогом алгоритма поиска корня функции методом деления пополам. 89 | 90 | Сначала задаются значения индексов, ограничивающих индексы элементов списка. Затем в цикле диапазон значений индексов разделяют пополам аналогично предыдущему алгоритму (деление, конечно, целочисленное). Выход из цикла осуществляется, когда диапазон сокращается до одного элемента. 91 | При этом возвращается номер элемента массива наиболее близкого к искомому значению, но превышающего его. Если искомое значение меньше всех элементов, то возвратится ноль, если больше -- N. 92 | % 93 | % 42:00 94 | \texttt{ 95 | \begin{tabbing} 96 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 97 | def upper\_bond(key, A):\\ 98 | \> A = sorted(A)\\ 99 | \> l = -1\\ 100 | \> r = len(A)\\ 101 | \> while r > l + 1:\\ 102 | \> \> m = (l + r)//2\\ 103 | \> \> if A[m] > key:\\ 104 | \> \> \> r = m\\ 105 | \> \> else: \> \> \# A[m] $\leqslant$ key\\ 106 | \> \> \> l = m\\ 107 | \> return r 108 | \end{tabbing} 109 | } 110 | \subsection*{Сортировка списка} 111 | % 48:00 112 | 113 | Для того чтобы отсортировать список (сделать его упорядоченным) существует множество алгоритмов. Одной из самых долгих является 114 | сортировка обезьяны. 115 | 116 | \subsection*{Сортировка обезьяны} 117 | 118 | Для реализации данного алгоритма необходима функция, перемешивающая элементы в массиве. В стандартной библиотеке Python есть такая функция shuffle. Ее можно подключить из модуля random следующим образом. 119 | \texttt{ 120 | \begin{tabbing} 121 | \hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 122 | from random import shuffle 123 | \end{tabbing} 124 | } 125 | Описанная ниже функция \texttt{monkey\_sort} перемешивает список, пока он не станет отсортированным. 126 | \texttt{ 127 | \begin{tabbing} 128 | \hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 129 | def monkey\_sort(A):\\ 130 | \> while not is\_sorted(A):\\ 131 | \> \> shuffle(A) 132 | \end{tabbing} 133 | } 134 | При этом вызывается функция \texttt{is\_sorted}, проверяющая, является ли текущий список упорядоченным. 135 | \texttt{ 136 | \begin{tabbing} 137 | \hspace{8mm}\=\hspace{8mm}\=\hspace{4cm}\=\kill 138 | def is\_sorted(A):\\ 139 | \> return A == sorted(A)\\ 140 | \end{tabbing} 141 | } 142 | Так как количество перестановок $n$ элементов равно $n!$, то количество операций пропорционально $n!$. 143 | 144 | \subsection*{Сортировка вставками} 145 | 146 | % 54:35 147 | Существует гораздо более быстрые алгоритмы. Одним из них является алгоритм сортировки вставками. 148 | В нем последовательно пробегаются все элементы, правее крайнего левого. Каждый следующий элемент вставляется в уже отсортированную часть списка, расположенную левее, причем так, чтобы упорядоченность сохранилась. В приведенном ниже примере использован циклический сдвиг, и соответствующая сложность алгоритма пропорциональна $N^2$. Однако алгоритм можно улучшить, если использовать рассмотренную ранее функцию upper\_bond для поиска места, в которое необходимо переставить текущий элемент. 149 | % 150 | %1:05:00 151 | \texttt{ 152 | \begin{tabbing} 153 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 154 | def insertion\_sort(A):\\ 155 | \> for i in range(1, len(A)):\\ 156 | \> \> new\_elem = A[i]\\ 157 | \> \> j = i - 1\\ 158 | \> \> while j >= 0 and A[j] > new\_elem:\\ 159 | \> \> \> A[j + 1] = A[j] \> \# сдвиг\\ 160 | \> \> \> j -= 1\\ 161 | \> \> A[j + 1] = new\_elem 162 | \end{tabbing} 163 | } 164 | Однако алгоритм можно улучшить, если использовать рассмотренную ранее функцию upper\_bond для поиска места, в которое необходимо переставить текущий элемент. 165 | 166 | \end{document} 167 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_8/lection_8.tex: -------------------------------------------------------------------------------- 1 | % !TeX spellcheck = russian_english 2 | % !TeX encoding = UTF-8 3 | \documentclass[a4paper, fleqn]{article} 4 | 5 | \usepackage{indentfirst} % Красная строка 6 | \usepackage[T2A]{fontenc} % Поддержка русских букв 7 | \usepackage[utf8]{inputenc} % Кодировка utf8 8 | \usepackage[russian]{babel} % руссификация 9 | \usepackage{amssymb} % дополнительные символы 10 | \usepackage{textcomp} % дополнительные текстовые символы 11 | \usepackage{amsmath} % матрицы 12 | \usepackage{listings} 13 | % листинги 14 | \lstset{language=Python, tabsize=4, language=Python} 15 | 16 | 17 | \textwidth = 16 cm 18 | \oddsidemargin= 0 cm 19 | \evensidemargin= 1 cm 20 | 21 | 22 | % \abovedisplayskip = 0 pt %.2\abovedisplayskip 23 | % \belowdisplayskip = .2\belowdisplayskip 24 | % \abovedisplayshortskip=.2\abovedisplayshortskip 25 | % \belowdisplayshortskip=.2\belowdisplayshortskip 26 | % \topsep= 0 pt 27 | 28 | % \setlength{\mathindent}{1.2 cm} 29 | % \setlength{\topsep}{0 pt} 30 | % \setlength{\abovedisplayskip}{0 pt} 31 | 32 | % \clubpenalty = 5000 % запрет висячих строк 33 | % \widowpenalty = 5000 34 | \binoppenalty=10000 35 | \relpenalty=10000 36 | 37 | % собственные команды и окружения 38 | 39 | \newenvironment{example}[1][]{\medskip \noindent \textbf{Пример. #1}\par \nopagebreak}{\medskip \par} % окружение-"пример" 40 | 41 | 42 | \title{Лекция \textnumero\,8} 43 | % {\huge \vspace{3 cm}}} 44 | 45 | \author{Т.\,Ф. Хирьянов} 46 | 47 | \date{} 48 | 49 | \begin{document} 50 | \maketitle 51 | 52 | \subsection*{Сортировка выбором} 53 | 54 | Рассмотренная ранее сортировка вставками может быть удобна, когда имеется необходимость сортировать некоторый массив элементов по мере его наполнения. В сортировке выбором на каждом этапе ищется тот элемент, который должен стоять н текущей позиции в отсортированном списке. Т.е. сперва находиться наименьший элемент и ставится в начало списка. Затем будет осуществляться поиск больших чисел; при этом они займут сразу правильные места и до конца сортировки переставляться не будут, в отличие от сортировки выбором. 55 | 56 | Реализация данного алгоритма выглядит следующим образом. В цикле пробегаются все позиции кроме последней (когда n - 1 элементов будут отсортированы, очевидно, оставшийся элемент будет находиться на нужном месте). Для каждой позиции ищется наименьший элемент из всех оставшихся правее элементов, включая последний. Если среди них найдется число, меньшее элемента на текущей позиции, то они меняются местами. Таким образом к моменту выхода из внешнего цикла список будет отсортирован. Сложность данного алгоритма составляет $O(n^2)$. 57 | \texttt{ 58 | \begin{tabbing} 59 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 60 | for pos in range(N - 1):\\ 61 | \> for i in range(pos + 1, N):\\ 62 | \> \> if A[i] < A[pos]:\\ 63 | \> \> \> tmp = A[i]\\ 64 | \> \> \> A[i] = A[pos]\\ 65 | \> \> \> A[pos] = tmp 66 | \end{tabbing} 67 | } 68 | 69 | \subsection*{Сортировка методом пузырька} 70 | 71 | Существуют структуры данных, в которых доступ до i-ого элемента происходит за не менее i шагов. В таком случае неудобно сравнивать далеко стоящие элементы. Можно осуществить проход списка, сравнивая соседние элементы и упорядочивая их в пределах каждой пары. По окончании прохода максимальный элемент окажется в крайней правой позиции, т.е. будет отсортирован. Применяя аналогичный алгоритм к оставшимся элементам, осуществляется сортировка всего списка. 72 | 73 | Для реализации данного алгоритма заведем переменную prohod, показывающую, что на каждой итерации нужно пробежать N - prohod элементов, начиная с крайнего левого. Так как на первом проходе осуществляется N - 1 сравнений, то удобно организовать проходы с помощью цикла от 1 до N не включая последнего. Если какая-то сравниваемая пара неупорядоченна, то элементы в ней меняются местами. Как и в предыдущем примере сложность данного алгоритма составляет $O(n^2)$. 74 | \texttt{ 75 | \begin{tabbing} 76 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 77 | for prohod in range(1, N):\\ 78 | \> for i in range(N - prohod):\\ 79 | \> \> if A[i] > A[i + 1]:\\ 80 | \> \> \> tmp = A[i]\\ 81 | \> \> \> A[i] = A[i + 1]\\ 82 | \> \> \> A[i + 1] = tmp 83 | \end{tabbing} 84 | } 85 | 86 | \subsection*{Сортировка дурака} 87 | 88 | В плохих случаях имеет асимптотику $O(N^3)$. 89 | % 20:00 90 | \texttt{ 91 | \begin{tabbing} 92 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 93 | i = 0\\ 94 | while i < N - 1:\\ 95 | \> if A[i] < A[i + 1]:\\ 96 | \> \> i += 1\\ 97 | \> else:\\ 98 | \> \> tmp = A[i]\\ 99 | \> \> A[i] = A[i - 1]\\ 100 | \> \> A[i + 1] = tmp\\ 101 | \> \> i = 0 102 | \end{tabbing} 103 | } 104 | 105 | \subsection*{Сортировка подсчетом} 106 | 107 | Допустим, что необходимо отсортировать следующие элементы. 108 | \[1 ~2 ~3 ~2 ~2 ~0 ~7 ~6 ~5 ~2 ~3 ~8 ~8 ~1 ~1 ~2 ~3 ~0 ~9 ~8 ~8 ~7 ~6 ~3 ~2\] 109 | 110 | С помощью метода пузырька или другими описанными ранее методами на решение данной задачи уйдет около $25^2 \gtrsim 600$ шагов. Однако можно заметить, что следующий массив содержит не больше 10 различных элементов, каждый из которых представляет небольшое неотрицательное число. Используя дополнительный массив счетчиков frequency можно понизить сложность сортировки до $O(N)$. Считывая в цикле элементы от 0 до 9, будем обновлять в массиве frequency частоту их вхождений. После этого останется только вывести эти элементы в порядке неубывания столько раз, сколько каждый элемент входил в исходный список. 111 | % 33:00 112 | \texttt{ 113 | \begin{tabbing} 114 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 115 | frequency = [0]*10\\ 116 | digit = int(input())\\ 117 | while 0 <= digit <= 9:\\ 118 | \> frequency[digit] += 1\\ 119 | \> digit = int(input())\\ 120 | for digit in range(10):\\ 121 | \> print(*[digit]*frequency[digit], end=' ') 122 | \end{tabbing} 123 | } 124 | 125 | Однако данный алгоритм будет работать очень долго, если среди возможных чисел будут очень большие. Например, пусть требуется упорядочить всего четыре числа. 126 | \[7 ~1 ~512 ~1875514852\] 127 | 128 | Используя сортировку подсчетом, потребуется обнулить более чем миллиард элементов массива frequency, на что уйдет приблизительно столько же операций. К тому же потребуется внушительный размер дополнительно используемой памяти. 129 | 130 | \subsection*{Поразрядная сортировка} 131 | 132 | Данная сортировка применима только для целых чисел или коротких строк и имеет линейную асимптотику $O(N\cdot M)$, где M -- характерный размер сортируемых чисел. Для больших чисел асимптотика ухудшается. 133 | 134 | Допустим нужно упорядочить следующие числа. 135 | \[ 753 ~58 ~236 ~200 ~18 ~211 ~214 ~758 ~812 ~7\] 136 | 137 | Начнем сортировать числа по их младшим разрядам, т.е. по их последним цифрам. Тогда получим список, в котором числа, отличаются только последней цифрой, будут упорядоченны друг относительно друга (например, 211 и 214, 753 и 758). 138 | \[200 ~211 ~812 ~753 ~214 ~236 ~7 ~58 ~18 ~758\] 139 | 140 | Аналогично сортируя числа по всем остальным разрядам, получим упорядоченный список. 141 | 142 | Для реализации данного алгоритма определим максимальную длину числа, входящего в список. Пробегаясь по всем разрядам до максимального (в десятичной системе счисления), произведем сортировку, аналогично тому, как показано выше. 143 | \texttt{ 144 | \begin{tabbing} 145 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 146 | A = [int(x) for x in input().split()]\\ 147 | max\_num\_len = max([len(str(x)) for x in A])\\ 148 | for radix in range(0, max\_num\_len):\\ 149 | \> B = [[] for i in range(10)]\\ 150 | \> for x in A:\\ 151 | \> \> digit = (x // (10 ** radix)) \% 10\\ 152 | \> \> B[digit].append(x)\\ 153 | \> \> A[:] = []\\% что делает эта строка? 154 | \> for digit in range(10):\\ 155 | \> A += B[digit] 156 | \end{tabbing} 157 | } 158 | 159 | \subsubsection*{Проверка типа входных данных} 160 | 161 | \texttt{ 162 | \begin{tabbing} 163 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 164 | def sort\_number(A):\\ 165 | \> assert(type(A[0]) == 'class') 166 | \end{tabbing} 167 | } 168 | 169 | \end{document} 170 | -------------------------------------------------------------------------------- /2015-2016_lections/lection_9/lection_9.tex: -------------------------------------------------------------------------------- 1 | % !TeX spellcheck = russian_english 2 | % !TeX encoding = UTF-8 3 | \documentclass[a4paper, fleqn]{article} 4 | 5 | \usepackage{indentfirst} % Красная строка 6 | \usepackage[T2A]{fontenc} % Поддержка русских букв 7 | \usepackage[utf8]{inputenc} % Кодировка utf8 8 | \usepackage[russian]{babel} % руссификация 9 | \usepackage{amssymb} % дополнительные символы 10 | \usepackage{textcomp} % дополнительные текстовые символы 11 | \usepackage{amsmath} % матрицы 12 | \usepackage{listings} 13 | % листинги 14 | \lstset{language=Python, tabsize=4, language=Python} 15 | 16 | 17 | \textwidth = 16 cm 18 | \oddsidemargin= 0 cm 19 | \evensidemargin= 1 cm 20 | 21 | 22 | % \abovedisplayskip = 0 pt %.2\abovedisplayskip 23 | % \belowdisplayskip = .2\belowdisplayskip 24 | % \abovedisplayshortskip=.2\abovedisplayshortskip 25 | % \belowdisplayshortskip=.2\belowdisplayshortskip 26 | % \topsep= 0 pt 27 | 28 | % \setlength{\mathindent}{1.2 cm} 29 | % \setlength{\topsep}{0 pt} 30 | % \setlength{\abovedisplayskip}{0 pt} 31 | 32 | % \clubpenalty = 5000 % запрет висячих строк 33 | % \widowpenalty = 5000 34 | \binoppenalty=10000 35 | \relpenalty=10000 36 | 37 | % собственные команды и окружения 38 | 39 | \newenvironment{example}[1][]{\medskip \noindent \textbf{Пример. #1}\par \nopagebreak}{\medskip \par} % окружение-"пример" 40 | 41 | 42 | \title{Лекция \textnumero\,9} 43 | % {\huge \vspace{3 cm}}} 44 | 45 | \author{Т.\,Ф. Хирьянов} 46 | 47 | \date{} 48 | 49 | \begin{document} 50 | \maketitle 51 | 52 | \section*{Рекурсия} 53 | 54 | Когда при выполнении функции вызывается еще одна функция, происходит запоминание места, откуда совершается переход. После завершения работы этой <<внутренней>> функции осуществляется воврат к этому месту. Поэтому нет никаких проблем для функции вызвать саму себя. Такой подход называется \emph{рекурсией}. 55 | 56 | При этом объекты, на которые ссылаются локальные переменные <<вызывающей>> функции~$f$ не совпадают с объектами, на которые ссылаются локальные переменные <<вызванной>> функции~$f$. Тем самым, при вызове еще одной функции~$f$ происходит создание нового \emph{пространства имен}, и благодаря этому сборщик мусора не удаляет объекты, созданные при предыдущих вызовах функции~$f$. 57 | 58 | Пример рекурсивного решения находит свое отражение в сказке о репе. У героя этой сказки деда возникла задача вытянуть репу из земли. Однако его усилий оказалось недостаточно, и он позвал на подмогу бабку. В двоем они также не смогли вытащить репу, и поэтому бабка позвала внучку. Аналогично внучка позвала собачку, собачка -- кошку, кошка -- мышку. Только после этого их совместных усилий хватило для того, чтобы вытащить репу. Данная сказка иллюстрирует один важный момент: чтобы рекурсия не была бесконечной необходимо, чтобы существовал \emph{крайний случай} (в данном случае помощь мыши). При этом по мере спуска вглубь рекурсии задача упрощается (недостаток сил для того, чтобы вытащить репу, уменьшается). 59 | Данный уровень погружения называется \emph{глубиной рекурсии}. 60 | 61 | \subsubsection*{Создание матрешки} 62 | % 09:00 63 | Хорошей иллюстрацией рекурсии может быть функция имитирующая создание матрешки \texttt{make\_ matroska}. В качестве аргументов в нее передаются размер матрешки \texttt{size} и количество матрешек \texttt{number}, которое требуется создать. 64 | Сначала создается (печатается) нижняя половина матрешки. Затем инициируется создание вложенной матрешки. Т.е. осуществляется рекурсивный вызов. Для того чтобы рекурсия не была бесконечной, необходимо в начале выполнения тела функции проверить, нужно ли еще создавать матрешки (\texttt{if number > 1}). Когда это условие не выполнится, выведется сообщение о создании наименьшей в данном случае матрешки. 65 | После этого будет осуществляться возврат к месту предыдущего вызова и завершаться выполнение тела функции -- создаваться (печататься) верхняя половина матрешки. 66 | % 18:00 67 | \texttt{ 68 | \begin{tabbing} 69 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 70 | def make\_matroska(size, number):\\ 71 | \> if number > 1:\\ 72 | \> \> print('низ размера', size)\\ 73 | \> \> make\_matroska(size - 1, number - 1)\\ 74 | \> \> print('верх размера', size)\\ 75 | \> else:\\ 76 | \> \> print('матрешечка размера', size)\\ 77 | \end{tabbing} 78 | } 79 | При этом внутри тела функции можно выделить два участка: до рекурсивного вызова и после. Первая часть называется \emph{прямым ходом рекурсии}, вторая -- \emph{обратным}. 80 | 81 | \subsection*{Поиск НОД. Алгоритм Евклида} 82 | 83 | % 21:00 84 | Рекурсия хорошо применяется при реализации алгоритма Евклида для поиска наибольшего общего делителя. Суть его заключается в том, что если $a$ и $b$ делятся на некоторое число, то и остаток от деления $a$ на $b$ также делится на это число. Благодаря этому можно переходить к исследованию делимости меньших чисел и рекурсивно применять к ним данный алгоритм, пока аналогичный остаток не станет равным нулю. 85 | % 24:50 86 | \texttt{ 87 | \begin{tabbing} 88 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 89 | def my\_gcd(a, b):\\ 90 | \> if b == 0:\\ 91 | \> \> return a\\ 92 | \> else:\\ 93 | \> \> return my\_gcd(b, a\%b)\\ 94 | \end{tabbing} 95 | } 96 | \subsection*{Факториал} 97 | 98 | % 26:30 99 | Примером неуместного использования рекурсии является реализация алгоритма нахождения факториала натурального числа, несмотря на то, что код выглядит очень лаконичным (особенно с использованием тернарного оператора). 100 | % 27:40 101 | \texttt{ 102 | \begin{tabbing} 103 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 104 | def factor(n):\\ 105 | \> return 1 if n == 0 else factor(n - 1)*n\\ 106 | \end{tabbing} 107 | } 108 | Тем самым размер используемой памяти растет пропорционально количеству вызовов $n$. При больших $n$ это может стать существенной проблемой. 109 | 110 | \subsection*{Числа Фибоначчи} 111 | 112 | % 00:00 113 | Другим <<плохим>> примером может служить рекурсивная функция вычисления числа Фибоначчи. 114 | % 01:50 115 | \texttt{ 116 | \begin{tabbing} 117 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 118 | def fib(n):\\ 119 | \> if n < 2:\\ 120 | \> \> return n\\ 121 | \> else:\\ 122 | \> \> return fib(n - 1) + fib(n - 2) 123 | \end{tabbing} 124 | } 125 | Несложно заметить, что данная функция вызывается избыточное количество раз. Действительно, \texttt{fib(n - 2)} будет определенно при еще вычислении \texttt{fib(n - 1)}. С ростом количества вызовов $n$ количество операций будет увеличиваться пропорционально $2^n$. 126 | 127 | \subsection*{Быстрое возведение в степень} 128 | 129 | % 07:00 130 | Операция возведения в степень может быть записана следующим образом. 131 | 132 | \begin{tabular}{rl} 133 | $a^n = $ & $\left\{ 134 | \begin{tabular}{l} 135 | $1,~\text{при}~n = 0$\\ 136 | $a\cdot a^{n - 1},~\text{при}~n \neq 0~\text{и}~n~ \text{нечетное}$\\ 137 | $(a^2)^{n/2},~\text{при}~n \neq 0~\text{и}~n~\text{четное}$\\ 138 | \end{tabular} \right. $ \\ 139 | \end{tabular} 140 | 141 | Последняя строчка дает возможность сократить количество этапов вдвое при рекурсивном вызове, если $n$ -- четное число. В случае, если $n$ степень двух, количество операций пропорционально $\log_2{n}$. 142 | % 11:50 143 | \texttt{ 144 | \begin{tabbing} 145 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 146 | def fast\_power(a, n):\\ 147 | \> if n == 0:\\ 148 | \> \> return 1\\ 149 | \> elif n\%2 == 1:\\ 150 | \> \> return a*fast\_power(a, n - 1)\\ 151 | \> else: \> \> \# n\%2 == 0\\ 152 | \> \> return fast\_power(a*a, n//2)\\ 153 | \end{tabbing} 154 | } 155 | \subsection*{Ханойские башни} 156 | 157 | % 13:00 158 | В качестве примера удачного применения рекурсии удобно рассмотреть задачу о Ханойских башнях. Ее суть заключается в том, что необходимо переложить пирамидку, составленную из блинов разной величины, на другой стержень. При этом за один ход можно перекладывать только один блин, причем так, что бы больший блин не лежал на меньшем, т.е. на каждом стержне находились <<правильные>> пирамидки. 159 | 160 | В приведенном ниже решении пирамидку из $n$ блинов перекладывают с $i$ на $j$ стержень. Крайним случаем является пирамидка из одного блина -- тогда решение тривиально. Он совпадает со случаем, когда остался только один не переложенный блин. Если допустить, что существует решение этой задачи для пирамидки из $n - 1$ звеньев, то легко найти решение и для необходимой пирамидки. Действительно, нужно переставить пирамидку из $n - 1$ звеньев на дополнительный свободный стержень, оставшийся самый большой блин переложить на нужный стержень и затем переставить остальные звенья поверх него. 161 | При этом задача перекладывания меньшей пирамидки аналогична исходной, поэтому удобно для данного действия вызвать ту же функцию, изменив, конечно, параметры. В приведенном ниже примере кода <<перекладывание>> заключается в распечатывании соответствующей строки. 162 | % 21:50 163 | \texttt{ 164 | \begin{tabbing} 165 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 166 | def hanoi(n, i=1, j=2):\\ 167 | \> if n == 1:\\ 168 | \> \> print('переставить 1', 'блин с', i, 'на', j, 'стержень')\\ 169 | \> else:\\ 170 | \> \> hanoi(n - 1, i, 6 - i - j)\\ 171 | \> \> print('переставить', n, 'блин', n - 1, i, 'на', j, 'стержень')\\ 172 | \> \> hanoi(n - 1, 6 - i - j, j)\\ 173 | \end{tabbing} 174 | } 175 | \subsection*{Генерация комбинаторных объектов} 176 | 177 | % 23:30 178 | \subsubsection*{Генерация двоичных чисел} 179 | 180 | Для генерации двоичных чисел удобно заполнять строчку нулями и единицами с помощью рекурсивного вызова и выводить двоичное число в крайнем для рекурсии случае. В приведенной ниже функции \texttt{bin\_gen} на вход подаются количество цифр в числе \texttt{n} и строка \texttt{prefix}, в которую будет записываться часть генерируемого числа и которая будет передаваться каждой новой функции. Она необходима, так как число <<собирается>>, удлиняясь при каждом новом вызове. Для обработки крайнего случая отдельно рассмотрена ситуация, когда n равно нулю. Если же это не так, то, удостоверившись, что n неотрицательно, осуществляется <<сборка>> числа по двум направлениям: в одном случае цифра с номером n будет равна 1, во втором -- 0. Очевидно, что рекурсия достигнет крайнего случая, и программа напечатает ровно $2^n$ чисел. 181 | % 28:00 182 | \texttt{ 183 | \begin{tabbing} 184 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 185 | def bin\_gen(n, prefix = ''):\\ 186 | \> if n == 0:\\ 187 | \> \> print(prefix)\\ 188 | \> else:\\ 189 | \> \> assert(n > 0)\\ 190 | \> \> bin\_gen(n - 1, prefix + '0')\\ 191 | \> \> bin\_gen(n - 1, prefix + '1')\\ 192 | \end{tabbing} 193 | } 194 | \subsubsection*{Генерация перестановок в списке} 195 | 196 | % 30:00 197 | Еще одним примером использования рекурсии может служить генерация всех возможных перестановок в списке. Для простоты пусть элементы списка -- это целые числа от 1 до n + 1. Список с перестановкой будет <<собираться>> по аналогии с предыдущим примером. Когда длина списка станет равной n (крайний случай), элементы списка будут выведены на экран с помощью \texttt{print(*A)}. Для того чтобы сгенерировать все перестановки рекурсивный вызов осуществляется в цикле, в котором пробегаются необходимые элементы. Чтобы последние не повторялись используется проверка на то, входит ли текущий элемент в частично созданный список. 198 | % 34:40 199 | \texttt{ 200 | \begin{tabbing} 201 | \hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{8mm}\=\hspace{3cm}\=\kill 202 | def perestanov\_gen(n, A=[])\\ 203 | \> if len(A) == n:\\ 204 | \> \> print(*A)\\ 205 | \> else:\\ 206 | \> \> for x in range(1, n + 1):\\ 207 | \> \> \> if x not in A:\\ 208 | \> \> \> \> perestanov\_gen(n, A + [x])\\ 209 | \end{tabbing} 210 | } 211 | Стоит отметить, что количество вызовов такой функции будет крайне велико и важно не допустить достижения максимальной глубины рекурсии, разрешенной в Python. 212 | \end{document} 213 | -------------------------------------------------------------------------------- /DBMP_MIPT-2016-2017/Figures/Pic.md: -------------------------------------------------------------------------------- 1 | Рисунки к лекциям 2 | 3 | Формат подписи: Pic_(номер лекци)_(номер секции)_(номер рисунка) 4 | 5 | Требования к формату файлов: .svg + экспортированный .pdf 6 | 7 | Софт: InkScape 8 | -------------------------------------------------------------------------------- /DBMP_MIPT-2016-2017/Lecture_Notes/README.md: -------------------------------------------------------------------------------- 1 | Последняя версия лекций в PDF 2 | -------------------------------------------------------------------------------- /DBMP_MIPT-2016-2017/Tex_Source/Lecture_1: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage[T2A]{fontenc} 3 | \usepackage[utf8]{inputenc} 4 | \usepackage[english,russian]{babel} 5 | \usepackage{amsmath,amssymb,amsthm,mathtools} 6 | \usepackage{euscript,mathrsfs} 7 | \usepackage{icomma} 8 | \usepackage{graphicx} 9 | \usepackage{wrapfig} 10 | \usepackage{indentfirst} 11 | \usepackage{wasysym} 12 | \usepackage{geometry} 13 | 14 | \title{Лекция №1 \\ 15 | {\bf \Huge Основы архитектуры компьютера}} 16 | \date{\today} 17 | 18 | \begin{document} 19 | 20 | \maketitle 21 | 22 | \newpage 23 | 24 | \section{История развития} 25 | 26 | История развития ЭВМ уходит глубоко к истокам человечества, однако наибольший прогресс был в последние века. 27 | 28 | Кратко историю можно описать такой схемой: 29 | 30 | \begin{description} 31 | \item[-1] 32 | \item[0] Электрические ЭВМ (Конрад Цузе)(машина Z1)(релейные компьютеры) 33 | \item[1] Ламповые ЭВМ, их главный недостаток: невысокая надежность и большие размеры 34 | \item[2] Транзисторные ЭВМ 35 | \item[3] ЭВМ на интегральных схемах 36 | \item[4] ЭВМ на сверхбольших интегральных схемах ($=$чип, микропроцессор) 37 | \end{description} 38 | 39 | Здесь цифры показывают ''поколения''. Переходы $1\rightarrow2\rightarrow3\rightarrow$ сопровождаются \emph{уменьшением} размеров. 40 | 41 | \newpage 42 | 43 | \section{Принципы фон Неймана} 44 | 45 | Полная статья: {\it Von Neumann, J., & Godfrey, M. D. (1993). First Draft of a Report on the EDVAC. IEEE Annals of the History of Computing, 15(4), 27-75.} 46 | 47 | Принципы фон Неймана описывают то как именно должна быть ЭВМ. Джон опередил свое время, описав эти принципы. 48 | 49 | Кратко принципы таковы: 50 | 51 | \begin{enumerate} 52 | \item Программируемость (выполнение последовательности действий) 53 | \item Принцип двоичности: данные в двоичной системе \& существует машинный код (англ. \emph{binary code}) 54 | \item Однородность памяти (данные и машинный код лежат в одном устройстве памяти 55 | \begin{description} 56 | \item[\bf{!!!}] Есть и другая архитектура, так называемая \emph{гарвардскаая архитектура}, где машиннный код и данные лежат в разных областях (т.е. устройствах), это гарантирует чуть больше надежности. 57 | \end{description} 58 | \item Память произвольного доступа, т.е. единое адресное пространство ОЗУ (англ. \emph{RAM, random access memory}) 59 | \item Последовательное программное управление, минимальная адресная ячейка$=$байт 60 | \begin{description} 61 | \item[\bf{!!!}] Команда не весит один байт, иначе было бы только $2^8=256$ команд 62 | \end{description} 63 | \item Необходимость условного перехода 64 | \end{enumerate} 65 | 66 | \section{Как это реализовано?} 67 | 68 | \section{Взаимодействие человека и ЭВМ} 69 | 70 | \end{document} 71 | -------------------------------------------------------------------------------- /DBMP_MIPT-2016-2017/Tex_Source/Tex_files.md: -------------------------------------------------------------------------------- 1 | Здесь собраны .tex файлы лекций 2016-2017 года 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | LATEX=pdflatex 2 | LATEXOPTS=--halt-on-error --shell-escape --file-line-error --interaction=nonstopmode 3 | 4 | PDFS := $(patsubst %,%.pdf,$(shell find -maxdepth 1 -name 'lection*' -type d)) 5 | 6 | default: all 7 | 8 | all: $(PDFS) 9 | stat $(PDFS) 10 | 11 | .SECONDEXPANSION: 12 | %.pdf: PDFNAME = $(basename $@) 13 | %.pdf: PDFPREREQ = $(PDFNAME)/$(PDFNAME).tex 14 | 15 | %.pdf: $$(PDFPREREQ) 16 | cd $$( dirname $< ); \ 17 | $(LATEX) $(LATEXOPTS) $$( basename $< ); \ 18 | $(LATEX) $(LATEXOPTS) $$( basename $< ); \ 19 | $(LATEX) $(LATEXOPTS) $$( basename $< ); \ 20 | mv $$( basename $< .tex ).pdf ..; cd - 21 | 22 | clean: 23 | rm -f $(PDFS) */*.aux */*.log 24 | 25 | .PHONY: default all clean 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Конспекты лекций по информатике ФМХФ МФТИ 2015-2016 год, лектор Хирьянов Т.Ф. 2 | 3 | Copyright (C) 2015 Timofey Khiryanov. 4 | Permission is granted to copy, distribute and/or modify this document 5 | under the terms of the GNU Free Documentation License, Version 1.3 6 | or any later version published by the Free Software Foundation; 7 | with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. 8 | A copy of the license is included in the section entitled "GNU 9 | Free Documentation License". 10 | -------------------------------------------------------------------------------- /lection_16/lection_16.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | 3 | %%% Работа с русским языком % для pdfLatex 4 | \usepackage{cmap} % поиск в~PDF 5 | \usepackage{mathtext} % русские буквы в~фомулах 6 | \usepackage[T2A]{fontenc} % кодировка 7 | \usepackage[utf8]{inputenc} % кодировка исходного текста 8 | \usepackage[english,russian]{babel} % локализация и переносы 9 | \usepackage{indentfirst} % отступ 1 абзаца 10 | 11 | %%% Работа с русским языком % для XeLatex 12 | %\usepackage[english,russian]{babel} %% загружает пакет многоязыковой вёрстки 13 | %\usepackage{fontspec} %% подготавливает загрузку шрифтов Open Type, True Type и др. 14 | %\defaultfontfeatures{Ligatures={TeX},Renderer=Basic} %% свойства шрифтов по умолчанию 15 | %\setmainfont[Ligatures={TeX,Historic}]{Times New Roman} %% задаёт основной шрифт документа 16 | %\setsansfont{Comic Sans MS} %% задаёт шрифт без засечек 17 | %\setmonofont{Courier New} 18 | %\usepackage{indentfirst} 19 | %\frenchspacing 20 | 21 | %%% Дополнительная работа с математикой 22 | \usepackage{amsfonts,amssymb,amsthm,mathtools} 23 | \usepackage{amsmath} 24 | \usepackage{icomma} % "Умная" запятая: $0,2$ --- число, $0, 2$ --- перечисление 25 | \usepackage{upgreek} 26 | 27 | %% Номера формул 28 | %\mathtoolsset{showonlyrefs=true} % Показывать номера только у тех формул, на которые есть \eqref{} в~тексте. 29 | 30 | %%% Страница 31 | \usepackage{extsizes} % Возможность сделать 14-й шрифт 32 | 33 | %% Шрифты 34 | \usepackage{euscript} % Шрифт Евклид 35 | \usepackage{mathrsfs} % Красивый матшрифт 36 | 37 | %% Свои команды 38 | \DeclareMathOperator{\sgn}{\mathop{sgn}} % создание новой конанды \sgn (типо как \sin) 39 | \usepackage{csquotes} % ещё одна штука для цитат 40 | \newcommand{\pd}[2]{\ensuremath{\cfrac{\partial #1}{\partial #2}}} % частная производная 41 | \newcommand{\abs}[1]{\ensuremath{\left|#1\right|}} % модуль 42 | \renewcommand{\phi}{\ensuremath{\varphi}} % греческая фи 43 | \newcommand{\pogk}[1]{\!\left(\cfrac{\sigma_{#1}}{#1}\right)^{\!\!\!2}\!} % для погрешностей 44 | 45 | % Ссылки 46 | \usepackage{color} % подключить пакет color 47 | % выбрать цвета 48 | \definecolor{BlueGreen}{RGB}{49,152,255} 49 | \definecolor{Violet}{RGB}{120,80,120} 50 | % назначить цвета при подключении hyperref 51 | \usepackage[unicode, colorlinks, urlcolor=blue, linkcolor=blue, pagecolor=blue, citecolor=blue]{hyperref} %синие ссылки 52 | %\usepackage[unicode, colorlinks, urlcolor=black, linkcolor=black, pagecolor=black, citecolor=black]{hyperref} % для печати (отключить верхний!) 53 | 54 | 55 | %% Перенос знаков в~формулах (по Львовскому) 56 | \newcommand*{\hm}[1]{#1\nobreak\discretionary{} 57 | {\hbox{$\mathsurround=0pt #1$}}{}} 58 | 59 | %%% Работа с картинками 60 | \usepackage{graphicx} % Для вставки рисунков 61 | \graphicspath{{images/}{images2/}} % папки с картинками 62 | \setlength\fboxsep{3pt} % Отступ рамки \fbox{} от рисунка 63 | \setlength\fboxrule{1pt} % Толщина линий рамки \fbox{} 64 | \usepackage{wrapfig} % Обтекание рисунков и таблиц текстом 65 | \usepackage{multicol} 66 | 67 | %%% Работа с таблицами 68 | \usepackage{array,tabularx,tabulary,booktabs} % Дополнительная работа с таблицами 69 | \usepackage{longtable} % Длинные таблицы 70 | \usepackage{multirow} % Слияние строк в~таблице 71 | \usepackage{caption} 72 | \captionsetup{labelsep=period, labelfont=bf} 73 | 74 | %%% Оформление 75 | \usepackage{indentfirst} % Красная строка 76 | %\setlength{\parskip}{0.3cm} % отступы между абзацами 77 | %%% Название разделов 78 | \usepackage{titlesec} 79 | \titlelabel{\thetitle.\quad} 80 | \renewcommand{\figurename}{\textbf{Рис.}} %Чтобы вместо figure под рисунками писал "рис" 81 | \renewcommand{\tablename}{\textbf{Таблица}} %Чтобы вместо table над таблицами писал Таблица 82 | 83 | %%% Теоремы 84 | \theoremstyle{plain} % Это стиль по умолчанию, его можно не переопределять. 85 | \newtheorem{theorem}{Теорема}[section] 86 | \newtheorem{proposition}[theorem]{Утверждение} 87 | 88 | \theoremstyle{definition} % "Определение" 89 | \newtheorem{definition}{Определение}[section] 90 | \newtheorem{corollary}{Следствие}[theorem] 91 | \newtheorem{problem}{Задача}[section] 92 | 93 | \theoremstyle{remark} % "Примечание" 94 | \newtheorem*{nonum}{Решение} 95 | \newtheorem{zamech}{Замечание}[theorem] 96 | 97 | %%% Правильные мат. символы для русского языка 98 | \renewcommand{\epsilon}{\ensuremath{\varepsilon}} 99 | \renewcommand{\phi}{\ensuremath{\varphi}} 100 | \renewcommand{\kappa}{\ensuremath{\varkappa}} 101 | \renewcommand{\le}{\ensuremath{\leqslant}} 102 | \renewcommand{\leq}{\ensuremath{\leqslant}} 103 | \renewcommand{\ge}{\ensuremath{\geqslant}} 104 | \renewcommand{\geq}{\ensuremath{\geqslant}} 105 | \renewcommand{\emptyset}{\varnothing} 106 | 107 | %%% Для лекций по инфе 108 | \usepackage{alltt} 109 | \newcounter{infa}[section] 110 | \newcounter{num} 111 | \definecolor{infa}{rgb}{0, 0.2, 0.89} 112 | \definecolor{infa1}{rgb}{0, 0.3, 1} 113 | \definecolor{grey}{rgb}{0.5, 0.5, 0.5} 114 | \newcommand{\tab}{\ \ \ } 115 | \newcommand{\com}[1]{{\color{grey}\##1}} 116 | \newcommand{\num}{\addtocounter{num}{1}\arabic{num}\tab} 117 | \newcommand{\defi}{{\color{infa}def}} 118 | \newcommand{\globali}{{\color{infa}global}} 119 | \newcommand{\ini}{{\color{infa}in}} 120 | \newcommand{\rangei}{{\color{infa}range}} 121 | \newcommand{\fori}{{\color{infa}for}} 122 | \newcommand{\ifi}{{\color{infa}if}} 123 | \newcommand{\elsei}{{\color{infa}else}} 124 | \newcommand{\printi}{{\color{infa1}print}} 125 | \newcommand{\enumeratei}{{\color{infa1}enumerate}} 126 | \newcommand{\maxi}{{\color{infa}max}} 127 | \newcommand{\classi}{{\color{infa}class}} 128 | \newcommand{\returni}{{\color{infa}return}} 129 | \newcommand{\elifi}{{\color{infa}elif}} 130 | \newenvironment{infa}[1]{ 131 | 132 | \vspace{0.5cm} 133 | \addtocounter{infa}{1}% 134 | \noindent{\large \textbf{Программа №\thesection.\arabic{infa}.}\ \textbf{#1}}% 135 | \begin{alltt}% 136 | }{\end{alltt} 137 | \setcounter{num}{0} 138 | \vspace{0.1cm}} 139 | %Пример кода: 140 | %\begin{infa}{Поразрядная сортировка} 141 | % \ \num \defi count_sort(a):\tab \com{определяет нашу функцию} 142 | % \ \num \tab m = \maxi(a)+1 143 | % \ \num \tab q = [0]*m 144 | % \ \num \tab \fori x \ini a: 145 | % \ \num \tab \tab q[x] += 1 146 | % \ \num \tab pos = 0 147 | % \ \num \tab \fori x \ini q: 148 | % \ \num \tab \tab \fori i \ini \rangei(q[x]): 149 | % \ \num \tab \tab \tab a[pos] = x 150 | % \num \tab \tab \tab pos += 1 151 | %\end{infa} 152 | 153 | \usepackage[left=1.27cm,right=1.27cm,top=1.27cm,bottom=2cm]{geometry} 154 | %\hbox to\textwidth{команда колонтитула} 155 | \begin{document} 156 | \newcounter{lec} 157 | \newcommand{\lec}[1]{\addtocounter{lec}{1} \setcounter{section}{0}% 158 | \begin{center} 159 | {\LARGE ЛЕКЦИЯ \arabic{lec}% 160 | \vspace{2mm}% 161 | 162 | \textbf{#1}% 163 | } 164 | \end{center} 165 | } 166 | \newpage 167 | \ 168 | \setcounter{lec}{15} 169 | \lec{Повторение} 170 | \section{Ссылочная модель данных} 171 | Ссылочная модель данных - объекты существуют независимо от времен. 172 | \begin{alltt} 173 | >>> 2+3 174 | 5 175 | \end{alltt} 176 | Создаются два объекта типа int. 177 | \begin{alltt} 178 | 2.__add__(3) - метод добавления 179 | \end{alltt} 180 | \begin{alltt} 181 | x = 2+3 # x ссылается на объект 5 182 | x = 'Hello' # возникает объект строки 183 | \end{alltt} 184 | После вывода результата объекты 2, 3, 5 удаляются, т.к. нет ссылки на эти объекты. 185 | Если x перестал ссылаться на 5, объект 5 уничтожается. 186 | \begin{alltt} 187 | x = 5 188 | y = x 189 | x = 'Hello' 190 | y = None 191 | \end{alltt} 192 | После того, как y начал ссылаться на None, объект 5 уничтожается. 193 | \begin{alltt} 194 | x = (2+3+5)**5**5 # приоритет у возведения в степени 195 | \end{alltt} 196 | 197 | Т.е. в начале выполняется 5**5, а потом (2+3+5)**25. 198 | 199 | Начиная с версии Python 3.6, можно разделять числа так: 200 | \begin{alltt} 201 | x = 100_001 202 | y = 0xAF_DC 203 | \end{alltt} 204 | \section{Пространство имен} 205 | 4 пространства: локальные, окружающие, глобальные, строенные (LEGB). 206 | 207 | y = 10*x+7 208 | Сначала будет происходить поиск локального x, затем в надпространстве, затем в глобальных, в последнюю очередь - во встроенных переменных. 209 | 210 | Если написать 211 | max = 10, 212 | то функция max перестанет работать. 213 | 214 | Пример: 215 | \begin{infa}{} 216 | \num \defi f(A): 217 | \num \tab A = A + 10 \com{если написать A += 10 ошибки не будет} 218 | \num B = [1, 2, 3] 219 | \num f(B) 220 | \num \printi(*B) \com{1 2 3} 221 | \end{infa} 222 | 223 | Строки и числа --- неизменяемые объекты. 224 | f является именем объекта functional. 225 | 226 | def --- по сути это операция создания нового объекта. 227 | 228 | Любой вызов функции порождает свое пространство имен, которое перестанет существовать после выполнения return. 229 | 230 | A начинает ссылаться на [1, 2, 3]. После конкатинации A начинает ссылаться на [1, 2, 3, 4]. A ссылается на глобальный объект, и начинает ссылаться на локальный объект. После return уничтожается A и список [1, 2, 3, 4]. 231 | 232 | Или можно записать так: 233 | \begin{infa}{} 234 | \num \defi f(A): 235 | \num \tab A.append(10) 236 | \num B = [1, 2, 3] 237 | \num f(B) 238 | \num \printi(*B) \com{1 2 3} 239 | \end{infa} 240 | 241 | Функция должна что-то возвращать. В частном случае, можно возвращать несколько параметров. Нарушить ссылочную модель можно только "залезая"\ в глобальные имена. 242 | 243 | \begin{infa}{} 244 | \num d=1 245 | \num \defi f(A): 246 | \num \tab \globali d 247 | \num \tab A.append(d) 248 | \num \tab d = d + 1 249 | \end{infa} 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | \section{ООП} 258 | Тип тоже является объектом типа тип. 259 | \begin{infa}{} 260 | \num \classi Base: 261 | \num \tab x = 10 262 | \num \tab \defi g(self, x0): 263 | \num \tab \tab self.x = x0 264 | \num b = Base() 265 | \num \printi(b.x) 266 | \end{infa} 267 | 268 | \begin{infa}{} 269 | \num \classi Base: 270 | \num \tab x = 10 271 | \num \tab \defi g(self, x0) 272 | \num \tab \tab self.x += x0 273 | \num b = Base() 274 | \num \printi(b.x) 275 | \end{infa} 276 | 277 | Нужно создавать атрибуты только в методе init! 278 | 279 | \section{Элементы функционального программирования} 280 | 281 | \subsection{Функция map} 282 | \begin{alltt} 283 | x, y, z = map(int, input().split()) \com{считывание трех чисел с клавиатуры} 284 | \end{alltt} 285 | 286 | Функция map применяет к каждому объекту функцию, которую мы написали. В нее же можно написать свою функцию: 287 | \begin{alltt} 288 | x, y, z = map(lambda x: int(x)**2, input().split()) 289 | A == list(map(int, range(100))) 290 | B = map(float, int(x) for x in input().split()) 291 | \end{alltt} 292 | 293 | map возвращает объект типа map. 294 | 295 | \subsection{Применение lambda-функций} 296 | $x^2+e^{1/x}+\ln x$ 297 | \begin{alltt} 298 | x = decompoused_value # нужно объявлять функцию 299 | (lambda x: x**2 + exp(1/x)+ln(x))(2) #хороший пример использования lambda 300 | \end{alltt} 301 | 302 | \subsection{Функция enumerate} 303 | \begin{infa}{} 304 | \num A = [10, 20, 30] 305 | \num \fori i,x \ini \enumeratei(A): \com{А используется как итерируемый объект} 306 | \num \tab \printi(i,x) \com{(0,10), (1,20), (2,30) - эту конструкцию нам вернет enumerate(A)} 307 | \num \tab x = x + 1 \com{Значение в массиве не изменилось, мы только испортили х} 308 | \end{infa} 309 | \subsection{Функция zip} 310 | 311 | \begin{alltt} 312 | A = [1, 2, 3, 4, 5] 313 | B = 'Hello' 314 | c = list(zip(A,B)) \com{результат есть zip-object} 315 | \end{alltt} 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | \end{document} -------------------------------------------------------------------------------- /lection_17/graph.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_17/graph.jpg -------------------------------------------------------------------------------- /lection_18/alg1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/alg1.jpg -------------------------------------------------------------------------------- /lection_18/alg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/alg2.jpg -------------------------------------------------------------------------------- /lection_18/alg3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/alg3.jpg -------------------------------------------------------------------------------- /lection_18/alg4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/alg4.jpg -------------------------------------------------------------------------------- /lection_18/alg5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/alg5.jpg -------------------------------------------------------------------------------- /lection_18/alg6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/alg6.jpg -------------------------------------------------------------------------------- /lection_18/alg7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/alg7.jpg -------------------------------------------------------------------------------- /lection_18/alg8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/alg8.jpg -------------------------------------------------------------------------------- /lection_18/alg9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/alg9.jpg -------------------------------------------------------------------------------- /lection_18/graph1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/graph1.jpg -------------------------------------------------------------------------------- /lection_18/kos1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/kos1.jpg -------------------------------------------------------------------------------- /lection_18/kos2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/kos2.jpg -------------------------------------------------------------------------------- /lection_18/kos3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/kos3.jpg -------------------------------------------------------------------------------- /lection_18/most.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/most.jpg -------------------------------------------------------------------------------- /lection_18/sharnir.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_18/sharnir.jpg -------------------------------------------------------------------------------- /lection_19/Animated_BFS.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/Animated_BFS.gif -------------------------------------------------------------------------------- /lection_19/frame-0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-0.png -------------------------------------------------------------------------------- /lection_19/frame-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-1.png -------------------------------------------------------------------------------- /lection_19/frame-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-2.png -------------------------------------------------------------------------------- /lection_19/frame-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-3.png -------------------------------------------------------------------------------- /lection_19/frame-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-4.png -------------------------------------------------------------------------------- /lection_19/frame-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-5.png -------------------------------------------------------------------------------- /lection_19/frame-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-6.png -------------------------------------------------------------------------------- /lection_19/frame-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-7.png -------------------------------------------------------------------------------- /lection_19/frame-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-8.png -------------------------------------------------------------------------------- /lection_19/frame-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_19/frame-9.png -------------------------------------------------------------------------------- /lection_21/germany.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_21/germany.png -------------------------------------------------------------------------------- /lection_22/graph_derevo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_22/graph_derevo.pdf -------------------------------------------------------------------------------- /lection_22/graph_derevo.pdf_tex: -------------------------------------------------------------------------------- 1 | %% Creator: Inkscape inkscape 0.92.1, www.inkscape.org 2 | %% PDF/EPS/PS + LaTeX output extension by Johan Engelen, 2010 3 | %% Accompanies image file 'graph_derevo.pdf' (pdf, eps, ps) 4 | %% 5 | %% To include the image in your LaTeX document, write 6 | %% \input{.pdf_tex} 7 | %% instead of 8 | %% \includegraphics{.pdf} 9 | %% To scale the image, write 10 | %% \def\svgwidth{} 11 | %% \input{.pdf_tex} 12 | %% instead of 13 | %% \includegraphics[width=]{.pdf} 14 | %% 15 | %% Images with a different path to the parent latex file can 16 | %% be accessed with the `import' package (which may need to be 17 | %% installed) using 18 | %% \usepackage{import} 19 | %% in the preamble, and then including the image with 20 | %% \import{}{.pdf_tex} 21 | %% Alternatively, one can specify 22 | %% \graphicspath{{/}} 23 | %% 24 | %% For more information, please see info/svg-inkscape on CTAN: 25 | %% http://tug.ctan.org/tex-archive/info/svg-inkscape 26 | %% 27 | \begingroup% 28 | \makeatletter% 29 | \providecommand\color[2][]{% 30 | \errmessage{(Inkscape) Color is used for the text in Inkscape, but the package 'color.sty' is not loaded}% 31 | \renewcommand\color[2][]{}% 32 | }% 33 | \providecommand\transparent[1]{% 34 | \errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package 'transparent.sty' is not loaded}% 35 | \renewcommand\transparent[1]{}% 36 | }% 37 | \providecommand\rotatebox[2]{#2}% 38 | \ifx\svgwidth\undefined% 39 | \setlength{\unitlength}{668.09966913bp}% 40 | \ifx\svgscale\undefined% 41 | \relax% 42 | \else% 43 | \setlength{\unitlength}{\unitlength * \real{\svgscale}}% 44 | \fi% 45 | \else% 46 | \setlength{\unitlength}{\svgwidth}% 47 | \fi% 48 | \global\let\svgwidth\undefined% 49 | \global\let\svgscale\undefined% 50 | \makeatother% 51 | \begin{picture}(1,0.49472366)% 52 | \put(0,0){\includegraphics[width=\unitlength,page=1]{graph_derevo.pdf}}% 53 | \put(0.02342677,0.00083317){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{0}}}% 54 | \put(0.06716565,0.00138131){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{1}}}% 55 | \put(0.14861047,0.00081124){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{2}}}% 56 | \put(0.24212123,0.00081124){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{3}}}% 57 | \put(0.32959898,0.00149094){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{4}}}% 58 | \put(0.40953558,0.00149094){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{5}}}% 59 | \put(0.45478275,0.00087702){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{6}}}% 60 | \put(0.50907926,0.00149094){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{7}}}% 61 | \put(0.58449108,0.00074547){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{8}}}% 62 | \put(0.64029593,0.00083317){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{9}}}% 63 | \put(0.73833134,0.00083317){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{10}}}% 64 | \put(0.80620201,0.00138131){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{11}}}% 65 | \put(0.87256449,0.00081124){\color[rgb]{0,0,0}\makebox(0,0)[lb]{\smash{12}}}% 66 | \end{picture}% 67 | \endgroup% 68 | -------------------------------------------------------------------------------- /lection_22/graph_derevo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mipt-cs/pdf-textbook-python3/a69c0d13951c8d636c2255b532353d4384c76a31/lection_22/graph_derevo.png -------------------------------------------------------------------------------- /lection_23/class Tree.py: -------------------------------------------------------------------------------- 1 | class Tree: 2 | class Node: 3 | def __init__(self, data): 4 | self.parent = None 5 | self.left = None 6 | self.right = None 7 | self.key = data 8 | def __init__(self): 9 | self.root = None 10 | def find(self, data): 11 | p = self.root 12 | while p is not None and p.key != data: 13 | if data > p.key: 14 | p = p.right 15 | else: 16 | p = p.left 17 | return p 18 | def insert(self, data): 19 | p = self.find(data) 20 | if p is not None: 21 | return 22 | node = Tree.Node(data) 23 | if self.root is None: 24 | self.root = node 25 | return 26 | p = self.root 27 | while True: 28 | if data < p.key: 29 | if p.left is None: 30 | p.left = node 31 | node.parent = p 32 | break 33 | else: 34 | p = p.left 35 | else: 36 | if p.right is None: 37 | p.right = node 38 | node.parent = p 39 | break 40 | else: 41 | p = p.right -------------------------------------------------------------------------------- /lection_23/lection_23.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | 3 | %%% Работа с русским языком % для pdfLatex 4 | \usepackage{cmap} % поиск в~PDF 5 | \usepackage{mathtext} % русские буквы в~фомулах 6 | \usepackage[T2A]{fontenc} % кодировка 7 | \usepackage[utf8]{inputenc} % кодировка исходного текста 8 | \usepackage[english,russian]{babel} % локализация и переносы 9 | \usepackage{indentfirst} % отступ 1 абзаца 10 | 11 | %%% Работа с русским языком % для XeLatex 12 | %\usepackage[english,russian]{babel} %% загружает пакет многоязыковой вёрстки 13 | %\usepackage{fontspec} %% подготавливает загрузку шрифтов Open Type, True Type и др. 14 | %\defaultfontfeatures{Ligatures={TeX},Renderer=Basic} %% свойства шрифтов по умолчанию 15 | %\setmainfont[Ligatures={TeX,Historic}]{Times New Roman} %% задаёт основной шрифт документа 16 | %\setsansfont{Comic Sans MS} %% задаёт шрифт без засечек 17 | %\setmonofont{Courier New} 18 | %\usepackage{indentfirst} 19 | %\frenchspacing 20 | 21 | %%% Дополнительная работа с математикой 22 | \usepackage{amsfonts,amssymb,amsthm,mathtools} 23 | \usepackage{amsmath} 24 | \usepackage{icomma} % "Умная" запятая: $0,2$ --- число, $0, 2$ --- перечисление 25 | \usepackage{upgreek} 26 | 27 | %% Номера формул 28 | %\mathtoolsset{showonlyrefs=true} % Показывать номера только у тех формул, на которые есть \eqref{} в~тексте. 29 | 30 | %%% Страница 31 | \usepackage{extsizes} % Возможность сделать 14-й шрифт 32 | 33 | %% Шрифты 34 | \usepackage{euscript} % Шрифт Евклид 35 | \usepackage{mathrsfs} % Красивый матшрифт 36 | 37 | %% Свои команды 38 | \DeclareMathOperator{\sgn}{\mathop{sgn}} % создание новой конанды \sgn (типо как \sin) 39 | \usepackage{csquotes} % ещё одна штука для цитат 40 | \newcommand{\pd}[2]{\ensuremath{\cfrac{\partial #1}{\partial #2}}} % частная производная 41 | \newcommand{\abs}[1]{\ensuremath{\left|#1\right|}} % модуль 42 | \renewcommand{\phi}{\ensuremath{\varphi}} % греческая фи 43 | \newcommand{\pogk}[1]{\!\left(\cfrac{\sigma_{#1}}{#1}\right)^{\!\!\!2}\!} % для погрешностей 44 | 45 | % Ссылки 46 | \usepackage{color} % подключить пакет color 47 | % выбрать цвета 48 | \definecolor{BlueGreen}{RGB}{49,152,255} 49 | \definecolor{Violet}{RGB}{120,80,120} 50 | % назначить цвета при подключении hyperref 51 | \usepackage[unicode, colorlinks, urlcolor=blue, linkcolor=blue, pagecolor=blue, citecolor=blue]{hyperref} %синие ссылки 52 | %\usepackage[unicode, colorlinks, urlcolor=black, linkcolor=black, pagecolor=black, citecolor=black]{hyperref} % для печати (отключить верхний!) 53 | 54 | 55 | %% Перенос знаков в~формулах (по Львовскому) 56 | \newcommand*{\hm}[1]{#1\nobreak\discretionary{} 57 | {\hbox{$\mathsurround=0pt #1$}}{}} 58 | 59 | %%% Работа с картинками 60 | \usepackage{graphicx} % Для вставки рисунков 61 | \graphicspath{{images/}{images2/}} % папки с картинками 62 | \setlength\fboxsep{3pt} % Отступ рамки \fbox{} от рисунка 63 | \setlength\fboxrule{1pt} % Толщина линий рамки \fbox{} 64 | \usepackage{wrapfig} % Обтекание рисунков и таблиц текстом 65 | \usepackage{multicol} 66 | 67 | %%% Работа с таблицами 68 | \usepackage{array,tabularx,tabulary,booktabs} % Дополнительная работа с таблицами 69 | \usepackage{longtable} % Длинные таблицы 70 | \usepackage{multirow} % Слияние строк в~таблице 71 | \usepackage{caption} 72 | \captionsetup{labelsep=period, labelfont=bf} 73 | 74 | %%% Оформление 75 | \usepackage{indentfirst} % Красная строка 76 | %\setlength{\parskip}{0.3cm} % отступы между абзацами 77 | %%% Название разделов 78 | \usepackage{titlesec} 79 | \titlelabel{\thetitle.\quad} 80 | \renewcommand{\figurename}{\textbf{Рис.}} %Чтобы вместо figure под рисунками писал "рис" 81 | \renewcommand{\tablename}{\textbf{Таблица}} %Чтобы вместо table над таблицами писал Таблица 82 | 83 | %%% Теоремы 84 | \theoremstyle{plain} % Это стиль по умолчанию, его можно не переопределять. 85 | \newtheorem{theorem}{Теорема}[section] 86 | \newtheorem{proposition}[theorem]{Утверждение} 87 | 88 | \theoremstyle{definition} % "Определение" 89 | \newtheorem{definition}{Определение}[section] 90 | \newtheorem{corollary}{Следствие}[theorem] 91 | \newtheorem{problem}{Задача}[section] 92 | 93 | \theoremstyle{remark} % "Примечание" 94 | \newtheorem*{nonum}{Решение} 95 | \newtheorem{zamech}{Замечание}[theorem] 96 | 97 | %%% Правильные мат. символы для русского языка 98 | \renewcommand{\epsilon}{\ensuremath{\varepsilon}} 99 | \renewcommand{\phi}{\ensuremath{\varphi}} 100 | \renewcommand{\kappa}{\ensuremath{\varkappa}} 101 | \renewcommand{\le}{\ensuremath{\leqslant}} 102 | \renewcommand{\leq}{\ensuremath{\leqslant}} 103 | \renewcommand{\ge}{\ensuremath{\geqslant}} 104 | \renewcommand{\geq}{\ensuremath{\geqslant}} 105 | \renewcommand{\emptyset}{\varnothing} 106 | 107 | %%% Для лекций по инфе 108 | \usepackage{tikz} 109 | \usetikzlibrary{graphs} 110 | \usepackage{alltt} 111 | \newcounter{infa}[section] 112 | \newcounter{num} 113 | \definecolor{infa}{rgb}{0, 0.2, 0.89} 114 | \definecolor{infa1}{rgb}{0, 0.3, 1} 115 | \definecolor{grey}{rgb}{0.5, 0.5, 0.5} 116 | \newcommand{\tab}{\ \ \ } 117 | \newcommand{\com}[1]{{\color{grey}\# #1}} 118 | \newcommand{\num}{\addtocounter{num}{1}\arabic{num}\tab} 119 | \newcommand{\defi}{{\color{infa}def}} 120 | \newcommand{\globali}{{\color{infa}global}} 121 | \newcommand{\ini}{{\color{infa}in}} 122 | \newcommand{\rangei}{{\color{infa}range}} 123 | \newcommand{\fori}{{\color{infa}for}} 124 | \newcommand{\ifi}{{\color{infa}if}} 125 | \newcommand{\elsei}{{\color{infa}else}} 126 | \newcommand{\printi}{{\color{infa1}print}} 127 | \newcommand{\enumeratei}{{\color{infa1}enumerate}} 128 | \newcommand{\maxi}{{\color{infa}max}} 129 | \newcommand{\classi}{{\color{infa}class}} 130 | \newcommand{\returni}{{\color{infa}return}} 131 | \newcommand{\elifi}{{\color{infa}elif}} 132 | \newcommand{\seti}{{\color{infa}set}} 133 | \newcommand{\noti}{{\color{infa}not}} 134 | \newcommand{\dicti}{{\color{infa}dict}} 135 | \newcommand{\zipi}{{\color{infa}zip}} 136 | \newcommand{\chri}{{\color{infa}chr}} 137 | \newcommand{\ordi}{{\color{infa}ord}} 138 | \newcommand{\leni}{{\color{infa}len}} 139 | \newcommand{\deli}{{\color{infa}del}} 140 | \newcommand{\sortedi}{{\color{infa}sorted}} 141 | \newcommand{\keyi}{{\color{infa}key}} 142 | \newcommand{\lambdai}{{\color{infa}lambda}} 143 | \newcommand{\inti}{{\color{infa}int}} 144 | \newcommand{\inputi}{{\color{infa}input}} 145 | \newcommand{\isi}{{\color{infa}is}} 146 | \newcommand{\Nonei}{{\color{infa}None}} 147 | \newcommand{\whilei}{{\color{infa}while}} 148 | \newcommand{\andi}{{\color{infa}and}} 149 | \newcommand{\fromi}{{\color{infa}from}} 150 | \newcommand{\importi}{{\color{infa}import}} 151 | \newcommand{\continuei}{{\color{infa}continue}} 152 | \newcommand{\mapi}{{\color{infa}map}} 153 | \newcommand{\Falsei}{{\color{infa1}False}} 154 | \newcommand{\listi}{{\color{infa}list}} 155 | \newcommand{\Truei}{{\color{infa1}True}} 156 | \newcommand{\mini}{{\color{infa1}min}} 157 | \newcommand{\breaki}{{\color{infa1}break}} 158 | 159 | 160 | \newenvironment{infa}[1]{ 161 | 162 | \vspace{0.5cm} 163 | \addtocounter{infa}{1}% 164 | \noindent{\large \textbf{Программа №\thesection.\arabic{infa}.}\ \textbf{#1}}% 165 | \begin{alltt}% 166 | }{\end{alltt} 167 | \setcounter{num}{0} 168 | \vspace{0.1cm}} 169 | \newenvironment{infanoname}{ 170 | 171 | %\vspace{0.5cm} 172 | %\addtocounter{infa}{1}% 173 | %\noindent{\large \textbf{Программа №\thesection.\arabic{infa}.}\ \textbf{#1}}% 174 | \begin{alltt}% 175 | }{\end{alltt} 176 | \setcounter{num}{0} 177 | \vspace{0.1cm}} 178 | 179 | \usepackage{animate} % Для добавления гифок 180 | \usepackage{xmpmulti} 181 | %Пример кода: 182 | %\begin{infa}{Поразрядная сортировка} 183 | % \ \num \defi count_sort(a):\tab \com{определяет нашу функцию} 184 | % \ \num \tab m = \maxi(a)+1 185 | % \ \num \tab q = [0]*m 186 | % \ \num \tab \fori x \ini a: 187 | % \ \num \tab \tab q[x] += 1 188 | % \ \num \tab pos = 0 189 | % \ \num \tab \fori x \ini q: 190 | % \ \num \tab \tab \fori i \ini \rangei(q[x]): 191 | % \ \num \tab \tab \tab a[pos] = x 192 | % \num \tab \tab \tab pos += 1 193 | %\end{infa} 194 | 195 | \usepackage[left=1.27cm,right=1.27cm,top=1.27cm,bottom=2cm]{geometry} 196 | %\hbox to\textwidth{команда колонтитула} 197 | 198 | \usepackage{verbatim} 199 | \begin{document} 200 | \newcounter{lec} 201 | \newcommand{\lec}[1]{\addtocounter{lec}{1} \setcounter{section}{0}% 202 | \begin{center} 203 | {\LARGE ЛЕКЦИЯ \arabic{lec}% 204 | \vspace{2mm}% 205 | 206 | \textbf{#1}% 207 | } 208 | \end{center} 209 | } 210 | \newpage 211 | \ 212 | \setcounter{lec}{22} 213 | \lec{Двоичное дерево поиска. Продолжение.} 214 | \section{Класс Дерево. Продолжение.} 215 | %Будет разумным погрузить класс звена в дерево 216 | \begin{infa}{Класс Дерево} 217 | \ \num \classi Tree: 218 | \ \num \tab \classi Node: \com{Класс в классе можно делать, т.к. в классе описано свое\\\phantom{12\ \ \ \ \ \ \ } пространство имен} 219 | \ \num \tab \tab \defi __init__(self, data): 220 | \ \num \tab \tab \tab self.parent = \Nonei 221 | \ \num \tab \tab \tab self.left = \Nonei 222 | \ \num \tab \tab \tab self.right = \Nonei 223 | \ \num \tab \tab \tab self.key = data 224 | \ \num \tab \defi __init__(self): 225 | \ \num \tab \tab self.root = \Nonei 226 | \num \tab \defi find(self, data): 227 | \num \tab \tab p = self.root 228 | \num \tab \tab \whilei p \isi \noti \Nonei \andi p.key != data: \com{Важна последовательность\\\phantom{12\ \ \ \ \ \ \ } написаний условий, т.к. может быть ошибка при проверке ключа} 229 | \num \tab \tab \tab \ifi data > p.key: 230 | \num \tab \tab \tab \tab p = p.right 231 | \num \tab \tab \tab \elsei: 232 | \num \tab \tab \tab \tab p = p.left 233 | \num \tab \tab \returni p 234 | \num \tab \defi insert(self, data): 235 | \num \tab \tab p = self.find(data) \com{Одно и то же число не может храниться дважды, \\\phantom{12\ \ \ \ \ \ \ }как в множестве, но значения могут повторяться} 236 | \num \tab \tab \ifi p \isi \noti \Nonei: 237 | \num \tab \tab \tab \returni 238 | \num \tab \tab node = Tree.Node(data) 239 | \num \tab \tab \ifi self.root \isi \Nonei: 240 | \num \tab \tab \tab self.root = node 241 | \num \tab \tab \tab \returni 242 | \num \tab \tab p = self.root 243 | \num \tab \tab \whilei \Truei: 244 | \num \tab \tab \tab \ifi data < p.key: 245 | \num \tab \tab \tab \tab \ifi p.left \isi \Nonei: 246 | \num \tab \tab \tab \tab \tab p.left = node 247 | \num \tab \tab \tab \tab \tab node.parent = p 248 | \num \tab \tab \tab \tab \tab \breaki 249 | \num \tab \tab \tab \tab \elsei: 250 | \num \tab \tab \tab \tab \tab p = p.left 251 | \num \tab \tab \tab \elsei: 252 | \num \tab \tab \tab \tab \ifi p.right \isi \Nonei: 253 | \num \tab \tab \tab \tab \tab p.right = node 254 | \num \tab \tab \tab \tab \tab node.parent = p 255 | \num \tab \tab \tab \tab \tab \breaki 256 | \num \tab \tab \tab \tab \elsei: 257 | \num \tab \tab \tab \tab \tab p = p.right 258 | \end{infa} 259 | \section{Балансировка дерева} 260 | Двоичное дерево поиска \textsf{сбалансированно}, если для каждой его вершины высота левого и правого поддерева отличаются не более чем на единицу. 261 | 262 | %нарисуем закошеное дерево 263 | \textbf{Инвариант}: та вершина, которая левее других вершин, должна остаться левее всех вершин, т.е двигать вверх--вниз вершины можно, но влево--вправо двигать нельзя, иначе нарушится последовательность чисел. 264 | 265 | Алгоритм балансировки подробно описан в \href{https://ru.wikipedia.org/wiki/%D0%90%D0%92%D0%9B-%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE#.D0.91.D0.B0.D0.BB.D0.B0.D0.BD.D1.81.D0.B8.D1.80.D0.BE.D0.B2.D0.BA.D0.B0}{википедии}. 266 | 267 | \textsf{АВЛ--дерево} --- сбалансированное по высоте двоичное дерево поиска: для каждой его вершины высота её двух поддеревьев различается не более чем на 1. 268 | 269 | 270 | \textsf{Красно--чёрное дерево} --- это одно из самобалансирующихся двоичных деревьев поиска, гарантирующих логарифмический рост высоты дерева от числа узлов и быстро выполняющее основные операции дерева поиска: добавление, удаление и поиск узла. Сбалансированность достигается за счёт введения дополнительного атрибута узла дерева --- «цвета». Этот атрибут может принимать одно из двух возможных значений --- «чёрный» или «красный». 271 | 272 | \textbf{Свойства} красно--черного дерева: 273 | \begin{enumerate} 274 | \item Узел либо красный, либо чёрный. 275 | \item Корень --- чёрный. (В других определениях это правило иногда опускается. Это правило слабо влияет на анализ, так как корень всегда может быть изменен с красного на чёрный, но не обязательно наоборот). 276 | \item Все листья --- чёрные. 277 | \item Оба потомка каждого красного узла --- чёрные. 278 | \item Всякий простой путь от данного узла до любого листового узла, являющегося его потомком, содержит одинаковое число чёрных узлов. 279 | \end{enumerate} 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | %\begin{comment} 289 | \begin{center} 290 | \vfill \emph{{\small Г. С. Демьянов, \href{https://vk.com/id37346992}{VK}\\ 291 | С. С. Клявинек, \href{https://vk.com/id85132547}{VK} 292 | }} 293 | \end{center} 294 | %\end{comment} 295 | 296 | 297 | 298 | 299 | 300 | \end{document} -------------------------------------------------------------------------------- /lection_25/lection_25.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | 3 | %%% Работа с русским языком % для pdfLatex 4 | \usepackage{cmap} % поиск в~PDF 5 | \usepackage{mathtext} % русские буквы в~фомулах 6 | \usepackage[T2A]{fontenc} % кодировка 7 | \usepackage[utf8]{inputenc} % кодировка исходного текста 8 | \usepackage[english,russian]{babel} % локализация и переносы 9 | \usepackage{indentfirst} % отступ 1 абзаца 10 | 11 | %%% Работа с русским языком % для XeLatex 12 | %\usepackage[english,russian]{babel} %% загружает пакет многоязыковой вёрстки 13 | %\usepackage{fontspec} %% подготавливает загрузку шрифтов Open Type, True Type и др. 14 | %\defaultfontfeatures{Ligatures={TeX},Renderer=Basic} %% свойства шрифтов по умолчанию 15 | %\setmainfont[Ligatures={TeX,Historic}]{Times New Roman} %% задаёт основной шрифт документа 16 | %\setsansfont{Comic Sans MS} %% задаёт шрифт без засечек 17 | %\setmonofont{Courier New} 18 | %\usepackage{indentfirst} 19 | %\frenchspacing 20 | 21 | %%% Дополнительная работа с математикой 22 | \usepackage{amsfonts,amssymb,amsthm,mathtools} 23 | \usepackage{amsmath} 24 | \usepackage{icomma} % "Умная" запятая: $0,2$ --- число, $0, 2$ --- перечисление 25 | \usepackage{upgreek} 26 | 27 | %% Номера формул 28 | %\mathtoolsset{showonlyrefs=true} % Показывать номера только у тех формул, на которые есть \eqref{} в~тексте. 29 | 30 | %%% Страница 31 | \usepackage{extsizes} % Возможность сделать 14-й шрифт 32 | 33 | %% Шрифты 34 | \usepackage{euscript} % Шрифт Евклид 35 | \usepackage{mathrsfs} % Красивый матшрифт 36 | 37 | %% Свои команды 38 | \DeclareMathOperator{\sgn}{\mathop{sgn}} % создание новой конанды \sgn (типо как \sin) 39 | \usepackage{csquotes} % ещё одна штука для цитат 40 | \newcommand{\pd}[2]{\ensuremath{\cfrac{\partial #1}{\partial #2}}} % частная производная 41 | \newcommand{\abs}[1]{\ensuremath{\left|#1\right|}} % модуль 42 | \renewcommand{\phi}{\ensuremath{\varphi}} % греческая фи 43 | \newcommand{\pogk}[1]{\!\left(\cfrac{\sigma_{#1}}{#1}\right)^{\!\!\!2}\!} % для погрешностей 44 | 45 | % Ссылки 46 | \usepackage{color} % подключить пакет color 47 | % выбрать цвета 48 | \definecolor{BlueGreen}{RGB}{49,152,255} 49 | \definecolor{Violet}{RGB}{120,80,120} 50 | % назначить цвета при подключении hyperref 51 | \usepackage[unicode, colorlinks, urlcolor=blue, linkcolor=blue, pagecolor=blue, citecolor=blue]{hyperref} %синие ссылки 52 | %\usepackage[unicode, colorlinks, urlcolor=black, linkcolor=black, pagecolor=black, citecolor=black]{hyperref} % для печати (отключить верхний!) 53 | 54 | 55 | %% Перенос знаков в~формулах (по Львовскому) 56 | \newcommand*{\hm}[1]{#1\nobreak\discretionary{} 57 | {\hbox{$\mathsurround=0pt #1$}}{}} 58 | 59 | %%% Работа с картинками 60 | \usepackage{graphicx} % Для вставки рисунков 61 | \graphicspath{{images/}{images2/}} % папки с картинками 62 | \setlength\fboxsep{3pt} % Отступ рамки \fbox{} от рисунка 63 | \setlength\fboxrule{1pt} % Толщина линий рамки \fbox{} 64 | \usepackage{wrapfig} % Обтекание рисунков и таблиц текстом 65 | \usepackage{multicol} 66 | 67 | %%% Работа с таблицами 68 | \usepackage{array,tabularx,tabulary,booktabs} % Дополнительная работа с таблицами 69 | \usepackage{longtable} % Длинные таблицы 70 | \usepackage{multirow} % Слияние строк в~таблице 71 | \usepackage{caption} 72 | \captionsetup{labelsep=period, labelfont=bf} 73 | 74 | %%% Оформление 75 | \usepackage{indentfirst} % Красная строка 76 | %\setlength{\parskip}{0.3cm} % отступы между абзацами 77 | %%% Название разделов 78 | \usepackage{titlesec} 79 | \titlelabel{\thetitle.\quad} 80 | \renewcommand{\figurename}{\textbf{Рис.}} %Чтобы вместо figure под рисунками писал "рис" 81 | \renewcommand{\tablename}{\textbf{Таблица}} %Чтобы вместо table над таблицами писал Таблица 82 | 83 | %%% Теоремы 84 | \theoremstyle{plain} % Это стиль по умолчанию, его можно не переопределять. 85 | \newtheorem{theorem}{Теорема}[section] 86 | \newtheorem{proposition}[theorem]{Утверждение} 87 | 88 | \theoremstyle{definition} % "Определение" 89 | \newtheorem{definition}{Определение}[section] 90 | \newtheorem{corollary}{Следствие}[theorem] 91 | \newtheorem{problem}{Задача}[section] 92 | 93 | \theoremstyle{remark} % "Примечание" 94 | \newtheorem*{nonum}{Решение} 95 | \newtheorem{zamech}{Замечание}[theorem] 96 | 97 | %%% Правильные мат. символы для русского языка 98 | \renewcommand{\epsilon}{\ensuremath{\varepsilon}} 99 | \renewcommand{\phi}{\ensuremath{\varphi}} 100 | \renewcommand{\kappa}{\ensuremath{\varkappa}} 101 | \renewcommand{\le}{\ensuremath{\leqslant}} 102 | \renewcommand{\leq}{\ensuremath{\leqslant}} 103 | \renewcommand{\ge}{\ensuremath{\geqslant}} 104 | \renewcommand{\geq}{\ensuremath{\geqslant}} 105 | \renewcommand{\emptyset}{\varnothing} 106 | 107 | %%% Для лекций по инфе 108 | \usepackage{tikz} 109 | \usetikzlibrary{graphs} 110 | \usepackage{alltt} 111 | \newcounter{infa}[section] 112 | \newcounter{num} 113 | \definecolor{infa}{rgb}{0, 0.2, 0.89} 114 | \definecolor{infa1}{rgb}{0, 0.3, 1} 115 | \definecolor{grey}{rgb}{0.5, 0.5, 0.5} 116 | \newcommand{\tab}{\ \ \ } 117 | \newcommand{\com}[1]{{\color{grey}\# #1}} 118 | \newcommand{\num}{\addtocounter{num}{1}\arabic{num}\tab} 119 | \newcommand{\defi}{{\color{infa}def}} 120 | \newcommand{\globali}{{\color{infa}global}} 121 | \newcommand{\ini}{{\color{infa}in}} 122 | \newcommand{\rangei}{{\color{infa}range}} 123 | \newcommand{\fori}{{\color{infa}for}} 124 | \newcommand{\ifi}{{\color{infa}if}} 125 | \newcommand{\elsei}{{\color{infa}else}} 126 | \newcommand{\printi}{{\color{infa1}print}} 127 | \newcommand{\enumeratei}{{\color{infa1}enumerate}} 128 | \newcommand{\maxi}{{\color{infa}max}} 129 | \newcommand{\classi}{{\color{infa}class}} 130 | \newcommand{\returni}{{\color{infa}return}} 131 | \newcommand{\elifi}{{\color{infa}elif}} 132 | \newcommand{\seti}{{\color{infa}set}} 133 | \newcommand{\noti}{{\color{infa}not}} 134 | \newcommand{\dicti}{{\color{infa}dict}} 135 | \newcommand{\zipi}{{\color{infa}zip}} 136 | \newcommand{\chri}{{\color{infa}chr}} 137 | \newcommand{\ordi}{{\color{infa}ord}} 138 | \newcommand{\leni}{{\color{infa}len}} 139 | \newcommand{\deli}{{\color{infa}del}} 140 | \newcommand{\sortedi}{{\color{infa}sorted}} 141 | \newcommand{\keyi}{{\color{infa}key}} 142 | \newcommand{\lambdai}{{\color{infa}lambda}} 143 | \newcommand{\inti}{{\color{infa}int}} 144 | \newcommand{\inputi}{{\color{infa}input}} 145 | \newcommand{\isi}{{\color{infa}is}} 146 | \newcommand{\Nonei}{{\color{infa}None}} 147 | \newcommand{\whilei}{{\color{infa}while}} 148 | \newcommand{\andi}{{\color{infa}and}} 149 | \newcommand{\fromi}{{\color{infa}from}} 150 | \newcommand{\importi}{{\color{infa}import}} 151 | \newcommand{\continuei}{{\color{infa}continue}} 152 | \newcommand{\mapi}{{\color{infa}map}} 153 | \newcommand{\Falsei}{{\color{infa1}False}} 154 | \newcommand{\listi}{{\color{infa}list}} 155 | \newcommand{\Truei}{{\color{infa1}True}} 156 | \newcommand{\mini}{{\color{infa1}min}} 157 | \newcommand{\breaki}{{\color{infa1}break}} 158 | 159 | 160 | \newenvironment{infa}[1]{ 161 | 162 | \vspace{0.5cm} 163 | \addtocounter{infa}{1}% 164 | \noindent{\large \textbf{Программа №\thesection.\arabic{infa}.}\ \textbf{#1}}% 165 | \begin{alltt}% 166 | }{\end{alltt} 167 | \setcounter{num}{0} 168 | \vspace{0.1cm}} 169 | \newenvironment{infanoname}{ 170 | 171 | %\vspace{0.5cm} 172 | %\addtocounter{infa}{1}% 173 | %\noindent{\large \textbf{Программа №\thesection.\arabic{infa}.}\ \textbf{#1}}% 174 | \begin{alltt}% 175 | }{\end{alltt} 176 | \setcounter{num}{0} 177 | \vspace{0.1cm}} 178 | 179 | \usepackage{animate} % Для добавления гифок 180 | \usepackage{xmpmulti} 181 | %Пример кода: 182 | %\begin{infa}{Поразрядная сортировка} 183 | % \ \num \defi count_sort(a):\tab \com{определяет нашу функцию} 184 | % \ \num \tab m = \maxi(a)+1 185 | % \ \num \tab q = [0]*m 186 | % \ \num \tab \fori x \ini a: 187 | % \ \num \tab \tab q[x] += 1 188 | % \ \num \tab pos = 0 189 | % \ \num \tab \fori x \ini q: 190 | % \ \num \tab \tab \fori i \ini \rangei(q[x]): 191 | % \ \num \tab \tab \tab a[pos] = x 192 | % \num \tab \tab \tab pos += 1 193 | %\end{infa} 194 | 195 | \usepackage[left=1.27cm,right=1.27cm,top=1.27cm,bottom=2cm]{geometry} 196 | %\hbox to\textwidth{команда колонтитула} 197 | 198 | \usepackage{verbatim} 199 | \begin{document} 200 | \newcounter{lec} 201 | \newcommand{\lec}[1]{\addtocounter{lec}{1} \setcounter{section}{0}% 202 | \begin{center} 203 | {\LARGE ЛЕКЦИЯ \arabic{lec}% 204 | \vspace{2mm}% 205 | 206 | \textbf{#1}% 207 | } 208 | \end{center} 209 | } 210 | \newpage 211 | \ 212 | \setcounter{lec}{24} 213 | \lec{Z--функция строки и ее вычисление} 214 | Основной материал лекции взят с \href{http://e-maxx.ru/algo/z_function}{сайта}. 215 | \section{Z--функция} 216 | \subsection{Определение} 217 | Пусть дана строка $s$ длины $n$. Тогда Z--функция от этой строки --- это массив длины $n$, i-ый элемент которого равен наибольшему числу символов, начиная с позиции i, совпадающих с первыми символами строки $s$. 218 | 219 | Иными словами, \texttt{z[i]} -- это наибольший общий префикс строки $s$ и её i--го суффикса. 220 | 221 | Во избежание неопределённости, мы будем считать строку 0--индексированной --- т.е. первый символ строки имеет индекс 0, а последний --- $n-1$. 222 | 223 | Первый элемент Z--функции, \texttt{z[0]}, обычно считают неопределённым. Мы будем считать, что он равен нулю. 224 | 225 | \subsection{Реализация} 226 | \subsubsection{Тривиальный алгоритм} 227 | \begin{infa}{Тривиальный алгоритм} 228 | \num \defi z_function_trivial(s): 229 | \num \tab n = \leni(s) 230 | \num \tab z = [0]*n 231 | \num \tab i = 1 232 | \num \tab \whilei i < n: 233 | \num \tab \tab \whilei i + z[i] < n \andi s[z[i]] == s[i+z[i]]: \com{Пока мы не дошли до\\\phantom{3\ \ \ \ \ \ \ } конца и символ на позиции z[i] равен символу на рассматриваемой позиции + z[i]\\\phantom{3\ \ \ \ \ \ \ } (т.е., это и есть основная проверка)} 234 | \num \tab \tab \tab z[i] += 1 235 | \num \tab \tab i += 1 236 | \num \tab \returni z 237 | \end{infa} 238 | Сложность такого алгоритма $O(N^2)$. 239 | 240 | \subsubsection{Эффективный алгоритм} 241 | Чтобы получить эффективный алгоритм, будем вычислять значения \texttt{z[i]} по очереди — от i=1 до $n-1$, и при этом постараемся при вычислении очередного значения \texttt{z[i]} максимально использовать уже вычисленные значения. 242 | \begin{infa}{Эффективная реализация Z--функции} 243 | \ \num \defi z_function(s): 244 | \ \num \tab z = [0]*\leni(s) 245 | \ \num \tab left = 0 246 | \ \num \tab right = 0 247 | \ \num \tab x = 0 248 | \ \num \tab \fori i \ini \rangei(1, \leni(s)): 249 | \ \num \tab \tab \ifi i <= right: 250 | \ \num \tab \tab \tab x = \mini(z[i-left], right - i + 1) 251 | \ \num \tab \tab \elsei: 252 | \num \tab \tab \tab x = 0 253 | \num \tab \tab \whilei i+x < \leni(s) \andi s[x] == s[i+x]: 254 | \num \tab \tab \tab x += 1 255 | \num \tab \tab \ifi i + x - 1 > right: 256 | \num \tab \tab \tab left, right = i, i + x - 1 257 | \num \tab \tab z[i] = x 258 | \num \tab \returni z 259 | \end{infa} 260 | Этот алгоритм выполняется за линейное время. 261 | 262 | \subsection{Применение} 263 | Применения Z--функции: 264 | \begin{itemize} 265 | \item Поиск подстроки в строке. 266 | \item Поиск количества различных подстрок в строке. 267 | \item Сжатие строки. 268 | \end{itemize} 269 | 270 | Запишем реализацию поиска количества различных подстрок в строке. 271 | \begin{infa}{Поиск количества различных подстрок в строке} 272 | \ \num \defi count_different_substrings(s): 273 | \ \num \tab n = \leni(s) 274 | \ \num \tab start = s[0] 275 | \ \num \tab res = 0 276 | \ \num \tab \fori i \ini \rangei(1, n): 277 | \ \num \tab \tab t = start[::-1] 278 | \ \num \tab \tab k = \leni(t) - \maxi(z_function(t)) 279 | \ \num \tab \tab res += k 280 | \ \num \tab \tab start += s[i] 281 | \num \tab \returni res 282 | \end{infa} 283 | 284 | 285 | 286 | 287 | 288 | 289 | \begin{center} 290 | \vfill \emph{{\small Г. С. Демьянов, \href{https://vk.com/id37346992}{VK}\\ 291 | С. С. Клявинек, \href{https://vk.com/id85132547}{VK}\\ 292 | А. С. Кожарин, \href{https://vk.com/id92540660}{VK} 293 | }} 294 | \end{center} 295 | 296 | 297 | 298 | 299 | 300 | \end{document} -------------------------------------------------------------------------------- /lection_27/lection_27.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | 3 | %%% Работа с русским языком % для pdfLatex 4 | \usepackage{cmap} % поиск в~PDF 5 | \usepackage{mathtext} % русские буквы в~фомулах 6 | \usepackage[T2A]{fontenc} % кодировка 7 | \usepackage[utf8]{inputenc} % кодировка исходного текста 8 | \usepackage[english,russian]{babel} % локализация и переносы 9 | \usepackage{indentfirst} % отступ 1 абзаца 10 | 11 | %%% Работа с русским языком % для XeLatex 12 | %\usepackage[english,russian]{babel} %% загружает пакет многоязыковой вёрстки 13 | %\usepackage{fontspec} %% подготавливает загрузку шрифтов Open Type, True Type и др. 14 | %\defaultfontfeatures{Ligatures={TeX},Renderer=Basic} %% свойства шрифтов по умолчанию 15 | %\setmainfont[Ligatures={TeX,Historic}]{Times New Roman} %% задаёт основной шрифт документа 16 | %\setsansfont{Comic Sans MS} %% задаёт шрифт без засечек 17 | %\setmonofont{Courier New} 18 | %\usepackage{indentfirst} 19 | %\frenchspacing 20 | 21 | %%% Дополнительная работа с математикой 22 | \usepackage{amsfonts,amssymb,amsthm,mathtools} 23 | \usepackage{amsmath} 24 | \usepackage{icomma} % "Умная" запятая: $0,2$ --- число, $0, 2$ --- перечисление 25 | \usepackage{upgreek} 26 | 27 | %% Номера формул 28 | %\mathtoolsset{showonlyrefs=true} % Показывать номера только у тех формул, на которые есть \eqref{} в~тексте. 29 | 30 | %%% Страница 31 | \usepackage{extsizes} % Возможность сделать 14-й шрифт 32 | 33 | %% Шрифты 34 | \usepackage{euscript} % Шрифт Евклид 35 | \usepackage{mathrsfs} % Красивый матшрифт 36 | 37 | %% Свои команды 38 | \DeclareMathOperator{\sgn}{\mathop{sgn}} % создание новой конанды \sgn (типо как \sin) 39 | \usepackage{csquotes} % ещё одна штука для цитат 40 | \newcommand{\pd}[2]{\ensuremath{\cfrac{\partial #1}{\partial #2}}} % частная производная 41 | \newcommand{\abs}[1]{\ensuremath{\left|#1\right|}} % модуль 42 | \renewcommand{\phi}{\ensuremath{\varphi}} % греческая фи 43 | \newcommand{\pogk}[1]{\!\left(\cfrac{\sigma_{#1}}{#1}\right)^{\!\!\!2}\!} % для погрешностей 44 | 45 | % Ссылки 46 | \usepackage{color} % подключить пакет color 47 | % выбрать цвета 48 | \definecolor{BlueGreen}{RGB}{49,152,255} 49 | \definecolor{Violet}{RGB}{120,80,120} 50 | % назначить цвета при подключении hyperref 51 | \usepackage[unicode, colorlinks, urlcolor=blue, linkcolor=blue, pagecolor=blue, citecolor=blue]{hyperref} %синие ссылки 52 | %\usepackage[unicode, colorlinks, urlcolor=black, linkcolor=black, pagecolor=black, citecolor=black]{hyperref} % для печати (отключить верхний!) 53 | 54 | 55 | %% Перенос знаков в~формулах (по Львовскому) 56 | \newcommand*{\hm}[1]{#1\nobreak\discretionary{} 57 | {\hbox{$\mathsurround=0pt #1$}}{}} 58 | 59 | %%% Работа с картинками 60 | \usepackage{graphicx} % Для вставки рисунков 61 | \graphicspath{{images/}{images2/}} % папки с картинками 62 | \setlength\fboxsep{3pt} % Отступ рамки \fbox{} от рисунка 63 | \setlength\fboxrule{1pt} % Толщина линий рамки \fbox{} 64 | \usepackage{wrapfig} % Обтекание рисунков и таблиц текстом 65 | \usepackage{multicol} 66 | 67 | %%% Работа с таблицами 68 | \usepackage{array,tabularx,tabulary,booktabs} % Дополнительная работа с таблицами 69 | \usepackage{longtable} % Длинные таблицы 70 | \usepackage{multirow} % Слияние строк в~таблице 71 | \usepackage{caption} 72 | \captionsetup{labelsep=period, labelfont=bf} 73 | 74 | %%% Оформление 75 | \usepackage{indentfirst} % Красная строка 76 | %\setlength{\parskip}{0.3cm} % отступы между абзацами 77 | %%% Название разделов 78 | \usepackage{titlesec} 79 | \titlelabel{\thetitle.\quad} 80 | \renewcommand{\figurename}{\textbf{Рис.}} %Чтобы вместо figure под рисунками писал "рис" 81 | \renewcommand{\tablename}{\textbf{Таблица}} %Чтобы вместо table над таблицами писал Таблица 82 | 83 | %%% Теоремы 84 | \theoremstyle{plain} % Это стиль по умолчанию, его можно не переопределять. 85 | \newtheorem{theorem}{Теорема}[section] 86 | \newtheorem{proposition}[theorem]{Утверждение} 87 | 88 | \theoremstyle{definition} % "Определение" 89 | \newtheorem{definition}{Определение}[section] 90 | \newtheorem{corollary}{Следствие}[theorem] 91 | \newtheorem{problem}{Задача}[section] 92 | 93 | \theoremstyle{remark} % "Примечание" 94 | \newtheorem*{nonum}{Решение} 95 | \newtheorem{zamech}{Замечание}[theorem] 96 | 97 | %%% Правильные мат. символы для русского языка 98 | \renewcommand{\epsilon}{\ensuremath{\varepsilon}} 99 | \renewcommand{\phi}{\ensuremath{\varphi}} 100 | \renewcommand{\kappa}{\ensuremath{\varkappa}} 101 | \renewcommand{\le}{\ensuremath{\leqslant}} 102 | \renewcommand{\leq}{\ensuremath{\leqslant}} 103 | \renewcommand{\ge}{\ensuremath{\geqslant}} 104 | \renewcommand{\geq}{\ensuremath{\geqslant}} 105 | \renewcommand{\emptyset}{\varnothing} 106 | 107 | %%% Для лекций по инфе 108 | \usepackage{tikz} 109 | \usetikzlibrary{graphs} 110 | \usepackage{alltt} 111 | \newcounter{infa}[section] 112 | \newcounter{num} 113 | \definecolor{infa}{rgb}{0, 0.2, 0.89} 114 | \definecolor{infa1}{rgb}{0, 0.3, 1} 115 | \definecolor{grey}{rgb}{0.5, 0.5, 0.5} 116 | \newcommand{\tab}{\ \ \ } 117 | \newcommand{\com}[1]{{\color{grey}\# #1}} 118 | \newcommand{\num}{\addtocounter{num}{1}\arabic{num}\tab} 119 | \newcommand{\defi}{{\color{infa}def}} 120 | \newcommand{\globali}{{\color{infa}global}} 121 | \newcommand{\ini}{{\color{infa}in}} 122 | \newcommand{\rangei}{{\color{infa}range}} 123 | \newcommand{\fori}{{\color{infa}for}} 124 | \newcommand{\ifi}{{\color{infa}if}} 125 | \newcommand{\elsei}{{\color{infa}else}} 126 | \newcommand{\printi}{{\color{infa1}print}} 127 | \newcommand{\enumeratei}{{\color{infa1}enumerate}} 128 | \newcommand{\maxi}{{\color{infa}max}} 129 | \newcommand{\classi}{{\color{infa}class}} 130 | \newcommand{\returni}{{\color{infa}return}} 131 | \newcommand{\elifi}{{\color{infa}elif}} 132 | \newcommand{\seti}{{\color{infa}set}} 133 | \newcommand{\noti}{{\color{infa}not}} 134 | \newcommand{\dicti}{{\color{infa}dict}} 135 | \newcommand{\zipi}{{\color{infa}zip}} 136 | \newcommand{\chri}{{\color{infa}chr}} 137 | \newcommand{\ordi}{{\color{infa}ord}} 138 | \newcommand{\leni}{{\color{infa}len}} 139 | \newcommand{\deli}{{\color{infa}del}} 140 | \newcommand{\sortedi}{{\color{infa}sorted}} 141 | \newcommand{\keyi}{{\color{infa}key}} 142 | \newcommand{\lambdai}{{\color{infa}lambda}} 143 | \newcommand{\inti}{{\color{infa}int}} 144 | \newcommand{\inputi}{{\color{infa}input}} 145 | \newcommand{\isi}{{\color{infa}is}} 146 | \newcommand{\Nonei}{{\color{infa}None}} 147 | \newcommand{\whilei}{{\color{infa}while}} 148 | \newcommand{\andi}{{\color{infa}and}} 149 | \newcommand{\fromi}{{\color{infa}from}} 150 | \newcommand{\importi}{{\color{infa}import}} 151 | \newcommand{\continuei}{{\color{infa}continue}} 152 | \newcommand{\mapi}{{\color{infa}map}} 153 | \newcommand{\Falsei}{{\color{infa1}False}} 154 | \newcommand{\listi}{{\color{infa}list}} 155 | \newcommand{\Truei}{{\color{infa1}True}} 156 | \newcommand{\mini}{{\color{infa1}min}} 157 | \newcommand{\breaki}{{\color{infa1}break}} 158 | 159 | 160 | \newenvironment{infa}[1]{ 161 | 162 | \vspace{0.5cm} 163 | \addtocounter{infa}{1}% 164 | \noindent{\large \textbf{Программа №\thesection.\arabic{infa}.}\ \textbf{#1}}% 165 | \begin{alltt}% 166 | }{\end{alltt} 167 | \setcounter{num}{0} 168 | \vspace{0.1cm}} 169 | \newenvironment{infanoname}{ 170 | 171 | %\vspace{0.5cm} 172 | %\addtocounter{infa}{1}% 173 | %\noindent{\large \textbf{Программа №\thesection.\arabic{infa}.}\ \textbf{#1}}% 174 | \begin{alltt}% 175 | }{\end{alltt} 176 | \setcounter{num}{0} 177 | \vspace{0.1cm}} 178 | 179 | \usepackage{animate} % Для добавления гифок 180 | \usepackage{xmpmulti} 181 | %Пример кода: 182 | %\begin{infa}{Поразрядная сортировка} 183 | % \ \num \defi count_sort(a):\tab \com{определяет нашу функцию} 184 | % \ \num \tab m = \maxi(a)+1 185 | % \ \num \tab q = [0]*m 186 | % \ \num \tab \fori x \ini a: 187 | % \ \num \tab \tab q[x] += 1 188 | % \ \num \tab pos = 0 189 | % \ \num \tab \fori x \ini q: 190 | % \ \num \tab \tab \fori i \ini \rangei(q[x]): 191 | % \ \num \tab \tab \tab a[pos] = x 192 | % \num \tab \tab \tab pos += 1 193 | %\end{infa} 194 | 195 | \usepackage[left=1.27cm,right=1.27cm,top=1.27cm,bottom=2cm]{geometry} 196 | %\hbox to\textwidth{команда колонтитула} 197 | 198 | \usepackage{verbatim} 199 | \begin{document} 200 | \newcounter{lec} 201 | \newcommand{\lec}[1]{\addtocounter{lec}{1} \setcounter{section}{0}% 202 | \begin{center} 203 | {\LARGE ЛЕКЦИЯ \arabic{lec}% 204 | \vspace{2mm}% 205 | 206 | \textbf{#1}% 207 | } 208 | \end{center} 209 | } 210 | \newpage 211 | \ 212 | \setcounter{lec}{26} 213 | \lec{Автоматы} 214 | \section{Машина Тьюринга} 215 | Это абстрактный исполнитель, живущий на бесконечной ленте, в клетках которой находятся буквы $\alpha$ принадлежащие фиксированному алфавиту A. Каретка машины Тьюринга может двигаться по ленте влево или вправо. Каретка может видеть, что нарисовано на ленте (на текущей клетке). Также у нее есть возможность изменять символы на ленте, т.е. она может записать, изменить. А также у нее есть состояние q. При этом это состояние принадлежит множеству допустимых состояний Q. Подмножество состояний --- состояние останова (остановки). Это подмножество конечно. Поведение этой машины детерминированно (оно задается увиденным символом и предыдущим состоянием). Она из исходного состояния переходит в новое состояние, в котором определено: 1) Состояние системы 2) Считанный символ 3) Действие. 216 | 217 | Множества Q и A конечные. Возможно очень большие, но конечные. Мощность множества --- число конечных состояний в нем. 218 | 219 | Программа, которую мы написали, не хранится нигде. Типа в памяти каретки. Нужно её куда--то записать. Самое простое --- написать не ленте. Тогда каретка, которая едет на двух лентах сразу --- универсальная (программируемая) машина Тьюринга. О скорости работы нет разговора. Есть вопрос о вычислимости алгоритма. 220 | \section{Вычислимость функций (алгоритмов)} 221 | Что по сути такое алгоритм? Есть определенные возможные входные данные. Есть множество значений --- множество возможных результатов. Алгоритм --- своего рода функция, которая переводит множество определения в множество значений. Но невычислимые функции. Вычислимые функции (алгоритмы) --- это алгоритмы. Функции называются вычислимыми, если есть возможность посчитать её через машину Тьюринга. То, что мы называем раличными алгоритмами (все виды сортировок) --- это, с точки зрения вычислимости - один алгоритм. Нам ведь не важен путь (как и не важна скорость). Нам важно, что есть возможность получить результат, не более того. А какие алгоритмы невычислимые? Например, доказано, что нельзя вычислить вычислимость программы. Т.е. невозможно написать программу, которая посчитает, закончится программа или нет. 222 | 223 | Исполнители А и В называются алгоритмически эквивалентными, если можно сэмулировать А на В и В на А. 224 | 225 | \section{Клеточные автоматы. Игра жизнь Джона Конвая} 226 | Простейшие автоматы --- это клетки, живущие не линии. В клетках --- нули и единицы. Состояние клетки зависит только от самой клетки и от двух ее ближайших соседей. В каждый следующий момент времени клетка меняет свое состояние в зависимости от своего и соседей состояний. При этом для всех клеток алгоритмы одинаковы. Всего есть 256 клеточных автоматов (возможных комбинаций для данных состояний триад клеток). Среди них есть и совсем простые. Интересны несколько из них. Одно --- правило 30, т.к. порождает случайные хаотические структуры. Также есть правила жизни Джона Конвея. Если клетка была жива, то остается живой при 2 или 3 соседях. А если была мертва, то оживает при наличии трех соседей. 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | \begin{center} 258 | \vfill \emph{{\small Г. С. Демьянов, \href{https://vk.com/id37346992}{VK}\\ 259 | С. С. Клявинек, \href{https://vk.com/id85132547}{VK}\\ 260 | А. С. Кожарин, \href{https://vk.com/id92540660}{VK} 261 | }} 262 | \end{center} 263 | \end{document} -------------------------------------------------------------------------------- /rst_test/howto.txt: -------------------------------------------------------------------------------- 1 | pandoc -f rst -t latex -o lab3.tex lab3.rst.example 2 | --------------------------------------------------------------------------------