This shows you the differences between two versions of the page.
pa:laboratoare:laborator-03 [2021/03/25 01:18] darius.neatu [SSM] |
pa:laboratoare:laborator-03 [2023/03/15 16:54] (current) radu.nichita |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Laborator 3: Programare Dinamică ====== | + | ====== Laborator 03: Programare Dinamică (1/2) ====== |
- | Responsabili: | + | |
- | * [[neatudarius@gmail.com|Darius-Florentin Neațu (2017-2021)]] | + | |
- | * [[radunichita99@gmail.com | Radu Nichita (2021)]] | + | |
- | * [[cristianolaru99@gmail.com | Cristian Olaru (2021)]] | + | |
- | * [[mirunaelena.banu@gmail.com | Miruna-Elena Banu (2021)]] | + | |
- | * [[maraioana9967@gmail.com | Mara-Ioana Nicolae (2021)]] | + | |
- | * [[stefanpopa2209@gmail.com | Ștefan Popa (2018-2020)]] | + | |
- | + | ||
- | Autori: | + | |
- | * [[neatudarius@gmail.com|Darius-Florentin Neațu (2018)]] | + | |
- | * [[visanr95@gmail.com|Radu Vișan (2018)]] | + | |
- | * [[cristb@gmail.com|Cristian Banu (2018)]] | + | |
- | * [[razvan.ch95@gmail.com|Răzvan Chițu (2018)]] | + | |
===== Obiective laborator ===== | ===== Obiective laborator ===== | ||
Line 78: | Line 65: | ||
Pentru o problemă dată, este **posibil** să găsim **mai multe recurențe corecte **(mai multe soluții posibile). Evident, criteriul de alegere între acestea va fi cel bazat pe complexitate. | Pentru o problemă dată, este **posibil** să găsim **mai multe recurențe corecte **(mai multe soluții posibile). Evident, criteriul de alegere între acestea va fi cel bazat pe complexitate. | ||
</note> | </note> | ||
+ | |||
+ | |||
===== Categoria 1: SSM ===== | ===== Categoria 1: SSM ===== | ||
Aceste recurențe au o oarecare asemănare cu problema SSM (enunț + soluție). | Aceste recurențe au o oarecare asemănare cu problema SSM (enunț + soluție). | ||
+ | |||
+ | |||
+ | |||
+ | <note> | ||
+ | ATENȚIE! Rețineți diferența între următoarele 2 noțiuni! | ||
+ | |||
+ | |||
+ | * **subsecvență** ([[https://en.wikipedia.org/wiki/Substring | substring]] în engleză) pentru un vector ** v ** înseamnă un alt vector $u = [v[i], v[i+1],..., v[j]]$ unde $i <= j$. | ||
+ | |||
+ | * **subșir** ([[https://en.wikipedia.org/wiki/Subsequence | subsequence]] în engleză) pentru un vector ** v ** înseamnă un alt vector $u = [v[i_1], v[i_2],..., v[i_k]]]$ unde $i_1 < i_2 < ... < i_k$. | ||
+ | </note> | ||
==== SSM ==== | ==== SSM ==== | ||
Line 86: | Line 86: | ||
Fie un vector $ v $ cu $ n $ elemente întregi. O subsecvență de numere din șir este de forma: $v_i, v_{i+1}, ... , v_j$ ($i <= j$), având suma asociată $s_{ij} = v_i + v_{i+1} + ... + v_j$. O subsecvență ** nu ** poate fi vidă. | Fie un vector $ v $ cu $ n $ elemente întregi. O subsecvență de numere din șir este de forma: $v_i, v_{i+1}, ... , v_j$ ($i <= j$), având suma asociată $s_{ij} = v_i + v_{i+1} + ... + v_j$. O subsecvență ** nu ** poate fi vidă. | ||
- | <note> | + | |
- | **subsecvență** (**subsequence** în engleză) pentru un vector ** v ** înseamnă un alt vector $u = [v[i], v[i+1],..., v[i+k]]]$ unde $k k>=1$. | + | |
- | </note> | + | |
=== Cerință === | === Cerință === | ||
Line 227: | Line 225: | ||
=== Enunț === | === Enunț === | ||
Fie un vector $ v $ cu $ n $ elemente întregi. Un subșir de numere din șir este de forma: $v_{i_1}, v_{i_2}, ... , v_{i_k}$. Un subșir ** nu ** poate fi vid ($k >= 1$). | Fie un vector $ v $ cu $ n $ elemente întregi. Un subșir de numere din șir este de forma: $v_{i_1}, v_{i_2}, ... , v_{i_k}$. Un subșir ** nu ** poate fi vid ($k >= 1$). | ||
- | |||
- | <note> | ||
- | **subșir** (**subsequence** în engleză) pentru un vector ** v ** înseamnă un alt vector $u = [v[i_1], v[i_2],..., v[i_k]]]$ unde $i_1 < i_2 < ... < i_k$. | ||
- | </note> | ||
=== Cerința === | === Cerința === | ||
Line 314: | Line 308: | ||
* presupune inductiv că avem rezolvate toate subproblemele mai mici | * presupune inductiv că avem rezolvate toate subproblemele mai mici | ||
* în cazul SCMAX, presupunem că avem calculate $ dp[1], dp[2], ..., dp[i-1] $ și dorim să calculăm $ dp[i] $ (cunoaștem cea mai bună soluție folosind primele j elemente și vedem dacă elementul de pe poziția i o poate îmbunătăți - $j = 1:i-1$) | * în cazul SCMAX, presupunem că avem calculate $ dp[1], dp[2], ..., dp[i-1] $ și dorim să calculăm $ dp[i] $ (cunoaștem cea mai bună soluție folosind primele j elemente și vedem dacă elementul de pe poziția i o poate îmbunătăți - $j = 1:i-1$) | ||
- | * deoarece nu știm unde e cel mai bine să îl pune pe $v[i]$ (după care v[j]?), încercăm pentru toate valorile posibile ale lui j (unde $j = 1 : n - 1$) | + | * deoarece nu știm unde e cel mai bine să îl pune pe $v[i]$ (după care v[j]?), încercăm pentru toate valorile posibile ale lui j (unde $j = 1 : i - 1$) |
* **dacă $v[j] < v[i] $**, atunci subșirul crescător care se termină pe poziția j, poate fi extins la dreapta cu elementul v[i], generând lungimea ** dp[j] + 1 ** | * **dacă $v[j] < v[i] $**, atunci subșirul crescător care se termină pe poziția j, poate fi extins la dreapta cu elementul v[i], generând lungimea ** dp[j] + 1 ** | ||
* deci dp[i] = max(dp[j] + 1), $j = 1 : i - 1$ (dacă nu există un astfel de j, valoarea lui max(...) este 0) | * deci dp[i] = max(dp[j] + 1), $j = 1 : i - 1$ (dacă nu există un astfel de j, valoarea lui max(...) este 0) | ||
- | * Ce se întamplă totuși dacă nu există un j care să îndeplinească condiția de mai sus? Atunci $v[i]$ va forma singur un subșir crescător de lungime 1 (care poate fi la un pas ulterior) | + | * Ce se întamplă totuși dacă nu există un j care să îndeplinească condiția de mai sus? Atunci $v[i]$ va forma singur un subșir crescător de lungime 1 (care poate fi folosit la un pas ulterior) |
Reunind cele spuse mai sus: | Reunind cele spuse mai sus: | ||
* $dp[1] = 1$ | * $dp[1] = 1$ | ||
- | * $dp[i] = 1 + max(dp[j])$, unde $j = 1 : i-1$ **și** $v[j] < v[i]$ | + | * $dp[i] = 1 + max(dp[j])$, unde $j = 1 : i-1$ **și** $v[j] < v[i]$; $i=2:n$ |
== Implementare recurență == | == Implementare recurență == | ||
Line 482: | Line 476: | ||
| | ||
Reunind cele spuse mai sus, obținem: | Reunind cele spuse mai sus, obținem: | ||
- | * $dp[0][cap] = 0$, pentru $cap = 0 : G$ | + | * $dp[0][cap] = 0$, pentru $cap = 0 : W$ |
- | * $dp[i][cap] = max(dp[i - 1], cap], dp[i - 1][cap - w_i] + p_i)$ | + | * $dp[i][cap] = max(dp[i - 1][cap], dp[i - 1][cap - w_i] + p_i)$ |
* pentru $i = 1: n$, $cap = 0:W$ | * pentru $i = 1: n$, $cap = 0:W$ | ||