HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-02-26
1 <p>В этом уроке мы перейдем от теории к практике. Вы узнаете, как реализовать алгоритм Литтла в коде.</p>
1 <p>В этом уроке мы перейдем от теории к практике. Вы узнаете, как реализовать алгоритм Литтла в коде.</p>
2 <p>Чтобы реализовать алгоритм Литтла, мы написали такой объемный код:</p>
2 <p>Чтобы реализовать алгоритм Литтла, мы написали такой объемный код:</p>
3 Нажмите, чтобы увидеть код<p>В таком объемном коде сложно разобраться самостоятельно, поэтому мы подробно обсудим, что происходит на каждом шаге.</p>
3 Нажмите, чтобы увидеть код<p>В таком объемном коде сложно разобраться самостоятельно, поэтому мы подробно обсудим, что происходит на каждом шаге.</p>
4 <p>Здесь мы реализовали вспомогательный класс Node, в котором сосредоточили функции для работы с узлами дерева решений.</p>
4 <p>Здесь мы реализовали вспомогательный класс Node, в котором сосредоточили функции для работы с узлами дерева решений.</p>
5 <p>JavaScript хранит ссылку на объекты, в том числе на массивы. Если мы хотим создать копию матрицы смежности в каждом узле, мы не можем просто скопировать массив. Нужно создать новый массив и скопировать в него все значения исходного массива.</p>
5 <p>JavaScript хранит ссылку на объекты, в том числе на массивы. Если мы хотим создать копию матрицы смежности в каждом узле, мы не можем просто скопировать массив. Нужно создать новый массив и скопировать в него все значения исходного массива.</p>
6 <p>Матрица - это массив массивов. Поэтому мы выполняем<strong>глубокое копирование</strong>:</p>
6 <p>Матрица - это массив массивов. Поэтому мы выполняем<strong>глубокое копирование</strong>:</p>
7 <p>Еще нам нужно создать две функции:</p>
7 <p>Еще нам нужно создать две функции:</p>
8 <ul><li>Первая функция будет искать минимумы в каждой строке</li>
8 <ul><li>Первая функция будет искать минимумы в каждой строке</li>
9 <li>Вторая - редуцировать, то есть вычитать минимумы из каждого элемента каждой строки</li>
9 <li>Вторая - редуцировать, то есть вычитать минимумы из каждого элемента каждой строки</li>
10 </ul><p>Так выглядит реализация в коде:</p>
10 </ul><p>Так выглядит реализация в коде:</p>
11 <p>Далее мы напишем похожие функции и для столбцов. Затем реализуем метод редуцирования матрицы и по строкам и по столбцам:</p>
11 <p>Далее мы напишем похожие функции и для столбцов. Затем реализуем метод редуцирования матрицы и по строкам и по столбцам:</p>
12 <p>Последний метод в классе Node - это getCellWithMaxPenalty. Он находит ячейку матрицы с наибольшим штрафом.</p>
12 <p>Последний метод в классе Node - это getCellWithMaxPenalty. Он находит ячейку матрицы с наибольшим штрафом.</p>
13 <p>Как мы помним, метод пробегает по всем нулевым элементам и складывает минимумы в той же строке и в том же столбце. При вычислении минимума сам элемент не учитывается:</p>
13 <p>Как мы помним, метод пробегает по всем нулевым элементам и складывает минимумы в той же строке и в том же столбце. При вычислении минимума сам элемент не учитывается:</p>
14 <p>Во время работы алгоритма Литтла мы должны исключить из рассмотрения закрывающие ребра - те, которые могут завершить маршрут раньше времени.</p>
14 <p>Во время работы алгоритма Литтла мы должны исключить из рассмотрения закрывающие ребра - те, которые могут завершить маршрут раньше времени.</p>
15 <p>Для поиска закрывающих ребер напишем функцию getCloseEdges. Для ее работы реализуем вспомогательные функции findNextStartCity и findNextEndCity:</p>
15 <p>Для поиска закрывающих ребер напишем функцию getCloseEdges. Для ее работы реализуем вспомогательные функции findNextStartCity и findNextEndCity:</p>
16 <p>На каждом шаге алгоритма мы строим левое и правое поддеревья из какого-то узла дерева решений.</p>
16 <p>На каждом шаге алгоритма мы строим левое и правое поддеревья из какого-то узла дерева решений.</p>
17 <p>Вынесем код построения в функцию makeChildren. Используем написанные нами ранее методы и функции - getCellWithMaxPenalty, cloneMatrix и reduce:</p>
17 <p>Вынесем код построения в функцию makeChildren. Используем написанные нами ранее методы и функции - getCellWithMaxPenalty, cloneMatrix и reduce:</p>
18 <p>Наконец, реализуем функцию little. В стандартной библиотеке JavaScript нет структуры данных, которая представляла бы очередь с приоритетами. Поэтому мы сделаем собственную простую структуру и будем выбирать узел с наименьшей нижней границей каждом шаге алгоритма:</p>
18 <p>Наконец, реализуем функцию little. В стандартной библиотеке JavaScript нет структуры данных, которая представляла бы очередь с приоритетами. Поэтому мы сделаем собственную простую структуру и будем выбирать узел с наименьшей нижней границей каждом шаге алгоритма:</p>
19 <h2>Выводы</h2>
19 <h2>Выводы</h2>
20 <p>В этом уроке мы закончили изучать алгоритм Литтла. Теперь вы знаете, как он работает в теории и как реализовать его в коде. Повторим ключевые выводы, к которым мы пришли в прошлом теоретическом уроке:</p>
20 <p>В этом уроке мы закончили изучать алгоритм Литтла. Теперь вы знаете, как он работает в теории и как реализовать его в коде. Повторим ключевые выводы, к которым мы пришли в прошлом теоретическом уроке:</p>
21 <ul><li>Алгоритм Литтла находит оптимальное решение в дереве решений</li>
21 <ul><li>Алгоритм Литтла находит оптимальное решение в дереве решений</li>
22 <li>Для работы алгоритма важно, чтобы оценка нижней границы была корректной</li>
22 <li>Для работы алгоритма важно, чтобы оценка нижней границы была корректной</li>
23 <li>Обычно алгоритм Литтла работает быстрее метода перебора, в худшем случае - с той же скоростью O(n!)</li>
23 <li>Обычно алгоритм Литтла работает быстрее метода перебора, в худшем случае - с той же скоростью O(n!)</li>
24 </ul>
24 </ul>