0/1 Hátizsák probléma megoldása dinamikus programozási példa segítségével
Mi a hátizsák probléma?
Hátizsák probléma Az algoritmus nagyon hasznos probléma a kombinatorikában. A szupermarketben n csomag van (n ≤ 100), az i csomag súlya W[i] ≤ 100, értéke V[i] ≤ 100. A tolvaj behatol a szupermarketbe, a tolvaj nem tud M-nél nagyobb súlyt (M ≤ 100) szállítani. ). Itt a megoldandó probléma: mely csomagokat viszi el a tolvaj, hogy a legmagasabb értéket kapja?
Bemenet:
- Maximális tömeg M és a csomagok száma n.
- W[i] súlytömb és a megfelelő V[i] érték.
output:
- Maximalizálja az értéket és a megfelelő súlyt a kapacitásban.
- Melyik csomagokat viszi el a tolvaj.
A hátizsák algoritmus további két típusra osztható:
- A 0/1 hátizsák probléma dinamikus programozással. Ebben a hátizsák-algoritmustípusban minden csomag felvehető vagy nem. Emellett a tolvaj nem vehet el egy elvitt csomag töredékét, és nem vehet el többször egy csomagot. Ezt a típust dinamikus programozási megközelítéssel lehet megoldani.
- Tört hátizsák probléma algoritmus. Ezt a típust a Greedy Strategy megoldhatja.
Hátizsákprobléma megoldása dinamikus programozással példával
Az oszd meg és uralkodj stratégiában a megoldandó problémát részproblémákra osztod. A részproblémákat tovább osztjuk kisebb részproblémákra. Ez a feladat addig folytatódik, amíg könnyen megoldható részproblémákat nem kap. Az ilyen felosztás során azonban sokszor találkozhat ugyanazzal a problémával.
A hátizsákos dinamikus programozás alapötlete, hogy egy táblázat segítségével tároljuk a megoldott részproblémák megoldásait. Ha ismételten szembesül egy részproblémával, csak a táblázatban szereplő megoldást kell átvennie anélkül, hogy újra meg kellene oldania. Ezért a dinamikus programozás által megtervezett algoritmusok nagyon hatékonyak.
Egy probléma dinamikus programozással történő megoldásához a következő feladatokat kell végrehajtania:
- Keressen megoldást a legkisebb részproblémákra.
- Találja meg a képletet (vagy szabályt), amellyel a legkisebb részproblémák megoldásán keresztül is fel lehet építeni egy részprobléma megoldását.
- Hozzon létre egy táblázatot, amely tárolja a részfeladatok megoldásait. Ezután számítsa ki a részfeladat megoldását a talált képlet alapján, és mentse el a táblázatba.
- A megoldott részproblémák közül megtalálja az eredeti probléma megoldását.
Elemezze a 0/1 hátizsák problémát
A 0/1 hátizsák-probléma dinamikus programozással történő elemzésekor észrevehető pontokat találhat. A hátizsák-algoritmus értéke két tényezőtől függ:
- Hány csomagot mérlegelnek
- A hátralévő súly, amelyet a hátizsák tárolhat.
Ezért két változó mennyisége van.
A dinamikus programozással hasznos információkkal rendelkezik:
- a célfüggvény két változó mennyiségtől fog függni
- az opciók táblázata egy 2 dimenziós táblázat lesz.
Ha a B[i][j] hívása a maximális lehetséges érték, az {1, 2, …, i} csomagok kiválasztásával j súlykorlátozással.
- A maximális érték, ha n csomagban van kiválasztva M súlykorlátozással, B[n][M]. Más szóval: Ha választható i csomagok, akkor B[i][j] az optimális súly, ha a hátizsák maximális súlya j.
- Az optimális súly mindig kisebb vagy egyenlő, mint a maximális tömeg: B[i][j] ≤ j.
Például: B[4][10] = 8. Ez azt jelenti, hogy optimális esetben a kiválasztott csomagok össztömege 8, amikor 4 első csomag közül lehet választani (1-4 csomag) és a maximális súly A hátizsákból 10. Nem szükséges, hogy mind a 4 elem ki legyen jelölve.
Képlet a B[i][j] kiszámításához
Bemenet, Ön határozza meg:
- W[i], V[i] viszont az i csomag súlya és értéke, amelyben i
{1, …, n}.
- M a maximális súly, amelyet a hátizsák elbír.
Abban az esetben, ha egyszerűen csak 1 csomag közül választhat. Minden j-re kiszámítja a B[1][j]-t: ami azt jelenti, hogy a hátizsák maximális súlya ≥ az 1. csomag súlya
B[1][j] = W[1]
A j súlykorlátozás mellett az {1, 2, …, i – 1, i} csomagok közötti optimális választásnak a legnagyobb értékhez két lehetősége van:
- Ha az i csomag nincs kiválasztva, a B[i][j] a maximálisan lehetséges érték az {1, 2, …, i – 1} csomagok közül kiválasztva j súlykorlátozással. Neked van:
B[i][j] = B[i – 1][j]
- Ha az i csomagot választjuk (természetesen csak akkor vegyük ezt az esetet, ha W[i] ≤ j), akkor B[i][j] egyenlő az i csomag V[i] értékével, plusz a maximális érték a következők közül választható ki. csomagok {1, 2, …, i – 1} súlykorlátozással (j – W[i]). Vagyis az Ön értékét tekintve:
B[i][j] = V[i] + B[i – 1][j – W[i]]
A maximális lehetséges érték B[i][j] létrehozása miatt B[i][j] lesz a fenti 2 érték maximuma.
A dinamikus programozás alapjai
Tehát mérlegelnie kell, hogy jobb-e az i csomagot választani vagy sem. Innentől kezdve megkapja a következő rekurzív képletet:
B[i][j]= max(B[i – 1][j], V[i]+B[i – 1][j – W[i]]
Könnyen belátható, hogy B[0][j] = a lehetséges maximális érték, ha 0 csomag = 0 közül választ.
Számítsa ki az opciók táblázatát
A fenti rekurzív képlet alapján összeállít egy opciótáblázatot. Annak ellenőrzésére, hogy az eredmények helyesek-e (ha nem pontosan, építse újra a B[i][j] célfüggvényt). A B[i][j] célfüggvény és az opciók táblázatának létrehozásával orientálja a nyomkövetést.
A B opciók táblázata n + 1 sort, M + 1 oszlopot tartalmaz,
- Először is a dinamikus programozás alapjaival töltve: a 0. sor minden nullát tartalmaz.
- Rekurzív képletekkel, használja a 0-s sort az 1. sor kiszámításához, használja az 1-es sort a 2. sor kiszámításához stb. … amíg az összes sort ki nem számítja.

Nyom
Az opciók táblázatának kiszámításakor a B[n][M] érdekli, ami a maximális érték, amelyet az M súlykorlátozású n csomagban történő kiválasztásnál kapunk.
- If B[n][M] = B[n – 1][M] akkor az n csomag nincs kiválasztva, nyomon követed a B[n – 1][M]-t.
- If B[n][M] ≠ B[n – 1][M], észreveszi, hogy az optimális kiválasztás az n csomaggal és a B[n – 1][M – W[n]] nyomvonallal rendelkezik.
Folytassa a nyomkövetést, amíg el nem éri a lehetőségek táblázatának 0. sorát.
Algoritmus az opciók táblázatában a kiválasztott csomagok megkereséséhez
Megjegyzés: Ha B[i][j] = B[i – 1][j], az i csomag nincs kiválasztva. B[n][W] a hátizsákba helyezett csomag optimális összértéke.
A nyomkövetés lépései:
- 1 lépés: i = n-ből kiindulva, j = M.
- 2 lépés: Nézze meg a j oszlopban alulról felfelé, megtalálja az i sort úgy, hogy B[i][j] > B[i – 1][j]. Jelölje ki a kiválasztott csomagot i: Válassza az [i] = igaz;
- 3 lépés: j = B[i][j] – W[i]. Ha j > 0, folytassa a 2. lépéssel, ellenkező esetben folytassa a 4. lépéssel
- 4 lépés: A kiválasztott csomagok nyomtatására vonatkozó lehetőségek táblázata alapján.
Java Kód
public void knapsackDyProg(int W[], int V[], int M, int n) {
int B[][] = new int[n + 1][M + 1];
for (int i=0; i<=n; i++)
for (int j=0; j<=M; j++) {
B[i][j] = 0;
}
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= M; j++) {
B[i][j] = B[i - 1][j];
if ((j >= W[i-1]) && (B[i][j] < B[i - 1][j - W[i - 1]] + V[i - 1])) {
B[i][j] = B[i - 1][j - W[i - 1]] + V[i - 1];
}
System.out.print(B[i][j] + " ");
}
System.out.print("\n");
}
System.out.println("Max Value:\t" + B[n][M]);
System.out.println("Selected Packs: ");
while (n != 0) {
if (B[n][M] != B[n - 1][M]) {
System.out.println("\tPackage " + n + " with W = " + W[n - 1] + " and Value = " + V[n - 1]);
M = M - W[n-1];
}
n--;
}
}
A hátizsák kód magyarázata:
- B[][] tábla létrehozása. Az egyes cellák alapértelmezett értéke 0.
- Építsd fel a B[][] táblázatot alulról felfelé haladva. Számítsa ki a lehetőségek táblázatát a visszakeresési képlettel!
- B[i][j] kiszámítása. Ha nem választja ki az i.
- Ezután értékelje: ha az i csomagot választja, az előnyösebb lesz, mint a B[i][j] visszaállítása.
- Kövesse nyomon a táblázatot az n sortól a 0 sorig.
- Ha az n. csomagot választja. Az n csomag kiválasztása után csak M – W[n – 1] súlyt adhat hozzá.
Ebben az oktatóanyagban két példa van. Íme a java kód a fenti program futtatásához, két példával:
public void run() {
/*
* Pack and Weight - Value
*/
//int W[] = new int[]{3, 4, 5, 9, 4};
int W[] = new int[]{12, 2, 1, 1, 4};
//int V[] = new int[]{3, 4, 4, 10, 4};
int V[] = new int[]{4, 2, 1, 2, 10};
/*
* Max Weight
*/
//int M = 11;
int M = 15;
int n = V.length;
/*
* Run the algorithm
*/
knapsackDyProg(W, V, M, n);
}
Megvan a kimenet:
- Első példa:
0 0 0 3 3 3 3 3 3 3 3 3 0 0 0 3 4 4 4 7 7 7 7 7 0 0 0 3 4 4 4 7 7 8 8 8 0 0 0 3 4 4 4 7 7 10 10 10 0 0 0 3 4 4 4 7 8 10 10 11 Max Value: 11 Selected Packs: Package 5 with W = 4 and Value = 4 Package 2 with W = 4 and Value = 4 Package 1 with W = 3 and Value = 3
- Második példa:
0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 2 2 2 2 2 2 2 2 2 2 4 4 6 6 0 1 2 3 3 3 3 3 3 3 3 3 4 5 6 7 0 2 3 4 5 5 5 5 5 5 5 5 5 6 7 8 0 2 3 4 10 12 13 14 15 15 15 15 15 15 15 15 Max Value: 15 Selected Packs: Package 5 with W = 4 and Value = 10 Package 4 with W = 1 and Value = 2 Package 3 with W = 1 and Value = 1 Package 2 with W = 2 and Value = 2

