RAkTS1cDR4q491
Źródło: Luis Quintero, dostępny w internecie: unsplash.com [dostęp 16.11.2023], domena publiczna.

Problem plecakowy, który jest tematem tej serii e‑materiałów, polega na takim wyborze przedmiotów z danego zbioru, by po spakowaniu wybrane przedmioty miały jak największą wartość, ale ich waga nie przekraczała pojemności plecaka. Istnieją różne metody jego rozwiązania, w tej serii prezentujemy jedną z nich – podejście zachłanne.

Wyróżniamy ogólnydecyzyjny problem plecakowy.

Z problemem ogólnym mamy do czynienia w sytuacji, gdy dysponujemy nieograniczoną liczbą sztuk każdego z przedmiotów.

W sytuacji, w której każdy przedmiot może być spakowany tylko raz, mówimy o problemie decyzyjnym.

Inny wariant tego problemu to ciągły problem plecakowy – w tym przypadku możliwe jest pakowanie ułamkowych części przedmiotów, jednak każdy przedmiot może być spakowany tylko raz (tak jak w przypadku decyzyjnego problemu plecakowego).

Problem plecakowy należy do problemów optymalizacjioptymalizacjaoptymalizacji. Załóżmy, że mamy zapełnić plecak, który może przenieść maksymalny ciężar . Dostępnych jest rodzajów przedmiotów. Każdy przedmiot  ma swoją określoną wartość  oraz wagę .

Zadanie polega na spakowaniu przedmiotów do plecaka, który może pomieścić ładunek o wadze nieprzekraczającej . Co więcej, wartość zgromadzonych w plecaku przedmiotów powinna być możliwie największa.

Przedmiot (i)

antyrama (0)

bieżnik (1)

chlebak (2)

dywanik (3)

ekspres (4)

firanki (5)

garnki (6)

Wartość – vi

2

6

4

2

2

4

3

Waga – wi

2

7

5

2

2

3

2

v i w i

2/2 (1)

6/7 (0,857)

4/5 (0,8)

2/2 (1)

2/2 (1)

4/3 (1,333)

3/2 (1,5)

Ważne!

Warto zauważyć, że nie zawsze rozwiązanie dające najlepszy wynik (największa wartość zapakowanych przedmiotów) wykorzysta maksymalną pojemność plecaka.

Co więcej, podejście zachłanne może nie dać rozwiązania, w którym wartość zapakowanych przedmiotów jest największa.

Metoda zachłanna polega na wybieraniu przedmiotów, zaczynając od najcenniejszych, czyli od tych o największym ilorazie wartości i wagi (). Jeśli przechowujemy przedmioty w pewnej tablicy, to należy je posortować nierosnąco tak, aby po posortowaniu spełniały następujący warunek:

Na początku algorytmu wyznaczamy iloraz , który zostanie zapamiętany w odpowiedniej zmiennej. Wówczas algorytm nie musi za każdym razem wyznaczać ilorazu od nowa – wystarczy, że pobierze go z zapisanej tablicy.

W następnym kroku algorytm przechodzi do pakowania przedmiotów do plecaka. Kolejne kroki zależne są od tego, z jakim problemem plecakowym mamy do czynienia.

Zaczniemy od zaprezentowania pseudokodu programu, który rozwiązuje ogólny problem plecakowy z wykorzystaniem algorytmu zachłannegoalgorytm zachłannyalgorytmu zachłannego.

Ważne!

W pseudokodach wykorzystujemy funkcję pomocniczą sortuj, której zadaniem jest posortowanie dostępnych przedmiotów nierosnąco ze względu na ilorazy ich  wartości i wag. Używamy zmodyfikowanego algorytmu sortowania bąbelkowegoPCfvfjgLksortowania bąbelkowego (nie będziemy go tu omawiać).

Linia 1. funkcja sortuj otwórz nawias okrągły wartość podkreślnik do podkreślnik wagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 2. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka n minus 2 przecinek. Linia 3. dla każdego j znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka n minus i minus 2. Linia 4. jeżeli wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias ostrokątny wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy. Linia 5. pomocnicza podkreślnik wdw ← wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 6. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j zamknij nawias kwadratowy ← wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy. Linia 7. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy ← pomocnicza podkreślnik wdw. Linia 9. pomocnicza podkreślnik indeksy ← indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 10. indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy ← indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy. Linia 11. indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy ← pomocnicza podkreślnik indeksy.

Ogólny problem plecakowy

Przykład 1

Zapoznajmy się z działaniem algorytmu, analizując kolejne jego kroki dla następujących danych:

  • pojemność plecaka: 27

  • przedmioty, które mamy do dyspozycji, ich wartości oraz wagi (do dyspozycji mamy nieograniczoną liczbę sztuk przedmiotu każdego rodzaju):

Przedmiot (i)

antyrama (0)

bieżnik (1)

chlebak (2)

dywanik (3)

ekspres (4)

firanki (5)

garnki (6)

Wartość – vi

2

6

4

1

2

4

15

Waga – wi

2

7

5

1

2

3

10

v i w i

2/2 (1)

6/7 (0,857)

4/5 (0,8)

1/1 (1)

2/2 (1)

4/3 (1,333)

15/10 (1,5)

Zaczniemy od obliczenia ilorazów wartości i wag (zapisaliśmy je już w tabeli).

Daje to następującą kolejność posortowanych nierosnąco przedmiotów: garnki, firanki, antyrama, dywanik, ekspres, bieżnik, chlebak (indeksy: 6, 5, 0, 3, 4, 1, 2).

Dla każdego posortowanego przedmiotu sprawdzamy, czy można go spakować, a jeśli tak, ile sztuk.

Wybieramy pierwszy przedmiot. To garnki, których waga to 10. Do plecaka wkładamy 2 sztuki tego przedmiotu. Pojemność plecaka po spakowaniu tych przedmiotów wynosi 7.

Waga kolejnego przedmiotu (firanek) wynosi 3, zatem  możemy spakować 2 sztuki tego przedmiotu. Pojemność plecaka po spakowaniu tego przedmiotu wynosi 1.

Następny przedmiot, antyrama, waży 8. Nie możemy jej spakować, ponieważ jej waga jest większa od tego, ile miejsca zostało w plecaku.

Kolejny przedmiot to dywanik. Jego waga wynosi 1, zatem do plecaka można spakować jego jedną sztukę. Po jego spakowaniu pozostała pojemność plecaka wynosi 0.

W plecaku nie ma więcej miejsca, zatem kolejne przedmioty nie mogą zostać spakowane.

Obliczmy całkowitą wartość spakowanych przedmiotów:

  • garnki: 15 × 2 sztuki

  • firanki: 4 × 2 sztuki

  • dywanik: 1 × 1 sztuka

Całkowita wartość spakowanych przedmiotów wynosi 39. Wykorzystaliśmy całe miejsce.

Specyfikacja problemu:

Dane:

  • nazwy – tablica liczb łańcuchów znaków; nazwy poszczególnych przedmiotów

  • wartości – tablica liczb naturalnych; wartości poszczególnych przedmiotów

  • wagi – tablica liczb naturalnych; wagi poszczególnych przedmiotów

  • n – liczba naturalna; liczba rodzajów przedmiotów

  • pojemność – liczba naturalna; maksymalna pojemność plecaka

Wynik:

  • liczby sztuk poszczególnych przedmiotów (również równe 0), których całkowita waga nie przekracza wartości przechowywanej w zmiennej pojemność, a których całkowita wartość jest największa wśród możliwych wypełnień plecaka rzeczami o takiej wadze, która nie przekracza wartości zmiennej pojemność

  • całkowita wartość spakowanego plecaka

W programie wykorzystamy dwie funkcje:

  • ogólnyPlecak – funkcja mająca na celu znalezienie największej łącznej wartości przedmiotów, które można zmieścić w plecaku o określonej pojemności z wykorzystaniem podejścia zachłannego;

  • sortuj – funkcja pomocnicza.

Jak wspomnieliśmy, nie będziemy tu omawiać funkcji sortuj. Przejdziemy zatem do zapisania funkcji właściwej.

