Witam serdecznie,
proszę o pomoc w wyznaczeniu złożoności obliczeniowych i pamięciowych (pesymistycznych i optymalnych) dla problemu plecakowego.
Algorytmu aproksymacyjnego i dokładnego.
Dokładny:
public void solvePropper(ProblemInstance problemInstance, TextBox result, ListBox resObjects,
TextBox timeResult)
{
DateTime start, stop;
//zaczynamy pomiar czasu
start = DateTime.Now;
//sortujemy przedmioty
problemInstance.Objects.Sort(new ObjComparer());
//macierze przechowujaca posrednie najlepsze wyniki
//element bestV[i,j] - oznacza najlepszy wynik dla pierwszych i elementow
//dla plecaka o wadze j
int[,] bestV = new int[problemInstance.N + 5, problemInstance.Size + 5];
//macierz pomagajaca odtworzyc rozwiazanie, element ch[i,j] ma wartosc 1
//jezeli dla pierwzych i elementow z plecakiem o wadze j, wzielismy do rozwiazania
//i'ty element
int[,] ch = new int[problemInstance.N + 5, problemInstance.Size + 5];
int i, j;
//dla dowolnego elementu gdy pojemnosc plecaka wynosi 0
//nie mozemy wziac zadnej wartosci wiec rozwiazanie wynosi 0
for (i = 0; i < problemInstance.N + 2; i++) bestV[i, 0] = 0;
//dla dowolnej wagi plecaka, w momencie gdy nie bierzemy zadnego elementu
//wartosc wynosi 0
for (j = 0; j < problemInstance.Size + 2; j++) bestV[0, j] = 0;
for (i = 1; i <=problemInstance.N; i++)
for (j = 0; j <= problemInstance.Size; j++)
{
ch[i, j] = 0;
if (((ObjectDesc)problemInstance.Objects[i-1]).Weight > j) //jezeli rozpatrywany element jest ciezszy niz pojemnosc plecaka
bestV[i, j] = bestV[i - 1, j];
else
{
//sprawdzamy czy lepiej wziac ten element czy wziac rozwiazanie dla elementu
//wczesniejszego nie biorac pod uwage aktualnego elementiu
if (bestV[i - 1, j] > bestV[i - 1, j - ((ObjectDesc)problemInstance.Objects[i-1]).Weight] +
((ObjectDesc)problemInstance.Objects[i-1]).Value)
bestV[i, j] = bestV[i - 1, j];
else
{
bestV[i, j] = bestV[i - 1, j - ((ObjectDesc)problemInstance.Objects[i-1]).Weight] +
((ObjectDesc)problemInstance.Objects[i-1]).Value;
ch[i, j] = 1;
//zapisujemy ze element i'ty brany jest do rozwiazania
}
}
}
//koncowy wynik znajduje sie w bestV[ilosc_elementow, rozmiar_plecaka]
int curN = problemInstance.N, curW = problemInstance.Size;
//dopoki nie osiagnelismy 0 wagi lub 0 elementu plecaka
while (curN > 0 && curW > 0)
{
if (ch[curN, curW] > 0) //wybralismy curN element
{
curW -= ((ObjectDesc)problemInstance.Objects[curN - 1]).Weight;
--curN;
resObjects.Items.Add(((ObjectDesc)problemInstance.Objects[curN]).Weight.ToString().PadRight(20).Substring(0, 15) +
" " + ((ObjectDesc)problemInstance.Objects[curN]).Value.ToString().PadLeft(10)); //dodajemy element wziety pod uwage
}
else
{
//przechodzimy o 1 element w tyl
curN--;
}
}
//wypisujemy wartosc plecaka
result.Text = bestV[problemInstance.N, problemInstance.Size].ToString();
Aproksymacyjny:
public void solveApprox(ProblemInstance problemInstance, TextBox result, ListBox resObjects,
TextBox timeResult)
{
DateTime start, stop;
//zaczynamy pomiar czasu
start = DateTime.Now;
//sortujemy dane ze wzgleduna stosunek wartosci /wagi
problemInstance.Objects.Sort(new AprComparer());
int curWeight = 0; //aktualna waga na poczatku wynosi 0;
int res = 0;
for (int i = 0; i < problemInstance.N; i++)
{
//dopoki mozemy dodac taki element
if (curWeight + ((ObjectDesc)problemInstance.Objects[i]).Weight <= problemInstance.Size)
{
//aktualizujemy wage dodajac wage wybranego elementu
curWeight += ((ObjectDesc)problemInstance.Objects[i]).Weight;
res += ((ObjectDesc)problemInstance.Objects[i]).Value;
resObjects.Items.Add(((ObjectDesc)problemInstance.Objects[i]).Weight.ToString().PadRight(20).Substring(0, 15) +
" " + ((ObjectDesc)problemInstance.Objects[i]).Value.ToString().PadLeft(10));
}
}