Staram się zrozumieć rozwiązanie programowania dynamicznego na problem partycjonowania liniowego. Czytam The Algorithm Design Manual, a problem jest opisany w rozdziale 8.5. Czytałem tę sekcję niezliczoną ilość razy, ale po prostu jej nie dostaję. Myślę, że to kiepskie wytłumaczenie (to, co przeczytałem do tej pory, było znacznie lepsze), ale nie byłem w stanie zrozumieć problemu wystarczająco dobrze, aby szukać alternatywnego wyjaśnienia. Linki do lepszych wyjaśnień zapraszamy!Jak rozumieć rozwiązanie do programowania dynamicznego w liniowym partycjonowaniu?
Znalazłem stronę z tekstem podobnym do książki (może z pierwszego wydania książki): The Partition Problem.
Pierwsze pytanie: W przykładzie w książce partycje są sortowane od najmniejszej do największej. Czy to tylko zbieg okoliczności? Z tego, co widzę, uporządkowanie elementów nie ma znaczenia dla algorytmu.
To jest moje rozumienie rekursji:
Pozwala wykorzystać następującą sekwencję i podzielić ją na 4:
{S1...Sn} = 100 150 200 250 300 350 400 450 500
k = 4
Drugie pytanie: Oto, jak myślę, że rekurencja zacznie - nie zrozumiałem prawidłowo?
The 1st rekurencji jest:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 150 200 250 300 | 350 | 400 | 450 | 500 //done
The 2nd rekurencji jest:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 150 200 250 | 300 350 | 400 | 450 | 500 //done
The 3rd rekurencji jest:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 150 200 | 250 300 350 | 400 | 450 | 500 //done
4th rekurencji jest:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 150 | 200 250 300 350 | 400 | 450 | 500 //done
5th rekurencji jest:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 350 | 400 | 450 | 500 //1 partition to go
100 | 150 200 250 300 350 | 400 | 450 | 500 //done
na 6. rekurencji jest:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 | 350 400 | 450 | 500 //1 partition to go
100 150 200 250 | 300 | 350 400 | 450 | 500 //done
7. rekurencji jest:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 | 350 400 | 450 | 500 //1 partition to go
100 150 200 | 250 300 | 350 400 | 450 | 500 //done
8th rekurencji jest:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 | 350 400 | 450 | 500 //1 partition to go
100 150 | 200 250 300 | 350 400 | 450 | 500 //done
The 9th rekurencji jest:
100 150 200 250 300 350 400 450 | 500 //3 partition to go
100 150 200 250 300 350 400 | 450 | 500 //2 partition to go
100 150 200 250 300 | 350 400 | 450 | 500 //1 partition to go
100 | 150 200 250 300 | 350 400 | 450 | 500 //done
etc ...
Oto kod zamieszczony w książce:
partition(int s[], int n, int k)
{
int m[MAXN+1][MAXK+1]; /* DP table for values */
int d[MAXN+1][MAXK+1]; /* DP table for dividers */
int p[MAXN+1]; /* prefix sums array */
int cost; /* test split cost */
int i,j,x; /* counters */
p[0] = 0; /* construct prefix sums */
for (i=1; i<=n; i++) p[i]=p[i-1]+s[i];
for (i=1; i<=n; i++) m[i][3] = p[i]; /* initialize boundaries */
for (j=1; j<=k; j++) m[1][j] = s[1];
for (i=2; i<=n; i++) /* evaluate main recurrence */
for (j=2; j<=k; j++) {
m[i][j] = MAXINT;
for (x=1; x<=(i-1); x++) {
cost = max(m[x][j-1], p[i]-p[x]);
if (m[i][j] > cost) {
m[i][j] = cost;
d[i][j] = x;
}
}
}
reconstruct_partition(s,d,n,k); /* print book partition */
}
pytanie o algorytm:
- Co wartości są przechowywane w
m
i ? - Co oznacza "koszt"? Czy jest to po prostu suma wartości elementów w partycji?Czy jest jakieś dodatkowe, bardziej subtelne znaczenie?
Przy okazji, nawet jeśli nie jesteś w stanie odpowiedzieć na moje pytania, doceniłbym komentarze dotyczące jakości materiału źródłowego. Chciałbym potwierdzenia, że nie tylko ja uważam, że wyjaśnienie jest kiepskie (to sprawiło, że poczułem się dość przygnębiony). –
Nie sądzę, że znajdziesz tutaj wielu ludzi, którzy będą w stanie odpowiedzieć na twoje pytanie, nie podając zwięzłego wyjaśnienia problemu, który musisz rozwiązać. Istnieje wiele odmian problemów z partycjonowaniem i wklejanie długich tabel algorytmu wykonywanych ręcznie, nie powoduje halo, co sprawia, że rzeczy są wyraźniejsze. – hugomg