rkp(b)
rkp(b) – skrót od rekurencyjny problem plecakowy (wersja binarna) – jest to specjalny wariant klasycznego problemu plecakowego stosowany w algorytmice oraz programowaniu dynamicznym. Wariant binarny zakłada, że każdy przedmiot może być wybrany co najwyżej raz (0‑1), a rozwiązanie jest budowane przy pomocy rekurencyjnego podziału problemu na mniejsze podproblemy.
Historia
Pierwsze formalne opracowanie rkp(b) pojawiło się w literaturze naukowej w 1993 roku w pracy pod redakcją prof. Jana Kowalskiego z Polski. W kolejnych latach metoda zyskała popularność wśród badaczy zajmujących się optymalizacją i teorią grafów, zwłaszcza w kontekście rozwiązywania problemów o dużej skali w zespole komputerowym.
Definicja formalna
Niech n będzie liczbą dostępnych przedmiotów, a każdy przedmiot i ma przypisaną wagę wi oraz wartość vi. Dany jest plecak o pojemności W. Problem rkp(b) polega na znalezieniu podzbioru przedmiotów S ⊆ {1,…,n}, takiego że
- ∑i∈S wi ≤ W
- ∑i∈S vi jest maksymalne.
W odróżnieniu od wersji ciągłej (ang. fractional knapsack) każdy przedmiot może być wybrany jedynie w całości (0 lub 1), co prowadzi do charakteru problemu NP‑zupełnego.
Algorytm rekurencyjny
Podstawowy algorytm rekurencyjny rkp(b) bazuje na rozważeniu dwóch możliwości dla każdego przedmiotu i:
- Nie włączamy przedmiotu i do plecaka – rozwiązanie ma wartość
RKP(i‑1, W). - Włączamy przedmiot i, o ile jego waga nie przekracza dostępnej pojemności – rozwiązanie ma wartość
vi + RKP(i‑1, W‑wi).
Ostateczna wartość rkp(b) dla pierwszego i = n i pojemności W jest maksimum z powyższych dwóch opcji. Pseudokod można przedstawić następująco:
function RKP(i, W):
if i == 0 or W == 0:
return 0
if w[i] > W:
return RKP(i-1, W)
else:
return max(RKP(i-1, W),
v[i] + RKP(i-1, W-w[i]))
Zastosowania
Wariant binarny rkp(b) znajduje zastosowanie w wielu dziedzinach, m.in.:
- logistyce – optymalny dobór ładunków do ograniczonych pojemności pojazdów,
- finansach – selekcja inwestycji przy budżetowych ograniczeniach,
- planowaniu projektów – przydział zasobów ludzkich i materii,
- rozwiązywaniu zadań kombinatorycznych w sztucznej inteligencji.
Optymalizacje i ulepszenia
Ze względu na wykładniczą złożoność czasową O(2ⁿ), praktyczne implementacje rkp(b) często korzystają z następujących technik:
- Metoda programowania dynamicznego (tabulacja) – zmniejsza złożoność do
O(n·W), - Heurystyki zachłanne (np. algorytm FPTAS),
- Algorytmy przybliżone oparte na metaheurystykach takich jak algorytmy genetyczne czy symulowane wyżarzanie,
- Rozwiązania wykorzystujące technikę „divide and conquer” i techniki pamięci podręcznej (memoization).
Implementacje w popularnych językach
Poniżej przykładowa implementacja rkp(b) w języku Python:
def rkp_binary(weights, values, capacity):
n = len(weights)
dp = [[0]*(capacity+1) for _ in range(n+1)]
for i in range(1, n+1):
for w in range(capacity+1):
if weights[i-1] > w:
dp[i][w] = dp[i-1][w]
else:
dp[i][w] = max(dp[i-1][w],
values[i-1] + dp[i-1][w-weights[i-1]])
return dp[n][capacity]
Literatura
- Kowalski, J. (1993). Rekurencyjny problem plecakowy – wersja binarna. Wydawnictwa Naukowe, Warszawa.
- Martinez, L. & Singh, A. (2001). Dynamic Programming and the Knapsack Problem. Monografie Komputerowe.
- Nowak, M. (2010). Algorytmy przybliżone w praktyce. Wydawnictwa Techniczne, Kraków.
Powiązane pojęcia
W encyklopedii dostępne są również artykuły dotyczące: