Skip to content

Динамическое программирование. Задача о количестве маршрутов. Принцип Беллмана.

Определение

Динамическое программирование - это метод решения оптимизационных задач, в которых решение можно разбить на более мелкие подзадачи, которые, в свою очередь, также можно разбить на еще более мелкие подзадачи. При этом решение каждой подзадачи используется для решения более крупных подзадач, пока не будет найдено решение всей задачи в целом.

Динамическое программирование похоже на метод «разделяй и властвуй» оба из которых решают исходную проблему путем решения подзадач. Разница в том, что алгоритм «разделяй и властвуй» будет выполнять много ненужной работы при решении подзадач, он будет многократно решать эти общие подзадачи; в то время как алгоритм динамического программирования решает каждую подзадачу только один раз, и сохраняет свое решение.

В рекурсии например результаты подзадач используется при формировании ответа, но никак не помогают при решении подзадач.

Что эффективнее?

  • рекурсия с ответом: return fibo(n-1) + fibo(n-2) без мемоизации
  • последовательное вычисление каждого числа фибоначчи, но ровно 1 раз.

Принцип оптимальности Беллмана: алгоритм считается оптимальным, если на любом его шаге для получения оптимального решения, используется результат его предыдущих решений.

Задача

Задача о количестве маршрутов: имеются несколько городов и между некоторыми из них проведены односторонние дороги так, что выехав из города, вернуться по той же дороге невозможно. Требуется найти кол-во маршрутов из одного пункта в другой.

Идея: чтобы подсчитать кол-во путей до пункта, необходимо знать сколькими способами мы можем попасть в пункты ведущие в этот и т.д.

Ход алгоритма:

  1. устанавливаем значение стартовой вершины 1
  2. проходимся по графу, например в матрице смежности и устанавливаем значение вершины как сумма значений вершин, которые ведут в неё