Zapisujemy jej nagłówek. Funkcja przyjmie pięć argumentów:

  • nazwy – tablica łańcuchów znaków; nazwy poszczególnych przedmiotów,

  • wartości – tablica liczb naturalnych; wartości poszczególnych przedmiotów,

  • wagi – tablica liczb naturalnych; wagi poszczególnych przedmiotów,

  • n – liczba naturalna; liczba rodzajów przedmiotów,

  • pojemność – liczba naturalna; maksymalna pojemność plecaka.

Linia 1. funkcja ogólnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły.

W pierwszym kroku tworzone są dwie kolejne tablice:

  • wartość_do_wagi – tablica liczb rzeczywistych,

  • indeksy – tablica liczb naturalnych.

Obie tablice składają się z n elementów. Zapisujemy pętlę dla, która będzie iterować przez kolejne elementy tablic, by je zapełnić.

Każdy i-ty element tablicy wartości dzielimy przez i-ty element tablicy wagi. Wynik dodajemy do tablicy wartość_do_wagi. Kolejne wartości licznika dodajemy do tablicy indeksy. W ten sposób obliczamy iloraz wartości i wagi poszczególnych przedmiotów i wypełniamy nimi tablicę.

Linia 1. funkcja ogólnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły. Linia 2. wartość podkreślnik do podkreślnik wagi ← utwórz pustą tablicę. Linia 3. indeksy ← utwórz pustą tablicę. Linia 4. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 5. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy ← wartości otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 6. indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy ← i.

Po wyjściu z pętli wywołujemy funkcję sortuj.

Funkcja sortuj przyjmuje trzy argumenty:

  • wartość_do_wagi – tablica liczb rzeczywistych,

  • indeksy – tablica liczb naturalnych,

  • n – liczba naturalna.

Jej zadaniem jest posortowanie obliczonych ilorazów wartości i wag przedmiotów nierosnąco.

Linia 1. funkcja ogólnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły. Linia 2. wartość podkreślnik do podkreślnik wagi ← utwórz pustą tablicę. Linia 3. indeksy ← utwórz pustą tablicę. Linia 4. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 5. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy ← wartości otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 6. indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy ← i. Linia 8. sortuj otwórz nawias okrągły wartość podkreślnik do podkreślnik wagi przecinek indeksy przecinek n zamknij nawias okrągły.

Po wykonaniu sortowania tworzymy zmienną wynik i przypisujemy jej wartość 0. Zmienna ta będzie przechowywała sumę wartości spakowanych przedmiotów.

Tworzymy również tablicę spakowane. Będzie przechowywała liczniki spakowanych przedmiotów.

W kolejnym kroku zapisujemy pętlę dla, która będzie iterowała przez posortowane przedmioty. Wykorzystamy ją do wypełnienia tablicy spakowane zerami.

Zapisujemy kolejną pętlę  dla. Ponownie iterujemy przez posortowane przedmioty.

W pętli utworzymy zmienną indeks, której z każdą iteracją będziemy przypisywać wartość i-tego elementu tablicy indeksy – pobieramy w ten sposób indeks bieżącego przedmiotu.

Linia 1. funkcja ogólnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły. Linia 2. wartość podkreślnik do podkreślnik wagi ← utwórz pustą tablicę. Linia 3. indeksy ← utwórz pustą tablicę. Linia 4. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 5. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy ← wartości otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 6. indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy ← i. Linia 8. sortuj otwórz nawias okrągły wartość podkreślnik do podkreślnik wagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 10. wynik ← 0. Linia 11. spakowane ← utwórz pustą tablicę. Linia 12. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 13. spakowane otwórz nawias kwadratowy i zamknij nawias kwadratowy ← 0. Linia 15. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 16. indeks ← indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy.

Wewnątrz pętli zapisujemy pętlę dopóki. Będzie ona wykonywała się tak długo, jak długo waga pakowanego przedmiotu będzie albo mniejsza od pojemności, albo jej równa. Dzięki tej pętli kolejne przedmioty będą mogły być dodawane więcej niż jeden raz.

