Comment comprendre la dynamique de la solution de programmation linéaire de partitionnement?

J'ai du mal à comprendre la dynamique de la solution de programmation linéaire de partitionnement problème. Je suis à la lecture de la La Conception D'Un Algorithme Manuel et le problème est décrit dans la section 8.5. J'ai lu l'article d'innombrables fois, mais je suis tout simplement pas l'obtenir. Je pense que c'est une mauvaise explication (ce que j'ai lu jusqu'à maintenant, a été beaucoup mieux), mais je n'ai pas été en mesure de comprendre le problème assez bien à chercher une autre explication. Des liens vers de meilleures explications bienvenue!

J'ai trouvé une page avec un texte semblable au livre (peut-être à partir de la première édition de l'ouvrage): La Partition Problème.

Première question: Dans l'exemple dans le livre les partitions sont ordonnés du plus petit au plus grand. Est-ce juste une coïncidence? De ce que je peux voir l'ordre des éléments n'est pas significative pour l'algorithme.

C'est ma compréhension de la récursivité:

Permet d'utiliser la séquence suivante et la partition en 4:

{S1...Sn} =  100   150   200   250   300   350   400   450   500
k = 4

Deuxième question: Voici comment je pense que la récurrence de commencer - ai-je bien compris?

Le 1er récursivité:

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

La 2ème récursivité:

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

La 3e la récursivité est:

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

La 4ème récursivité:

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

La 5ème récursivité:

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

La 6ème récursivité:

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

Le 7e la récursivité est:

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

Le 8e la récursivité est:

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

La 9e récursivité:

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...

Voici le code tel qu'il apparaît dans le livre:

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 */
}

Question à propos de l'algorithme:

  1. Quelles valeurs sont stockées dans le m et d?
  2. Que signifie "coût" signifie? Est-ce simplement le total des éléments de valeurs au sein d'une partition? Ou est-il plus subtil sens?
  • BTW, même si vous ne pouvez pas répondre à mes questions, j'aimerais avoir des commentaires sur la qualité de la matière d'origine. J'aimerais une confirmation qu'il n'est pas juste moi qui trouve l'explication des pauvres (Il m'a fait sentir assez stoopid).
  • Je ne pense pas que vous trouverez beaucoup de gens ici en mesure de répondre à votre question, sans donner une brève explication du problème que vous devez résoudre. Il existe de nombreuses variantes de problèmes de partitionnement et le collage de longues tables de l'algorithme exécuté par la main n'a pas de halo rendre les choses plus claires.