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>