Jeśli przedmiot o danym indeksie zmieści się w plecaku, waga przedmiotu odejmowana jest od dostępnej pojemności plecaka (element tablicy wagi o indeksie indeks jest odejmowany od wartości zmiennej pojemność). Równocześnie dodajemy wartość tego przedmiotu do wyniku (element tablicy wartości o indeksie indeks jest dodawany do wartości zmiennej wynik). Inkrementujemy wartość elementu tablicy spakowane o indeksie indeks.

Linia 1. funkcja ogólnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły. Linia 2. wartość podkreślnik do podkreślnik wagi ← utwórz pustą tablicę. Linia 3. indeksy ← utwórz pustą tablicę. Linia 4. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 5. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy ← wartości otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 6. indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy ← i. Linia 8. sortuj otwórz nawias okrągły wartość podkreślnik do podkreślnik wagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 10. wynik ← 0. Linia 11. spakowane ← utwórz pustą tablicę. Linia 12. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 13. spakowane otwórz nawias kwadratowy i zamknij nawias kwadratowy ← 0. Linia 15. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 16. indeks ← indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 17. dopóki wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemność. Linia 18. pojemność ← pojemność minus wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 19. wynik ← wynik plus wartości otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 20. spakowane otwórz nawias kwadratowy indeks zamknij nawias kwadratowy ← spakowane otwórz nawias kwadratowy indeks zamknij nawias kwadratowy plus 1.

Po wyjściu z pętli dla zapisujemy kolejną pętlę dla. Wykorzystamy ją do wypisywania informacji na temat tego, ile sztuk danego rodzaju przedmiotu zostało spakowanych.

Wypisujemy całkowitą wartość spakowanych przedmiotów.

Linia 1. funkcja ogólnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły. Linia 2. wartość podkreślnik do podkreślnik wagi ← utwórz pustą tablicę. Linia 3. indeksy ← utwórz pustą tablicę. Linia 4. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 5. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy ← wartości otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 6. indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy ← i. Linia 8. sortuj otwórz nawias okrągły wartość podkreślnik do podkreślnik wagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 10. wynik ← 0. Linia 11. spakowane ← utwórz pustą tablicę. Linia 12. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 13. spakowane otwórz nawias kwadratowy i zamknij nawias kwadratowy ← 0. Linia 15. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 16. indeks ← indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 17. dopóki wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemność. Linia 18. pojemność ← pojemność minus wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 19. wynik ← wynik plus wartości otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 20. spakowane otwórz nawias kwadratowy indeks zamknij nawias kwadratowy ← spakowane otwórz nawias kwadratowy indeks zamknij nawias kwadratowy plus 1. Linia 22. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 23. wypisz cudzysłów Liczba spakowanych sztuk przedmiotu cudzysłów nazwy otwórz nawias kwadratowy i zamknij nawias kwadratowy cudzysłów otwórz nawias okrągły indeks cudzysłów i cudzysłów zamknij nawias okrągły dwukropek cudzysłów spakowane otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 25. wypisz cudzysłów Wartość spakowanych przedmiotów dwukropek cudzysłów wynik.

Dodajemy wywołanie funkcji.

Pamiętamy również o dodaniu funkcji sortuj.

Kompletny kod programu:

