Ugrás a tartalomhoz

0-1 knapsack problem

A Wikiszótárból, a nyitott szótárból


Főnév

0-1 knapsack problem (tsz. 0-1 knapsack problems)

  1. (informatika) A hátizsák probléma az operációkutatás és a kombinatorikus optimalizálás egyik legismertebb feladata. Lényege, hogy adott egy korlátozott kapacitású hátizsák, és egy sor tárgy, melyek mindegyike rendelkezik egy súllyal és értékkel. A cél az, hogy a hátizsákba pakolva a tárgyakat:
  • ne lépjük túl a maximális súlykapacitást,
  • és maximalizáljuk az összértéket.



2. A 0–1 hátizsák változat

A 0–1 knapsack változatnál minden tárgyat vagy teljesen berakunk (1), vagy egyáltalán nem (0). Nincs lehetőség részleges választásra (ellentétben a frakcionált változattal).



3. Matematikai modell

Legyen:

  • : a tárgyak száma
  • : az -edik tárgy súlya
  • : az -edik tárgy értéke
  • : a hátizsák maximális kapacitása
  • : döntési változó (1, ha az -edik tárgy bekerül, 0 különben)

A modell:



4. Példa

Adott 4 tárgy:

Tárgy Érték (v) Súly (w)
1 60 10
2 100 20
3 120 30
4 70 15

A hátizsák kapacitása: W = 50

Megoldás: válasszuk ki azokat a tárgyakat, amelyek összsúlya ≤ 50, de az összérték maximális.



5. Megoldási módszerek

🧮 1. Brute-force (erőből)

  • Minden lehetséges kombinációt kipróbál:
  • Kis -re működik, de nagyobb méretnél exponenciálisan lassú

💡 2. Dinamikus programozás (DP)

  • Optimalitás elve alapján részproblémákat old meg
  • Polinomiális idő:
  • Hatékony, ha nem túl nagy

🌲 3. Branch and Bound (B&B)

  • Teljes keresés, de részproblémák kizárása becslés alapján
  • Ténylegesen is 0–1 optimalizálásra szabott

📉 4. Heurisztikus módszerek

  • Gyors, de nem garantáltan optimális
  • Példa: Greedy algoritmus: legjobb érték/súly arány szerint pakol



6. Dinamikus programozás megközelítése

Készítsünk egy táblázatot , ahol:

  • : az első tárgy figyelembevételével
  • : a súlykapacitás

Rekurzív képlet:



7. Python megvalósítás (DP)

def knapsack(weights, values, W):
    n = len(values)
    dp = [[0] * (W+1) for _ in range(n+1)]

    for i in range(1, n+1):
        for w in range(W+1):
            if weights[i-1] <= w:
                dp[i][w] = max(dp[i-1][w], dp[i-1][w - weights[i-1]] + values[i-1])
            else:
                dp[i][w] = dp[i-1][w]
    
    return dp[n][W]

# Teszt
w = [10, 20, 30, 15]
v = [60, 100, 120, 70]
W = 50
print("Max érték:", knapsack(w, v, W))  # Várható eredmény: 170

8. Túlméretezett probléma?

  • Ha nagy szám, akkor a táblázat nagyméretű lesz → memória- és időigény nő
  • Ilyenkor memóriaoptimalizált megoldás (csak 1D tömb) vagy heurisztika javasolt



9. Kapcsolódó problémák

Probléma Rövid leírás
Frakcionált hátizsák Részleges tárgyválasztás is megengedett
Többdimenziós hátizsák Többféle korlát (pl. térfogat + súly)
Többszörös hátizsák Több hátizsák, külön korlátokkal
Többször választható Egyes tárgyakból többet is be lehet pakolni
Subset Sum Különleges eset: , célösszeg adott



10. Összefoglalás

A 0–1 knapsack probléma egy klasszikus és rendkívül fontos kombinatorikus optimalizálási feladat:

  • Bináris döntések: minden tárgy vagy bent van, vagy nincs
  • Cél: maximális érték úgy, hogy súlykorlát nem sérül
  • Hatékonyen megoldható dinamikus programozással, ha a kapacitás nem túl nagy
  • Valós életbeli alkalmazások:
    • Pénzügyi tervezés
    • Hordozható eszköz optimalizálás
    • Készletgazdálkodás
    • Adatcsomagolás