Metody i algorytmy podejmowania decyzji
1. Wieloetapowe PD — Programowanie dynamiczne
Sformułowanie problemu
- x₀ — stan startowy
- xn+1 = f(xn, un) — równanie stanu
- φ(xn, un-1) — koszt kroku
\[ \overline{u}_N \triangleq (u_0, u_1, \ldots, u_{N-1}) \]
tak aby minimalizować:
\[ Q^N(\overline{u}_N) = \sum_{n=1}^{N} \varphi(x_n, u_{n-1}) \]
Zasada optymalności Bellmana
Jeśli optymalny proces decyzyjny przerwiemy w chwili n w stanie xn, a następnie ponownie go podejmiemy przyjmując xn za stan początkowy, to dalszy ciąg procesu będzie taki sam, jaki byłby gdyby nie przerywać procesu z x₀. Stan xn w pełni determinuje dalszy proces — zawiera pełną informację o poprzednich decyzjach.
Algorytm — przebieg wstecz
\[ Q_N(\overline{u}_N) = \sum_{n=0}^{N-1} g(x_n, u_n), \qquad V_N(x_0) = \min_{\overline{u}_N} Q_N(\overline{u}_N) \]
n = N−1:
\[ V_1(x_{N-1}) = \min_{u_{N-1}} g(x_{N-1}, u_{N-1}) \longrightarrow u^*_{N-1} = \Psi_{N-1}(x_{N-1}) \]
n = N−2:
\[ V_2(x_{N-2}) = \min_{u_{N-2}}\left[g(x_{N-2}, u_{N-2}) + V_1\!\left(x_{N-1} = f(x_{N-2}, u_{N-2})\right)\right] \longrightarrow u^*_{N-2} = \Psi_{N-2}(x_{N-2}) \]
n = 0:
\[ V_N(x_0) = \min_{u_0}\left[g(x_0, u_0) + V_{N-1}(x_1 = f(x_0, u_0))\right] \longrightarrow u^*_0 = \Psi_0(x_0) \]
Przebieg w przód (odtworzenie rozwiązania)
u*₁ = Ψ₁(x₁) ← x₁ = f(x₀, u*₀)
u*₂ = Ψ₂(x₂) ← x₂ = f(x₁, u*₁)
⋮
u*N-1 = ΨN-1(xN-1) ← xN-1 = f(xN-2, u*N-2)
2. Wielokryterialne PD (MCDM)
\( \mathbf{y} = [y^{(1)},\ldots,y^{(k)}]^T \) — wektor k kryteriów, \( y^{(i)} = f^{(i)}(u) \), \( F: U \rightarrow Y \)
Front Pareto
Ocena y dominuje ŷ jeśli:
\[ \begin{cases} \forall i \in \overline{1,k}: y^{(i)} \leq \hat{y}^{(i)} \\ \exists i \in \overline{1,k}: y^{(i)} < \hat{y}^{(i)} \end{cases} \]
Front Pareto = zbiór wszystkich ocen niezdominowanych przez żadną inną z Y. Decyzje odpowiadające zbiorowi Pareto są Pareto optymalne.
Skalaryzacja — metody sprowadzania do problemów jednokryterialnych
(a) Ważona suma kryteriów jednorodnych:
\[ G(u) = \sum_{i=1}^{k} w_i f^{(i)}(u), \quad w_i \geq 0,\; \sum_{i=1}^k w_i = 1 \]
(b) Ważona suma kryteriów niejednorodnych:
\[ G(u) = \sum_{i=1}^{k} w_i \frac{f^{(i)}(u)}{f^{(i)*}}, \quad f^{(i)*} = \min_{u \in U} f^{(i)}(u) \]
(c) Optymalizacja celu głównego: i-te kryterium jako cel główny, pozostałe jako ograniczenia:
\[ \min_{u \in U} f^{(i)}(u) \quad \text{s.t.} \quad \forall l \neq i: f^{(l)}(u) \leq b_l \]
(d) Minimalizacja odległości od punktu referencyjnego:
\[ \min_{u \in U} \|y - \bar{y}\|, \qquad \bar{y} = [f^{(1)*}(u) \;\; f^{(2)*}(u) \;\; \ldots \;\; f^{(k)*}(u)]^T \]
Metoda AHP (Analytic Hierarchy Process)
Rozważamy n wariantów decyzyjnych u ∈ U ≜ {u₁,…,uₙ}. Wartości kryteriów f⁽ⁱ⁾(u) nie muszą być liczbowe.
Skala Saatiego do porównań parami:
| Ocena słowna | Ocena liczbowa |
|---|---|
| Równie preferowane | 1 |
| Nieznacznie preferowane | 2, 3 |
| Silnie preferowane | 4, 5 |
| Bardzo silnie preferowane | 6, 7 |
| Nadzwyczaj preferowane | 8, 9 |
Macierz porównań kryteriów M⁽⁰⁾ = [m⁽⁰⁾hl]: mhh=1, mhl=1/mlh, mhl=mhp·mpl (spójność)
Macierz porównań wariantów M⁽ⁱ⁾ = [m⁽ⁱ⁾jl] dla każdego kryterium i: analogiczna struktura.
- Normalizacja: \( \overline{m}^{(0)}_{hl} = \frac{m^{(0)}_{hl}}{c^{(0)}_l} \), gdzie \( c^{(0)}_l = \sum_h m^{(0)}_{hl} \)
- Średnie wierszowe: \( s^{(0)}_h = \frac{1}{k}\sum_{l=1}^k \overline{m}^{(0)}_{hl} \) — waga kryterium h; \( s^{(i)}_j = \frac{1}{n}\sum_{l=1}^n \overline{m}^{(i)}_{jl} \) — pozycja wariantu j
- Ranking końcowy: \( r_j = \sum_{h=1}^k s^{(0)}_h \cdot s^{(h)}_j \) — globalna ocena wariantu j
Sprawdzanie spójności: \( CR = \frac{CI}{RI} \leq 0{,}1 \), gdzie \( CI = \frac{\sum_l c^{(0)}_l \cdot s^{(0)}_l - k}{k-1} \)
| n | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| RI | 0 | 0 | 0.58 | 0.90 | 1.12 | 1.24 | 1.32 | 1.41 | 1.45 | 1.49 |
Metoda ELECTRE I
- Ustal wagi kryteriów wi: \( \sum_{i=1}^k w_i = 1 \)
- Oblicz relację: \( \varphi_i(u_j, u_l) = \begin{cases}1 & f^{(i)}(u_j) \geq f^{(i)}(u_l) \\ 0 & \text{wpp}\end{cases} \)
- Oblicz współczynnik zgodności: \( c(u_j, u_l) = \sum_{i=1}^k w_i \varphi_i(u_j, u_l) \)
- Wyznacz zbiór zgodności: \( C_s = \{(u_j, u_l): c(u_j, u_l) \geq s\} \), gdzie próg s ∈ [½, 1]
- Wyznacz zbiór niezgodności: \( D_v = \{(u_j, u_l) \in C_s: \exists f^{(i)}: f^{(i)}(u_l) > f^{(i)}(u_j) + v_i\} \), gdzie vi — próg weta
- Relacja przewyższania: S(s,v) = Cs − Dv
- Utwórz ranking — N podzbiorów wariantów, elementy pary z relacji S w sąsiednich podzbiorach
3. Algorytm rozdziału zasobów — operacje niezależne
Algorytm oparty na dwóch przesłankach: (1) najkrótszy czas T* gdy wszystkie operacje trwają tyle samo, (2) należy wykorzystać wszystkie zasoby U.
\[ \begin{cases} \forall i \in \{1,\ldots,n\}: \gamma_i(u^*_i; a_i) = T^* \\ \sum_{i=1}^n u^*_i = U \end{cases} \]
Algorytm (3 kroki):
- Wyznacz u*i za pomocą funkcji odwrotnych: \( \forall i: u^*_i = \gamma^{-1}_i(T^*; a_i) \)
- Rozwiąż równanie \( \sum_{i=1}^n \gamma^{-1}_i(T^*; a_i) = U \) i wyznacz \( T^* = G(U, a_1, \ldots, a_n) \)
- Oblicz: \( u^*_i = \gamma^{-1}_i(G(U, a_1, \ldots, a_n); a_i) \triangleq \eta_i(U, a_1, \ldots, a_n) \)
Warunek stosowania: istnienie γ⁻¹i oraz G.
Przykład: rozdział pamięci RAM między procesory — U = całkowita RAM, vi = wielkość zadania dla procesora i. Im więcej RAM, tym krótszy czas wykonania.
4. Algorytm rozdziału zasobów — operacje o dowolnej strukturze
Algorytm 3-krokowy: dekompozycja → alokacja lokalna → koordynacja.
Krok 1: Dekompozycja struktury na przedziały
Przedziały wyznaczane są przez zdarzenia (węzły) grafu kompleksu operacji:
l — liczba zdarzeń (wierzchołków grafu); j ∈ {1,…,l−1}
Krok 2: Alokacja w j-tym przedziale (jak dla niezależnych)
Dodatkowe oznaczenia:
- Uj = {uij: i ∈ Sj} — zasoby w przedziale j
- xij — rozmiar operacji i w przedziale j; Xj = {xij: i ∈ Sj}
- Tij = γi(uij, xij) — czas wykonania części operacji i w przedziale j
\[ T^j = F_j(U_j, X_j) = \max_{i \in S_j}[\gamma_i(u_{ij}, x_{ij})] \]
Rozwiązanie dla j-tego przedziału \( \forall i \in S_j: u^*_{ij}(X_j) = \eta_j(X_j; U) \) z układu równań:
\[ \begin{cases} \sum_{i \in S_j} u^*_{ij} = U \\ \gamma_i(u^*_{ij}; x_{ij}) = T^{j*} \quad i \in S_j \end{cases} \]
Krok 3: Koordynacja — wyznaczenie X*
\[ T(X^*_1,\ldots,X^*_{l-1}) = \min_{X_1,\ldots,X_{l-1}} \sum_{j=1}^{l-1} G_j(X_j; U) \]
Ograniczenia: xij ≥ 0; \( \sum_{j \in Q_i} x_{ij} = v_i \) (suma rozmiarów operacji i po wszystkich przedziałach = vi)
5. Algorytm Ibarry dla R||Cmax
Algorytm przybliżony dla szeregowania zadań niezależnych na maszynach dowolnych. Złożoność O(n), aproksymowalność: \( C^{\text{Ibarra}}_{\max} \leq m \cdot C^*_{\max} \)
2. Podstaw uij := 0
3. DLA j = 1 DO n WYKONAJ
4. Znajdź najmniejszy indeks l maszyny dla której:
∀i ≠ l: Tl + plj ≤ Ti + pij
Podstaw Tl := Tl + plj oraz ulj := 1
// Przydziel zadanie j do maszyny z minimalnym przyszłym obciążeniem
6. Algorytm Johnsona dla F2||Cmax
Problem przepływowy dla 2 maszyn dedykowanych. Algorytm optymalny. Złożoność O(n log n).
Posortuj S₁ rosnąco wg p1j
2. Utwórz zbiór S₂ = J − S₁ (pozostałe zadania)
Posortuj S₂ malejąco wg p2j
3. Złącz: π = (S₁ ∥ S₂)
// Wynik: optymalna permutacja minimalizująca Cmax
7. Algorytm NEH dla F||Cmax (m > 2)
Dla maszyn dedykowanych, m > 2. Algorytm przybliżony, jakość typowo <2% od optimum. Złożoność O(mn²).
2. Weź 2 pierwsze — wybierz permutację (1,2) lub (2,1) z mniejszym Cmax
3. DLA k := 3 DO n WYKONAJ
4. Wstaw k-te zadanie do każdej z k możliwych pozycji
Zachowaj pozycję dającą najmniejszy Cmax
// Wynik dla k = n: permutacja NEH
8. Algorytm najtańszego włączania dla TSP
Cheapest Insertion Algorithm — algorytm przybliżony. Złożoność O(n²log n), aproksymowalność ε = 2 (QINS ≤ 2·Q*).
2. Wybierz miasto k ∈ U₂ jako start cyklu
U₂ := U₂ − {k}, U₁ := (k)
3. Znajdź l ∈ U₂ z minimalnym clk + ckl
U₂ := U₂ − {l}, U₁ := (k → l → k)
4. Znajdź łuk (g→h) ∈ U₁ i miasto m ∈ U₂
minimalizujące: cgm + cmh − cgh // koszt wstawienia m między g i h
5. U₂ := U₂ − {m}, U₁ := (k→⋯→g→m→h→⋯→k)
6. JEŚLI U₂ = ∅ → zakończ (wynik w U₁), WPORZĄDKU → wróć do kroku 4
9. Algorytm 2-optymalny dla TSP
Algorytm r-optymalny — startuje z rozwiązania dopuszczalnego (np. z najtańszego włączania), następnie poprawia przez wymianę krawędzi. Złożoność O(n²log n), aproksymowalność ε = 2.
2. Dwie niesąsiadujące krawędzie są usuwane i zastępowane przez inne
tak, aby zachować cykl Hamiltona o mniejszej wartości kryterium
3. Wykonuj wszystkie możliwe wymiany: jest ich (n−3)n/2
4. Powtarzaj aż do braku poprawy
10. Algorytm zachłanny dla 0-1 KP
Algorytm przybliżony. Złożoność O(n log n), aproksymowalność ε = 2.
2. Posortuj elementy malejąco wg wi/vi
3. Wkładaj elementy do plecaka w tej kolejności, aż do wypełnienia
Przykład (V=10):
| i | vi | wi | wi/vi | Kolejność | ui |
|---|---|---|---|---|---|
| 1 | 3 | 5 | 1.67 | I | 1 |
| 4 | 6 | 4 | 0.67 | II | 1 |
| 2 | 4 | 3 | 0.75 | III | 0 |
| 3 | 2 | 2 | 1.00 | IV | 0 |
| 5 | 1 | 3 | 3.00 | V | 1 |
V=10, załadowanie: i∈{1,5} (v=4), i=4 nie wchodzi (6+4>10) → Q = 5+3+4 = 12, zajętość = 1+3+6 = 10 ≤ V
11. Algorytm konstrukcyjny dla UFLP
Algorytm zachłanny dla Uncapacitated Facility Location Problem.
Zbiory pomocnicze: L' = {i ∈ L: xi=1} — uruchomione lokalizacje; C' = {j ∈ C: nie przypisany do żadnej lokalizacji}.
2. Wybierz i ∈ L−L' i podzbiór C'' ⊆ C', tak aby minimalizować:
\( (i, C'') = \arg\min_{i \in L-L',\; C'' \subseteq C'} \left(\frac{f_i + \sum_{j \in C''} c_{ij}}{|C''|}\right) \)
// Wybierz lokalizację z najmniejszym średnim kosztem na klienta
3. Uaktualnij: L' := L' ∪ {i}, C' := C' − C''
4. Powtarzaj kroki 2. i 3. aż C' = ∅
Złożoność obliczeniowa i aproksymowalność — nieokreślone analitycznie dla ogólnego przypadku.
Zestawienie algorytmów
| Algorytm | Problem | Złożoność | Typ | Aproksymacja |
|---|---|---|---|---|
| ηi (zasoby) | Alokacja niezal. | O(n) | Optymalny | — |
| Ibarra | R||Cmax | O(n) | Przybliżony | ρ = m |
| Johnson | F2||Cmax | O(n log n) | Optymalny | — |
| NEH | F||Cmax | O(mn²) | Przybliżony | <2% od opt. |
| Najtańsze włączanie | TSP | O(n²log n) | Przybliżony | ρ = 2 |
| 2-optymalny | TSP | O(n²log n) | Przybliżony | ρ = 2 |
| Zachłanny | 0-1 KP | O(n log n) | Przybliżony | ρ = 2 |
| Konstrukcyjny | UFLP | ? | Zachłanny | ? |