Linia 1. funkcja sortuj otwórz nawias okrągły wartość podkreślnik do podkreślnik wagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 2. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka n minus 2 przecinek. Linia 3. dla każdego j znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka n minus i minus 2. Linia 4. jeżeli wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias ostrokątny wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy. Linia 5. pomocnicza podkreślnik wdw ← wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 6. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j zamknij nawias kwadratowy ← wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy. Linia 7. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy ← pomocnicza podkreślnik wdw. Linia 9. pomocnicza podkreślnik indeksy ← indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 10. indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy ← indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy. Linia 11. indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy ← pomocnicza podkreślnik indeksy. Linia 13. funkcja ogólnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły. Linia 14. wartość podkreślnik do podkreślnik wagi ← utwórz pustą tablicę. Linia 15. indeksy ← utwórz pustą tablicę. Linia 16. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 17. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy ← wartości otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 18. indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy ← i. Linia 20. sortuj otwórz nawias okrągły wartość podkreślnik do podkreślnik wagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 22. wynik ← 0. Linia 23. spakowane ← utwórz pustą tablicę. Linia 24. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 25. spakowane otwórz nawias kwadratowy i zamknij nawias kwadratowy ← 0. Linia 27. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 28. indeks ← indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 29. dopóki wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemność. Linia 30. pojemność ← pojemność minus wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 31. wynik ← wynik plus wartości otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 32. spakowane otwórz nawias kwadratowy indeks zamknij nawias kwadratowy ← spakowane otwórz nawias kwadratowy indeks zamknij nawias kwadratowy plus 1. Linia 34. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 35. wypisz cudzysłów Liczba spakowanych sztuk przedmiotu cudzysłów nazwy otwórz nawias kwadratowy i zamknij nawias kwadratowy cudzysłów otwórz nawias okrągły indeks cudzysłów i cudzysłów zamknij nawias okrągły dwukropek cudzysłów spakowane otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 37. wypisz cudzysłów Wartość spakowanych przedmiotów dwukropek cudzysłów wynik. Linia 39. nazwy ← cudzysłów antyrama cudzysłów przecinek cudzysłów bieżnik cudzysłów przecinek cudzysłów chlebak cudzysłów przecinek cudzysłów dywanik cudzysłów przecinek cudzysłów ekspres cudzysłów przecinek cudzysłów firanki cudzysłów przecinek cudzysłów garnki cudzysłów. Linia 40. wartości ← 2 przecinek 6 przecinek 4 przecinek 1 przecinek 2 przecinek 4 przecinek 15. Linia 41. wagi ← 2 przecinek 7 przecinek 5 przecinek 1 przecinek 2 przecinek 3 przecinek 10. Linia 42. n ← 7. Linia 43. pojemność ← 27. Linia 44. ogólnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły.

Wynik działania programu:

Linia 1. Liczba spakowanych sztuk przedmiotu antyrama otwórz nawias okrągły indeks 0 zamknij nawias okrągły dwukropek 0. Linia 2. Liczba spakowanych sztuk przedmiotu bieżnik otwórz nawias okrągły indeks 1 zamknij nawias okrągły dwukropek 0. Linia 3. Liczba spakowanych sztuk przedmiotu chlebak otwórz nawias okrągły indeks 2 zamknij nawias okrągły dwukropek 0. Linia 4. Liczba spakowanych sztuk przedmiotu dywanik otwórz nawias okrągły indeks 3 zamknij nawias okrągły dwukropek 1. Linia 5. Liczba spakowanych sztuk przedmiotu ekspres otwórz nawias okrągły indeks 4 zamknij nawias okrągły dwukropek 0. Linia 6. Liczba spakowanych sztuk przedmiotu firanki otwórz nawias okrągły indeks 5 zamknij nawias okrągły dwukropek 2. Linia 7. Liczba spakowanych sztuk przedmiotu garnki otwórz nawias okrągły indeks 6 zamknij nawias okrągły dwukropek 2. Linia 9. Wartość spakowanych przedmiotów dwukropek 39.

Decyzyjny problem plecakowy

Przykład 2

Zapoznajmy się z działaniem algorytmu, analizując kolejne jego kroki dla następujących danych:

  • pojemność plecaka: 31

  • przedmioty, które mamy do dyspozycji, ich wartości oraz wagi (do dyspozycji mamy po jednej sztuce przedmiotu każdego rodzaju):

Przedmiot (i)

andruty (0)

bajaderka (1)

chałka (2)

drożdżówka (3)

ekler (4)

flan (5)

galaretka (6)

Wartość – vi

3

10

2

3

2

7

8

Waga – wi

4

4

9

2

2

8

4

v i w i

3/4 (0,75)

10/4 (2,5)

2/9 (0,222)

3/2 (1,5)

2/2 (1)

7/8 (0,875)

8/4 (2)

Zaczniemy od obliczenia ilorazów wartości i wag (zapisaliśmy je już w tabeli)

Daje to następującą kolejność posortowanych nierosnąco przedmiotów: bajaderka, galaretka,  drożdżówka, ekler, flan, andruty, chałka (indeksy: 1, 6, 3, 4, 5, 0, 2).

Dla każdego posortowanego przedmiotu sprawdzamy, czy można go spakować.

Wybieramy pierwszy przedmiot. To bajaderka, której waga to 4. Waga jest mniejsza od pojemności, zatem pakujemy ten przedmiot do plecaka. Pojemność plecaka po jego spakowaniu wynosi 27.

Waga kolejnego przedmiotu (galaretki) wynosi 4, zatem można spakować ten przedmiot. Pojemność plecaka to 23.

Kolejnym przedmiotem jest drożdżówka. Waga tego przedmiotu to 2. Jest mniejsza od pojemności plecaka, zatem może zostać zapakowana. Pozostała pojemność plecaka wynosi 21.

Kolejny przedmiot, ekler, waży 2. Może zostać zapakowany, a pojemność po jego spakowaniu wynosi  19.

Waga flanu, następnego przedmiotu, wynosi 8. Jest mniejsza od tego, jaka jest pozostała pojemność plecaka, zatem można go spakować. Pojemność plecaka wynosi 11.

Andruty to kolejny przedmiot, a jego waga wynosi 4. Mogą zostać zapakowane do plecaka, jego pojemność to 7.

Waga ostatniego przedmiotu, chałki jest większa od tego, ile wynosi pojemność plecaka, ponieważ jest równa 9. Nie możemy zatem zapakować do plecaka tego przedmiotu.

Sprawdziliśmy tym samym możliwość zapakowania wszystkich przedmiotów.

Obliczmy całkowitą wartość spakowanych przedmiotów:

  • bajaderka: 10

  • galaretka: 8

  • drożdżówka: 3

  • ekler: 2

  • flan: 7

  • andruty: 3

Całkowita wartość spakowanych przedmiotów wynosi 33. Nie wykorzystaliśmy całego miejsca.

Specyfikacja problemu:

Dane:

  • nazwy – tablica liczb łańcuchów znaków; nazwy poszczególnych przedmiotów

  • wartości – tablica liczb naturalnych; wartości poszczególnych przedmiotów

  • wagi – tablica liczb naturalnych; wagi poszczególnych przedmiotów

  • n – liczba naturalna; liczba rodzajów przedmiotów

  • pojemność – liczba naturalna; maksymalna pojemność plecaka

Wynik:

  • spakowane przedmioty, których całkowita waga nie przekracza wartości przechowywanej w zmiennej pojemność, a których całkowita wartość jest największa wśród możliwych wypełnień plecaka rzeczami o takiej wadze, która nie przekracza wartości zmiennej pojemność; pakujemy po jednej sztuce przedmiotu każdego rodzaju

  • całkowita wartość spakowanego plecaka

Decyzyjny problem plecakowy wymaga, by każdy przedmiot był dodawany do plecaka maksymalnie jeden raz. W programie wymaga to zmiany jednej z instrukcji.

Konieczne jest pominięcie pętli dopóki w tym fragmencie i wykorzystanie instrukcji warunkowej jeżeli.

Wynika to z tego, że w przypadku decyzyjnego problemu plecakowego pakujemy wyłącznie jedną sztukę danego rodzaju przedmiotu. Instrukcja dopóki w rozwiązaniu problemu ogólnego odpowiadała za to, by pakowano tyle sztuk przedmiotu danego rodzaju, ile mieściło się w plecaku.

Linia 1. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 2. indeks ← indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 3. jeżeli wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemność. Linia 4. pojemność ← pojemność minus wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 5. wynik ← wynik plus wartości otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 6. wypisz cudzysłów Spakowano przedmiot cudzysłów nazwy otwórz nawias kwadratowy indeks zamknij nawias kwadratowy cudzysłów otwórz nawias okrągły indeks cudzysłów indeks cudzysłów zamknij nawias okrągły cudzysłów.

Zwróć uwagę, że w kodzie nie pojawia się również tablica spakowane, ponieważ w przypadku problemu decyzyjnego nie ma potrzeby liczenia, ile sztuk danego przedmiotu spakowano (do dyspozycji jest tylko jedna sztuka danego przedmiotu).

Kompletny kod programu:

Linia 1. funkcja sortuj otwórz nawias okrągły wartość podkreślnik do podkreślnik wagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 2. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka n minus 2 przecinek. Linia 3. dla każdego j znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka n minus i minus 2. Linia 4. jeżeli wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias ostrokątny wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy. Linia 5. pomocnicza podkreślnik wdw ← wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 6. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j zamknij nawias kwadratowy ← wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy. Linia 7. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy ← pomocnicza podkreślnik wdw. Linia 9. pomocnicza podkreślnik indeksy ← indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 10. indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy ← indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy. Linia 11. indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy ← pomocnicza podkreślnik indeksy. Linia 13. funkcja decyzyjnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły. Linia 14. wartość podkreślnik do podkreślnik wagi ← utwórz pustą tablicę. Linia 15. indeksy ← utwórz pustą tablicę. Linia 16. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 17. wartość podkreślnik do podkreślnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy ← wartości otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 18. indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy ← i. Linia 20. sortuj otwórz nawias okrągły wartość podkreślnik do podkreślnik wagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 22. wynik ← 0. Linia 23. spakowane ← utwórz pustą tablicę. Linia 24. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 25. spakowane otwórz nawias kwadratowy i zamknij nawias kwadratowy ← 0. Linia 27. dla każdego i znak równości 0 przecinek 1 przecinek 2 przecinek kropka kropka kropka przecinek n minus 1. Linia 28. indeks ← indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 29. jeżeli wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemność. Linia 30. pojemność ← pojemność minus wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 31. wynik ← wynik plus wartości otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 32. wypisz cudzysłów Spakowano przedmiot cudzysłów nazwy otwórz nawias kwadratowy indeks zamknij nawias kwadratowy cudzysłów otwórz nawias okrągły indeks cudzysłów indeks cudzysłów zamknij nawias okrągły cudzysłów. Linia 34. wypisz cudzysłów Wartość spakowanych przedmiotów dwukropek cudzysłów wynik. Linia 36. nazwy ← cudzysłów andruty cudzysłów przecinek cudzysłów bajaderka cudzysłów przecinek cudzysłów chałka cudzysłów przecinek cudzysłów drożdżówka cudzysłów przecinek cudzysłów ekler cudzysłów przecinek cudzysłów flan cudzysłów przecinek cudzysłów galaretka cudzysłów. Linia 37. wartości ← 3 przecinek 10 przecinek 2 przecinek 3 przecinek 2 przecinek 7 przecinek 8. Linia 38. wagi ← 4 przecinek 4 przecinek 9 przecinek 2 przecinek 2 przecinek 8 przecinek 4. Linia 39. n ← 7. Linia 40. pojemność ← 31. Linia 41. decyzyjnyPlecak otwórz nawias okrągły nazwy przecinek wartości przecinek wagi przecinek n przecinek pojemność zamknij nawias okrągły.

Wynik działania programu:

Linia 1. Spakowano przedmiot bajaderka otwórz nawias okrągły indeks 1 zamknij nawias okrągły. Linia 2. Spakowano przedmiot galaretka otwórz nawias okrągły indeks 6 zamknij nawias okrągły. Linia 3. Spakowano przedmiot drożdżówka otwórz nawias okrągły indeks 3 zamknij nawias okrągły. Linia 4. Spakowano przedmiot ekler otwórz nawias okrągły indeks 4 zamknij nawias okrągły. Linia 5. Spakowano przedmiot flan otwórz nawias okrągły indeks 5 zamknij nawias okrągły. Linia 6. Spakowano przedmiot andruty otwórz nawias okrągły indeks 0 zamknij nawias okrągły. Linia 8. Wartość spakowanych przedmiotów dwukropek 33.

Słownik

algorytm zachłanny
algorytm zachłanny

algorytm podejmujący lokalnie optymalne dla danego kroku wybory, licząc, że doprowadzi to globalnie optymalnego rozwiązania problemu

optymalizacja
optymalizacja

(od łac. optimus – najlepszy) poprawa wydajności algorytmu uzyskana dzięki zmniejszeniu liczby operacji niezbędnych do otrzymania wyniku