0/1 Rucksack-Problembehebung anhand eines dynamischen Programmierbeispiels

Was ist das Rucksackproblem?

Rucksackproblem Der Algorithmus ist ein sehr hilfreiches Problem in der Kombinatorik. Im Supermarkt gibt es n Pakete (n โ‰ค 100), das Paket i hat das Gewicht W[i] โ‰ค 100 und den Wert V[i] โ‰ค 100. Ein Dieb bricht in den Supermarkt ein, der Dieb kann kein Gewicht tragen, das mehr als M (M โ‰ค 100) betrรคgt ). Das hier zu lรถsende Problem lautet: Welche Pakete wird der Dieb mitnehmen, um den hรถchsten Wert zu erzielen?

Eingang:

  • Maximales Gewicht M und die Anzahl der Pakete n.
  • Array aus Gewicht W[i] und entsprechendem Wert V[i].

Ausgang:

  • Maximieren Sie den Wert und das entsprechende Gewicht in der Kapazitรคt.
  • Welche Pakete wird der Dieb mitnehmen?

Der Knapsack-Algorithmus kann weiter in zwei Typen unterteilt werden:

  • Das 0/1-Knapsack-Problem mit dynamischer Programmierung. Bei diesem Knapsack-Algorithmustyp kann jedes Paket genommen oder nicht genommen werden. AuรŸerdem darf der Dieb nicht einen Bruchteil eines Pakets mitnehmen oder ein Paket mehr als einmal mitnehmen. Dieser Typ kann durch den dynamischen Programmieransatz gelรถst werden.
  • Algorithmus fรผr fraktioniertes Knapsack-Problem. Dieser Typ kann durch Greedy Strategy gelรถst werden.

So lรถsen Sie das Rucksackproblem mithilfe dynamischer Programmierung anhand eines Beispiels

Bei der Divide-and-Conquer-Strategie teilt man das zu lรถsende Problem in Teilprobleme auf. Die Teilprobleme werden weiter in kleinere Teilprobleme unterteilt. Diese Aufgabe wird fortgesetzt, bis Sie Teilprobleme erhalten, die leicht gelรถst werden kรถnnen. Bei einer solchen Aufteilung kann es jedoch vorkommen, dass Sie mehrmals auf dasselbe Problem stoรŸen.

Die Grundidee der dynamischen Knapsack-Programmierung besteht darin, eine Tabelle zu verwenden, um die Lรถsungen gelรถster Teilprobleme zu speichern. Wenn Sie erneut auf ein Teilproblem stoรŸen, mรผssen Sie nur die Lรถsung aus der Tabelle รผbernehmen, ohne es erneut lรถsen zu mรผssen. Daher sind die durch dynamische Programmierung entwickelten Algorithmen sehr effektiv.

Lรถsen Sie das Rucksackproblem mit dynamischer Programmierung

Um ein Problem mithilfe dynamischer Programmierung zu lรถsen, mรผssen Sie die folgenden Aufgaben ausfรผhren:

  • Finden Sie Lรถsungen fรผr die kleinsten Teilprobleme.
  • Finden Sie die Formel (oder Regel) heraus, um eine Lรถsung eines Teilproblems durch Lรถsungen selbst kleinster Teilprobleme zu erstellen.
  • Erstellen Sie eine Tabelle, in der die Lรถsungen von Teilproblemen gespeichert sind. Berechnen Sie dann die Lรถsung des Teilproblems gemรครŸ der gefundenen Formel und speichern Sie sie in der Tabelle.
  • Aus den gelรถsten Teilproblemen finden Sie die Lรถsung des ursprรผnglichen Problems.

Analysieren Sie das 0/1-Rucksackproblem

Bei der Analyse des 0/1-Knapsack-Problems mithilfe der dynamischen Programmierung kรถnnen Sie einige auffรคllige Punkte feststellen. Der Wert des Rucksackalgorithmus hรคngt von zwei Faktoren ab:

  1. Wie viele Pakete werden berรผcksichtigt?
  2. Das Restgewicht, das der Rucksack aufnehmen kann.

