Skip to content

Commit

Permalink
dynamic - bellman
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanIStereotekk committed Nov 18, 2024
1 parent f12e2f2 commit f109a48
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 2 deletions.
83 changes: 83 additions & 0 deletions content/dijkstra-algorythm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,86 @@ print(processed)
```
---

### Пример логического решения другой задачи с взвешенным графом:


Допустим мы имеем граф

Его вершины и веса:

```
ST >> A = 4
ST >> B = 1
ST >> F = 6
B >> F = 3
B >> C = 2
A >> C = 2
C >> F = 2
```
Для работы нам нужна структура в виде таблицы данных где мы будем хранить вычисления.

Начинаем от старта к любому, из наших трех начальных ребер: `ST >> A` , `ST >> B` , `ST >> F`

Первая итерация, кладем в очередь - вершину, вес ребра, и вершину предшественник.

Как выгдядит это:

Обходим `ST >> A = 4`, `ST >> B = 1`, `ST >> F = 6`
Важно что в очереди на выход/обработку первым - самый легкий вес, то есть первый на извлечение и обход к следующим вершинам.

`*В примере с кодом выше, в роли таблицы с очередью я использовал python dictionary - parents, neighbors, costs.
В случае примера с кодом такое решение наиболее подходящее.
Безусловно есть и другие способы решить как хранить и обрабатывать подобные данные.`

```
------------------------------------
| предшественник | вершина | вес |
--------------------------------------
| ST | B | 1 |
--------------------------------------
| ST | A | 4 |
--------------------------------------
| ST | F | 6 |
--------------------------------------
```
Первым извлекаем `ST >> B` который весит `1`, он у нас самый легкий и поэтому работаем с ним первым.

`B >> C = 2` + вес ребра предшественника, он у нас = `1`.
То есть мы на прошлой релаксации определили вес ребра
до вершины `В`.

Следовательно `B >> F = 3` + вес предшественника = `1`

И далее работаем по тому же алгоритму...
```
------------------------------------
| предшественник | вершина | вес |
--------------------------------------
| B | C | 3 |
--------------------------------------
| B | F | 4 |
--------------------------------------
```
Больше смежных ребер у `B` нет ! Следовательно переходим к другим, извлекаем из очереди самый легкий!

Дальше переходим к `C >> F = 5`.

Ребро до `F` не станем переписывать, оно тяжелее чем уже имеющееся значение `B >> F = 4`
Возвращаемся к тем ребрам которые не иследованы.

`A >> C = 2` + `4` от `ST >> A` = `6` - Не будем переписывать значение `C` = `6`
потому что есть путь легче `S >> B >> C`.

Оставим `C` весом 3, а его предшественник `B`

`C >> F` = `2` + У узла `C` уже было значение `3` от ребер `SТ >> B >> C`, что в сумме дает вес `5`,

но мы знаем что до `F` мы доберемся за вес меньше `4` по ребрам от `SТ >> B >> F`

Так мы обошли все вершины, и нашли самый легкий путь от стартового - ``, через - `B`, к - `F` финишу.

Короткое но должно быть вполне понятное объяснение происходящего в процессе работы алгоритма.



61 changes: 59 additions & 2 deletions content/dynamic-programming.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,63 @@ tags: "мемоизация, --, python"
---


#### Статья про динамическое программирование.

Скоро тут будет статья.





Это такой подход в решении в котором программист декомпозирует задачу на более простые подзадачи.
Как правило разбивая на мелкие задачи, программист уменьшает сложность, и снижает количество вычислений.
Хороший пример рекурсивное решение последовательности Фибоначчи когда программа
вызывает экспоненциально тот же стек вызовов, каждый раз вызывая уже вычисленное значение в каждом новом вызове.
Конечно такой подход не совсем оптимален с точки зрения вычислительных ресурсов.


```
def recursive_fibonacci(n):
if n <=2:
return 1
else:
return recursive_fibonacci(n - 1) + recursive_fibonacci(n - 2)
```
решение с рекурсисей

---








Мемоизация - подход в динамическом программировании когда имеет смысл сохранения вычисленных подзадач.
Какой смысл делать те же самые вычисления много раз?
Не лучше ли их записать, а в нужный момент просто извлечь готовое вычисленное решение. Конечно да !


```
def memoized_fibonacci(n):
memo = {}
if n in memo:
return memo[n]
if n <= 2 :
return 1
else:
result = memoized_fibonacci(n - 1) + memoized_fibonacci(n - 2)
memo[n] = resulter
return resulter
```
решение с мемоизацией

---

### Сверху вниз, и снизу вверх.

продолжение ....



0 comments on commit f109a48

Please sign in to comment.