Pakowanie plecaka (wersja rekurencyjna)

0

Witam mam do napisania problem plecakowy(metoda siłowa) za pomocą rekurencji. Napisałem program w wersji iteracyjnej, lecz przy każdej próbie przerobienia go na wersję rekurencyjną otrzymuję błędne odpowiedzi był bym wdzięczny za wskazówki jak ten algorytm zapisać w wersji rekurencyjnej.

Oto co udało mi się napisać:

 static String pakowanie(int[] tab_elementow, int ilosc_elementow, int pojemnosc_plecaka) {
  int waga = 0;
  for (int i = 0; i < ilosc_elementow; i++) {
   for (int j = i + 1; j < ilosc_elementow; j++) {
    waga = pojemnosc_plecaka;
    waga -= tab_elementow[i];
    wynik = "";
    for (int k = j; k < ilosc_elementow; k++) {
     if ((waga - tab_elementow[k] >= 0)) {
      waga -= tab_elementow[k];
      wynik += tab_elementow[k] + " ";
     }
     if (waga == 0) {

      return pojemnosc_plecaka + " = " + tab_elementow[i] + " " + wynik;
     }
    }
   }
  }

  return "BRAK";
 }
0

Witaj!
Z twojego kodu domyślam się, że przedmioty pakowane do plecaka nie mają żadnych wartości? Mają być po prostu pakowane tak by upchać do niego jak najwięcej kg. Zrobiłem to rekurencyjnie z wykorzystaniem sortowania tablicy. Za każdym razem ostatni element posortowanej tablicy (tj. najcięższy) "dodawany jest do plecaka" jeśli nie jest większy od pozostałego wolnego miejsca, a program wykonuje tą funkcję jeszcze raz przekazując do niej tablicę obciętą o ostatni element (tj. najcięższy). Powtarza się tak dopóty dopóki ilość elementów nie będzie równa 0, a funkcja zwróci pusty string. Wymaga to małej optymalizacji, żeby tylko za pierwszym wywołaniem funkcji packIt tablica była sortowana (to zaoszczędzi troszkę czasu przy wielu przedmiotach do włożenia) oraz usunięcie + przy ostatnim elemencie, ale z tym sobie już poradzisz. Kod działa, jednak jeżeli ktoś uważa, że jest coś źle, proszę pisać, chętnie się czegoś nauczę.

 import java.util.Arrays;

public class Backpack {

	public static String packIt(int[] items, int itemsCount, int backpackCap) {
		
		if(itemsCount == 0 ) return "";
		
		Arrays.sort(items);
		int heaviestItem = items[itemsCount-1];
		int newItems[] = Arrays.copyOf(items, itemsCount-1);
		int newBackpackCap = backpackCap - heaviestItem;
		
		if(newBackpackCap < 0) {
			return packIt(newItems, itemsCount-1, backpackCap);
		}
		
		return heaviestItem + " + " + packIt(newItems, itemsCount-1, newBackpackCap);

	}
	
	public static void main(String[] args) {
		
		int[] items = {33, 22, 12, 4, 56, 33, 99, 20, 44, 1};
		int backpackCap = 204;
		int itemsCount = 10;
		
		System.out.println("Waga " + backpackCap + " = " + packIt(items, itemsCount, backpackCap));
	}
}
0

Sam napisałem algorytm jednak mam problem z czasem jego działania :/ Mógł by mi ktoś podpowiedzieć co zrobić żeby wykonywał się szybciej ?


 static void Pakuj(int i, int obecnaWaga) {
  if (i == liczba_przedmiotow || czy_prawda == true) {
   if (obecnaWaga > maxWaga) {
    maxWaga = obecnaWaga;
    System.arraycopy(rzecz, 0, wynik, 0, liczba_przedmiotow);
   }
  } else {
   if (obecnaWaga + waga[i] == pojemnosc_plecaka) {
    rzecz[i] = true;//zaznacza indeksy pod ktorymi znajdują się szukane elementy
    obecnaWaga += waga[i];
    if (obecnaWaga > maxWaga) {
     maxWaga = obecnaWaga;
     System.arraycopy(rzecz, 0, wynik, 0, liczba_przedmiotow);
    }
    czy_prawda = true;//sprawdza czy znaleziono elementy
   } else {
    if (obecnaWaga + waga[i] < pojemnosc_plecaka) {
     rzecz[i] = true; 
     obecnaWaga += waga[i];
     Pakuj(i + 1, obecnaWaga);
     rzecz[i] = false;
     obecnaWaga -= waga[i];
    }
    Pakuj(i + 1, obecnaWaga);
   }
  }
 }

1 użytkowników online, w tym zalogowanych: 0, gości: 1