Daher haben Sie zwei variable GrรถรŸen.

Mit der dynamischen Programmierung verfรผgen Sie รผber nรผtzliche Informationen:

  1. Die Zielfunktion hรคngt von zwei variablen GrรถรŸen ab
  2. Die Optionstabelle ist eine zweidimensionale Tabelle.

Wenn B[i][j] aufgerufen wird, ist der maximal mรถgliche Wert durch Auswahl in Paketen {1, 2, โ€ฆ, i} mit Gewichtsbeschrรคnkung j.

  • Der Maximalwert bei Auswahl in n Paketen mit der Gewichtsgrenze M betrรคgt B[n][M]. Mit anderen Worten: Wenn i Pakete zur Auswahl stehen, ist B[i][j] das optimale Gewicht, wenn das maximale Gewicht des Rucksacks j betrรคgt.
  • Das optimale Gewicht ist immer kleiner oder gleich dem maximalen Gewicht: B[i][j] โ‰ค j.

Zum Beispiel: B[4][10] = 8. Dies bedeutet, dass im optimalen Fall das Gesamtgewicht der ausgewรคhlten Pakete 8 betrรคgt, wenn 4 erste Pakete zur Auswahl stehen (1. bis 4. Paket) und das maximale Gewicht des Rucksacks betrรคgt 10. Es ist nicht notwendig, dass alle 4 Elemente ausgewรคhlt sind.

Formel zur Berechnung von B[i][j]

Eingabe, Sie definieren:

  • W[i], V[i] sind wiederum das Gewicht und der Wert des Pakets i, in dem i Formel zur Berechnung von B[i][j]widersetzte sich
  • M ist das maximale Gewicht, das der Rucksack tragen kann.

Fรผr den Fall, dass Sie einfach nur 1 Paket zur Auswahl haben. Sie berechnen B[1][j] fรผr jedes j: was bedeutet, dass das maximale Gewicht des Rucksacks โ‰ฅ dem Gewicht des 1. Pakets ist

B[1][j] = W[1]

Mit der Gewichtsgrenze j hat die optimale Auswahl unter den Paketen {1, 2, โ€ฆ, i โ€“ 1, i}, um den grรถรŸten Wert zu haben, zwei Mรถglichkeiten:

  • Wenn das Paket i nicht ausgewรคhlt ist, ist B[i][j] der maximal mรถgliche Wert durch Auswahl unter den Paketen {1, 2, โ€ฆ, i โ€“ 1} mit der Gewichtsbeschrรคnkung von j. Du hast:
B[i][j] = B[i โ€“ 1][j]
  • Wenn Paket i ausgewรคhlt ist (diesen Fall natรผrlich nur berรผcksichtigen, wenn W[i] โ‰ค j), dann ist B[i][j] gleich dem Wert V[i] von Paket i, plus der Maximalwert kann durch Auswahl unter erhalten werden Pakete {1, 2, โ€ฆ, i โ€“ 1} mit Gewichtslimit (j โ€“ W[i]). Das heiรŸt, in Bezug auf den Wert, den Sie haben:
B[i][j] = V[i] + B[i โ€“ 1][j โ€“ W[i]]

Aufgrund der Erstellung von B[i][j], dem maximal mรถglichen Wert, ist B[i][j] der maximale der beiden oben genannten Werte.

Grundlage der dynamischen Programmierung

Sie mรผssen also รผberlegen, ob es besser ist, das Paket i zu wรคhlen oder nicht. Von dort aus haben Sie die rekursive Formel wie folgt:

B[i][j]= max(B[i โ€“ 1][j], V[i]+B[i โ€“ 1][j โ€“ W[i]]

Es ist leicht zu erkennen, dass B[0][j] = maximal mรถglicher Wert ist, indem man aus 0 Paket = 0 auswรคhlt.

Berechnen Sie die Optionstabelle

Sie erstellen eine Optionstabelle basierend auf der obigen rekursiven Formel. Um zu รผberprรผfen, ob die Ergebnisse korrekt sind (falls nicht, erstellen Sie die Zielfunktion B[i][j] neu). Durch die Erstellung der Zielfunktion B[i][j] und der Optionstabelle orientieren Sie sich an der tracing.

Tabelle der Optionen B umfasst n + 1 Zeilen, M + 1 Spalten,

  • Zunรคchst mit den Grundlagen der dynamischen Programmierung gefรผllt: Zeile 0 enthรคlt alle Nullen.
  • Verwenden Sie rekursive Formeln, verwenden Sie Zeile 0, um Zeile 1 zu berechnen, verwenden Sie Zeile 1, um Zeile 2 zu berechnen usw. โ€ฆ bis alle Zeilen berechnet sind.
Berechnen Sie die Optionstabelle
Tabelle der Optionen

Trace

Bei der Berechnung der Optionstabelle sind Sie an B[n][M] interessiert, dem Maximalwert, der bei der Auswahl in allen n Paketen mit der Gewichtsgrenze M erhalten wird.

  • If fort= fortwรคhrendโ€“ fortwรคhrend Wenn Paket n nicht ausgewรคhlt ist, trace B[n โ€“ 1][M].
  • If B[n][M] โ‰  B[n โ€“ 1][M]Sie stellen fest, dass die optimale Auswahl das Paket n und trace B[n โ€“ 1][M โ€“ W[n]].

Weiter zu trace bis zum Erreichen von Zeile 0 der Optionstabelle.

Algorithmus zum Nachschlagen der Optionstabelle, um die ausgewรคhlten Pakete zu finden

Hinweis: Wenn B[i][j] = B[i โ€“ 1][j], wird das Paket i nicht ausgewรคhlt. B[n][W] ist der optimale Gesamtwert des Pakets, das in den Rucksack gesteckt wird.

Schritte fรผr tracing:

  • Schritt 1:: Ausgehend von i = n, j = M.
  • Schritt 2:: Schauen Sie in Spalte j von unten nach oben, Sie finden die Zeile i mit B[i][j] > B[i โ€“ 1][j]. Ausgewรคhltes Paket markieren i: Select [i] = true;
  • Schritt 3:: j = B[i][j] โ€“ W[i]. Wenn j > 0, gehe zu Schritt 2, andernfalls zu Schritt 4
  • Schritt 4:: Basierend auf der Optionstabelle zum Drucken der ausgewรคhlten Pakete.

Java Code

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--;
	}
}
Funktion knapsackDyProg() in Java

Funktion knapsackDyProg() in Java

Erklรคrung des Knapsack-Codes:

  1. Erstellen Sie Tabelle B[][]. Der Standardwert fรผr jede Zelle ist 0.
  2. Erstellen Sie Tabelle B[][] von unten nach oben. Berechnen Sie die Optionstabelle mit der Abrufformel.
  3. Berechnen Sie B[i][j]. Wenn Sie das Paket i nicht auswรคhlen.
  4. Bewerten Sie dann: Wenn Sie Paket i auswรคhlen, ist dies vorteilhafter als das Zurรผcksetzen von B[i][j].
  5. Tracร–ffne die Tabelle von Zeile n bis Zeile 0.
  6. Wenn Sie Paket Nr. wรคhlen. Sobald Paket n ausgewรคhlt ist, kann nur das Gewicht M โ€“ W[n โ€“ 1] hinzugefรผgt werden.


In diesem Tutorial haben Sie zwei Beispiele. Hier ist Java-Code zum Ausfรผhren des obigen Programms mit zwei Beispielen:

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);
}

Sie haben die Ausgabe:

  • Erstes Beispiel:
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
  • Zweites Beispiel:
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

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: