Implementacja rozwiązań różnych wariantów problemu plecakowego w języku Python

Ważne!

W kolejnych implementacjach wykorzystamy funkcję pomocniczą sortuj, której zadaniem jest posortowanie dostępnych przedmiotów nierosnąco ze względu na iloraz wartości oraz wag. Użyjemy zmodyfikowanego algorytmu sortowania bąbelkowegoPoYAEP8llsortowania bąbelkowego (nie będziemy go tu omawiać).

Linia 1. def sortuj otwórz nawias okrągły wartoscDoWagi przecinek indeksy przecinek n zamknij nawias okrągły dwukropek. Linia 2. for i in range otwórz nawias okrągły n minus 1 zamknij nawias okrągły dwukropek. Linia 3. for j in range otwórz nawias okrągły n minus i minus 1 zamknij nawias okrągły dwukropek. Linia 4. if wartoscDoWagi otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias ostrokątny wartoscDoWagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy dwukropek. Linia 5. wartoscDoWagi otwórz nawias kwadratowy j zamknij nawias kwadratowy przecinek wartoscDoWagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy znak równości wartoscDoWagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy przecinek wartoscDoWagi otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 6. indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy przecinek indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy znak równości indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy przecinek indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy.
Ważne!

Podejście zachłannealgorytm zachłannyzachłanne może nie dać najlepszego możliwego wyniku w wypadku problemu plecakowego.

Ogólny problem plecakowy

Specyfikacja problemu:

Dane:

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

  • wartosci – 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

  • pojemnosc – 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 pojemnosc, 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 pojemnosc

  • całkowita wartość spakowanego plecaka

Zaprezentowane rozwiązania będziemy testować dla następujących danych:

  • maksymalna pojemność plecaka wynosi 41;

  • do dyspozycji mamy nieograniczoną liczbę sztuk każdego rodzaju przedmiotów;

  • przedmioty mają następujące wartości oraz wagi:

Przedmiot – i

0

1

2

3

4

5

6

Nazwa

anemon

bławatek

chaber

dziurawiec

eustoma

forsycja

gipsówka

Wartość

21

15

4

4

14

1

3

Waga

11

8

5

4

7

1

7

Już wiesz

Przypomnijmy, w jaki sposób działa algorytm, analizując zaprezentowane dane.

Zaczniemy od obliczenia ilorazów wartości i wag.

Obliczone ilorazy: 21/11, 15/8, 4/5, 4/4, 14/7, 1/1, 3/7.

Sortujemy je nierosnąco.

Posortowane nierosnąco ilorazy: 14/7, 21/11, 15/8, 4/4, 1/1, 4/5, 3/7.

Daje to następującą kolejność posortowanych nierosnąco przedmiotów: eustoma, anemon, bławatek, dziurawiec, forsycja, chaber, gipsówka (indeksy: 4, 0, 1, 3, 5, 2, 6).

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

Wybieramy pierwszy przedmiot. To eustoma, której waga to 7. Do plecaka wkładamy 5 sztuk tego przedmiotu. Pojemność plecaka po spakowaniu tych przedmiotów wynosi 6.

Waga kolejnego przedmiotu (anemonu) wynosi 11, zatem nie można go spakować do plecaka.

Następny przedmiot, bławatek, waży 8. On również nie może zostać spakowany do plecaka.

Kolejny przedmiot to dziurawiec. Jego waga wynosi 4, zatem do plecaka można spakować jego jedną sztukę. Po spakowaniu kolejnych przedmiotów pojemność plecaka wynosi 2.

Następnym przedmiotem jest forsycja. Jej waga to 1. Do plecaka pakujemy jej dwie sztuki.

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

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

  • eustoma: 14 × 5 sztuk

  • dziurawiec: 1 × 4 sztuki

  • forsycja: 2 × 1 sztuka

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

W programie wykorzystamy dwie funkcje:

  • ogolnyPlecak – 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 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,

  • wartosci – 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,

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

Linia 1. def ogolnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły dwukropek.

W pierwszym kroku tworzone są dwie kolejne tablice:

  • wartoscDoWagi – tablica liczb rzeczywistych,

  • indeksy – tablica liczb naturalnych.

Obie tablice składają się z n elementów. Zapisujemy pętlę for, która będzie iterować po kolejnych elementach tablic, by je zapełnić.

Każdy i-ty element tablicy wartosci dzielimy przez i-ty element tablicy wagi. Pamiętajmy o wykonaniu rzutowania, by uzyskany wynik był liczbą zmiennoprzecinkową.

Wynik dodajemy do tablicy wartoscDoWagi. Następnie do tablicy indeksy dodajemy kolejne wartości licznika, czyli zmiennej i.

Linia 1. def ogolnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły dwukropek. Linia 2. wartoscDoWagi znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 3. indeksy znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 4. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 5. wartoscDoWagi kropka append otwórz nawias okrągły float otwórz nawias okrągły wartosci otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły. Linia 6. indeksy kropka append otwórz nawias okrągły i zamknij nawias okrągły.

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

Funkcja sortuj przyjmuje trzy argumenty:

  • wartoscDoWagi – tablica liczb rzeczywistych,

  • indeksy – tablica liczb naturalnych,

  • n – liczba naturalna.

Linia 1. def ogolnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły dwukropek. Linia 2. wartoscDoWagi znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 3. indeksy znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 4. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 5. wartoscDoWagi kropka append otwórz nawias okrągły wartosci otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły. Linia 6. indeksy kropka append otwórz nawias okrągły i zamknij nawias okrągły. Linia 8. sortuj otwórz nawias okrągły wartoscDoWagi 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 wybranych przedmiotów.

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

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

Zapisujemy kolejną pętlę for. 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.

Zapisujemy pętlę while. 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.

Linia 1. def ogolnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły dwukropek. Linia 2. wartoscDoWagi znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 3. indeksy znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 4. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 5. wartoscDoWagi kropka append otwórz nawias okrągły wartosci otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły. Linia 6. indeksy kropka append otwórz nawias okrągły i zamknij nawias okrągły. Linia 8. sortuj otwórz nawias okrągły wartoscDoWagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 10. wynik znak równości 0. Linia 11. spakowane znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 12. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 13. spakowane kropka append otwórz nawias okrągły 0 zamknij nawias okrągły. Linia 15. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 16. indeks znak równości indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 17. while wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości paojemnosc dwukropek.

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 pojemnosc). Równocześnie dodajemy wartość tego przedmiotu do wyniku (element tablicy wartosci o indeksie indeks jest dodawany do wartości zmiennej wynik). Inkrementujemy wartość elementu tablicy spakowane o indeksie indeks.

Linia 1. def ogolnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły dwukropek. Linia 2. wartoscDoWagi znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 3. indeksy znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 4. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 5. wartoscDoWagi kropka append otwórz nawias okrągły wartosci otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły. Linia 6. indeksy kropka append otwórz nawias okrągły i zamknij nawias okrągły. Linia 8. sortuj otwórz nawias okrągły wartoscDoWagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 10. wynik znak równości 0. Linia 11. spakowane znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 12. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 13. spakowane kropka append otwórz nawias okrągły 0 zamknij nawias okrągły. Linia 15. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 16. indeks znak równości indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 17. while wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemnosc dwukropek. Linia 18. pojemnosc minus znak równości wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 19. wynik plus znak równości wartosci otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 20. spakowane otwórz nawias kwadratowy indeks zamknij nawias kwadratowy plus plus.

Po wyjściu z pętli for zapisujemy kolejną pętlę for. 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. def ogolnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły dwukropek. Linia 2. wartoscDoWagi znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 3. indeksy znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 4. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 5. wartoscDoWagi kropka append otwórz nawias okrągły wartosci otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły. Linia 6. indeksy kropka append otwórz nawias okrągły i zamknij nawias okrągły. Linia 8. sortuj otwórz nawias okrągły wartoscDoWagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 10. wynik znak równości 0. Linia 11. spakowane znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 12. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 13. spakowane kropka append otwórz nawias okrągły 0 zamknij nawias okrągły. Linia 15. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 16. indeks znak równości indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 17. while wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemnosc dwukropek. Linia 18. pojemnosc minus znak równości wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 19. wynik plus znak równości wartosci otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 20. spakowane otwórz nawias kwadratowy indeks zamknij nawias kwadratowy plus plus. Linia 22. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 23. print otwórz nawias okrągły cudzysłów Liczba spakowanych sztuk przedmiotu cudzysłów plus nazwy otwórz nawias kwadratowy i zamknij nawias kwadratowy plus cudzysłów otwórz nawias okrągły indeks cudzysłów plus str otwórz nawias okrągły i zamknij nawias okrągły plus cudzysłów zamknij nawias okrągły dwukropek cudzysłów plus str otwórz nawias okrągły spakowane otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły zamknij nawias okrągły. Linia 25. print otwórz nawias okrągły cudzysłów lewy ukośnik nWartosc spakowanych przedmiotow dwukropek cudzysłów przecinek wynik.
Ważne!

linii 23 wykonujemy rzutowanie typu (zmiana typu całkowitoliczbowego na łańcuch znaków), by dokonać konkatenacji łańcuchów znaków, a w konsekwencji uniknąć znaków spacji umieszczanych między zmiennymi a łańcuchami znaków.

Dodajemy wywołanie funkcji.

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

Oto kompletny kod programu:

Linia 1. def sortuj otwórz nawias okrągły wartoscDoWagi przecinek indeksy przecinek n zamknij nawias okrągły dwukropek. Linia 2. for i in range otwórz nawias okrągły n minus 1 zamknij nawias okrągły dwukropek. Linia 3. for j in range otwórz nawias okrągły n minus i minus 1 zamknij nawias okrągły dwukropek. Linia 4. if wartoscDoWagi otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias ostrokątny wartoscDoWagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy dwukropek. Linia 5. wartoscDoWagi otwórz nawias kwadratowy j zamknij nawias kwadratowy przecinek wartoscDoWagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy znak równości wartoscDoWagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy przecinek wartoscDoWagi otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 6. indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy przecinek indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy znak równości indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy przecinek indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 8. def ogolnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły dwukropek. Linia 9. wartoscDoWagi znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 10. indeksy znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 11. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 12. wartoscDoWagi kropka append otwórz nawias okrągły wartosci otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły. Linia 13. indeksy kropka append otwórz nawias okrągły i zamknij nawias okrągły. Linia 15. sortuj otwórz nawias okrągły wartoscDoWagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 17. wynik znak równości 0. Linia 18. spakowane znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 19. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 20. spakowane kropka append otwórz nawias okrągły 0 zamknij nawias okrągły. Linia 22. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 23. indeks znak równości indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 24. while wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemnosc dwukropek. Linia 25. pojemnosc minus znak równości wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 26. wynik plus znak równości wartosci otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 27. spakowane otwórz nawias kwadratowy indeks zamknij nawias kwadratowy plus znak równości 1. Linia 29. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 30. print otwórz nawias okrągły cudzysłów Liczba spakowanych sztuk przedmiotu cudzysłów plus nazwy otwórz nawias kwadratowy i zamknij nawias kwadratowy plus cudzysłów otwórz nawias okrągły indeks cudzysłów plus str otwórz nawias okrągły i zamknij nawias okrągły plus cudzysłów zamknij nawias okrągły dwukropek cudzysłów plus str otwórz nawias okrągły spakowane otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły zamknij nawias okrągły. Linia 32. print otwórz nawias okrągły cudzysłów lewy ukośnik nWartosc spakowanych przedmiotow dwukropek cudzysłów przecinek wynik zamknij nawias okrągły. Linia 34. nazwy znak równości otwórz nawias kwadratowy cudzysłów anemon cudzysłów przecinek cudzysłów bławatek cudzysłów przecinek cudzysłów chaber cudzysłów przecinek cudzysłów dziurawiec cudzysłów przecinek cudzysłów eustoma cudzysłów przecinek cudzysłów forsycja cudzysłów przecinek cudzysłów gipsówka cudzysłów zamknij nawias kwadratowy. Linia 35. wartosci znak równości otwórz nawias kwadratowy 21 przecinek 15 przecinek 4 przecinek 4 przecinek 14 przecinek 1 przecinek 3 zamknij nawias kwadratowy. Linia 36. wagi znak równości otwórz nawias kwadratowy 11 przecinek 8 przecinek 5 przecinek 4 przecinek 7 przecinek 1 przecinek 7 zamknij nawias kwadratowy. Linia 37. n znak równości 7. Linia 38. pojemnosc znak równości 41. Linia 39. ogolnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły.

Wynik działania programu:

Linia 1. Liczba spakowanych sztuk przedmiotu anemon otwórz nawias okrągły indeks 0 zamknij nawias okrągły dwukropek 0. Linia 2. Liczba spakowanych sztuk przedmiotu bławatek otwórz nawias okrągły indeks 1 zamknij nawias okrągły dwukropek 0. Linia 3. Liczba spakowanych sztuk przedmiotu chaber otwórz nawias okrągły indeks 2 zamknij nawias okrągły dwukropek 0. Linia 4. Liczba spakowanych sztuk przedmiotu dziurawiec otwórz nawias okrągły indeks 3 zamknij nawias okrągły dwukropek 1. Linia 5. Liczba spakowanych sztuk przedmiotu eustoma otwórz nawias okrągły indeks 4 zamknij nawias okrągły dwukropek 5. Linia 6. Liczba spakowanych sztuk przedmiotu forsycja otwórz nawias okrągły indeks 5 zamknij nawias okrągły dwukropek 2. Linia 7. Liczba spakowanych sztuk przedmiotu gipsówka otwórz nawias okrągły indeks 6 zamknij nawias okrągły dwukropek 0. Linia 9. Wartosc spakowanych przedmiotow dwukropek 76.

Decyzyjny problem plecakowy

Specyfikacja problemu:

Dane:

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

  • wartosci – 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

  • pojemnosc – liczba naturalna; maksymalna pojemność plecaka

Wynik:

  • spakowane przedmioty, których całkowita waga nie przekracza wartości przechowywanej w zmiennej pojemnosc, 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 pojemnosc; pakujemy po jednej sztuce przedmiotu każdego rodzaju

  • całkowita wartość spakowanego plecaka

Zaprezentowane rozwiązania będziemy testować dla następujących danych:

  • maksymalna pojemność plecaka wynosi 21;

  • do dyspozycji mamy po jednej sztuce przedmiotu każdego rodzaju;

  • przedmioty mają następujące wartości oraz wagi:

Przedmiot – i

0

1

2

3

4

5

6

Nazwa

aparat

baterie

czajnik

dmuchany materac

ekologiczny prysznic

filtr

garnuszek

Wartość

4

15

6

13

5

12

3

Waga

8

3

2

6

15

16

2

Pojemność plecaka to 21.

Już wiesz

Przypomnijmy, w jaki sposób działa algorytm, analizując podane dane.

Zaczniemy od obliczenia ilorazów wartości i wag: 4/8, 15/3, 6/2, 13/6, 5/15, 12/16, 3/2.

Sortujemy je nierosnąco.

Posortowane nierosnąco ilorazy: 15/3, 6/2, 13/6, 3/2, 12/16, 4/8, 5/15.

Daje to następującą kolejność posortowanych nierosnąco przedmiotów: baterie, czajnik, dmuchany materac, garnuszek, filtr, aparat, ekologiczny prysznic (indeksy: 1, 2, 3, 6, 5, 0, 4).

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

Wybieramy pierwszy przedmiot. To baterie, których waga to 3. Waga jest mniejsza od pojemności, zatem pakujemy je do plecaka. Pojemność plecaka po spakowaniu baterii wynosi 18.

Waga kolejnego przedmiotu (czajnika) wynosi 2, zatem można spakować ten przedmiot. Pojemność plecaka to 16.

Kolejnym przedmiotem jest dmuchany materac. Waga tego przedmiotu to 6. Jest mniejsza od pojemności plecaka, zatem przedmiot zostaje zapakowany. Pozostała pojemność plecaka wynosi 10.

Kolejny przedmiot, garnuszek, waży 2. Może zostać spakowany, a pojemność po jego spakowaniu wynosi  8.

Waga filtra, następnego przedmiotu, wynosi 16. Jest większa od tego, jaka jest pozostała pojemność plecaka, zatem nie można go spakować.

Aparat jest kolejnym przedmiotem, a jego waga wynosi 8. Może zostać spakowany do plecaka.

Wypełniliśmy tym samym całe miejsce w plecaku.

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

  • baterie: 15

  • czajnik: 6

  • dmuchany materac: 13

  • garnuszek: 3

  • aparat: 4

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

Decyzyjny problem plecakowy wymaga, by każdy przedmiot był dodawany do plecaka maksymalnie jeden raz. W programie wymaga to zmiany niewielkiej części programu.

Konieczne jest pominięcie pętli while w tym fragmencie i wykorzystanie instrukcji warunkowej if:

Linia 1. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 2. indeks znak równości indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 3. if wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemnosc dwukropek. Linia 4. pojemnosc minus znak równości wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 5. wynik plus znak równości wartosci otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 6. print otwórz nawias okrągły cudzysłów Spakowano przedmiot cudzysłów plus nazwy otwórz nawias kwadratowy indeks zamknij nawias kwadratowy plus cudzysłów otwórz nawias okrągły indeks cudzysłów plus str otwórz nawias okrągły indeks zamknij nawias okrągły plus 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).

Oto kompletny kod programu:

Linia 1. def sortuj otwórz nawias okrągły wartoscDoWagi przecinek indeksy przecinek n zamknij nawias okrągły dwukropek. Linia 2. for i in range otwórz nawias okrągły n minus 1 zamknij nawias okrągły dwukropek. Linia 3. for j in range otwórz nawias okrągły n minus i minus 1 zamknij nawias okrągły dwukropek. Linia 4. if wartoscDoWagi otwórz nawias kwadratowy j zamknij nawias kwadratowy otwórz nawias ostrokątny wartoscDoWagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy dwukropek. Linia 5. wartoscDoWagi otwórz nawias kwadratowy j zamknij nawias kwadratowy przecinek wartoscDoWagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy znak równości wartoscDoWagi otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy przecinek wartoscDoWagi otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 6. indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy przecinek indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy znak równości indeksy otwórz nawias kwadratowy j plus 1 zamknij nawias kwadratowy przecinek indeksy otwórz nawias kwadratowy j zamknij nawias kwadratowy. Linia 8. def decyzyjnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły dwukropek. Linia 9. wartoscDoWagi znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 10. indeksy znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 11. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 12. wartoscDoWagi kropka append otwórz nawias okrągły wartosci otwórz nawias kwadratowy i zamknij nawias kwadratowy prawy ukośnik wagi otwórz nawias kwadratowy i zamknij nawias kwadratowy zamknij nawias okrągły. Linia 13. indeksy kropka append otwórz nawias okrągły i zamknij nawias okrągły. Linia 15. sortuj otwórz nawias okrągły wartoscDoWagi przecinek indeksy przecinek n zamknij nawias okrągły. Linia 17. wynik znak równości 0. Linia 18. spakowane znak równości otwórz nawias kwadratowy zamknij nawias kwadratowy. Linia 19. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 20. spakowane kropka append otwórz nawias okrągły 0 zamknij nawias okrągły. Linia 22. for i in range otwórz nawias okrągły n zamknij nawias okrągły dwukropek. Linia 23. indeks znak równości indeksy otwórz nawias kwadratowy i zamknij nawias kwadratowy. Linia 24. if wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy otwórz nawias ostrokątny znak równości pojemnosc dwukropek. Linia 25. pojemnosc minus znak równości wagi otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 26. wynik plus znak równości wartosci otwórz nawias kwadratowy indeks zamknij nawias kwadratowy. Linia 27. print otwórz nawias okrągły cudzysłów Spakowano przedmiot cudzysłów plus nazwy otwórz nawias kwadratowy indeks zamknij nawias kwadratowy plus cudzysłów otwórz nawias okrągły indeks cudzysłów plus str otwórz nawias okrągły indeks zamknij nawias okrągły plus cudzysłów zamknij nawias okrągły cudzysłów zamknij nawias okrągły. Linia 29. print otwórz nawias okrągły cudzysłów lewy ukośnik nWartosc spakowanych przedmiotow dwukropek cudzysłów przecinek wynik zamknij nawias okrągły. Linia 31. nazwy znak równości otwórz nawias kwadratowy cudzysłów aparat cudzysłów przecinek cudzysłów baterie cudzysłów przecinek cudzysłów czajnik cudzysłów przecinek cudzysłów dmuchany materac cudzysłów przecinek cudzysłów ekologiczny prysznic cudzysłów przecinek cudzysłów filtr cudzysłów przecinek cudzysłów garnuszek cudzysłów zamknij nawias kwadratowy. Linia 32. wartosci znak równości otwórz nawias kwadratowy 4 przecinek 15 przecinek 6 przecinek 13 przecinek 5 przecinek 12 przecinek 3 zamknij nawias kwadratowy. Linia 33. wagi znak równości otwórz nawias kwadratowy 8 przecinek 3 przecinek 2 przecinek 6 przecinek 15 przecinek 16 przecinek 2 zamknij nawias kwadratowy. Linia 34. n znak równości 7. Linia 35. pojemnosc znak równości 21. Linia 36. decyzyjnyPlecak otwórz nawias okrągły nazwy przecinek wartosci przecinek wagi przecinek n przecinek pojemnosc zamknij nawias okrągły.

Wynik działania programu

Linia 1. Spakowano przedmiot baterie otwórz nawias okrągły indeks 1 zamknij nawias okrągły. Linia 2. Spakowano przedmiot czajnik otwórz nawias okrągły indeks 2 zamknij nawias okrągły. Linia 3. Spakowano przedmiot dmuchany materac otwórz nawias okrągły indeks 3 zamknij nawias okrągły. Linia 4. Spakowano przedmiot garnuszek otwórz nawias okrągły indeks 6 zamknij nawias okrągły. Linia 5. Spakowano przedmiot aparat otwórz nawias okrągły indeks 0 zamknij nawias okrągły. Linia 7. Wartosc spakowanych przedmiotow dwukropek 41.

Słownik

algorytm zachłanny
algorytm zachłanny

algorytm wybierający na każdym kroku lokalnie najlepsze rozwiązanie, licząc, że doprowadzi to do globalnie optymalnegooptymalizacjaoptymalnego rozwiązania problemu

optymalizacja
optymalizacja

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