web-dev-qa-db-fra.com

compter le nombre de partitions d'un ensemble avec n éléments dans k sous-ensembles

Ce programme sert à compter le nombre de partitions d’un ensemble de n éléments dans k sous-ensembles. Je confond ici return k*countP(n-1, k) + countP(n-1, k-1); Quelqu'un peut-il expliquer ce qui se passe ici? Pourquoi multiplions-nous avec k?

NOTE-> Je sais que ce n'est pas la meilleure façon de calculer le nombre de partitions qui seraient DP

// A C++ program to count number of partitions 
// of a set with n elements into k subsets 
#include<iostream> 
using namespace std; 

// Returns count of different partitions of n 
// elements in k subsets 
int countP(int n, int k) 
{ 
    // Base cases 
    if (n == 0 || k == 0 || k > n) 
        return 0; 
    if (k == 1 || k == n) 
        return 1; 

    // S(n+1, k) = k*S(n, k) + S(n, k-1) 
    return k*countP(n-1, k) + countP(n-1, k-1); 
} 

// Driver program 
int main() 
{ 
    cout << countP(3, 2); 
    return 0; 
} 
7
user10796621

Vous avez mentionné les nombres Stirling du second type qui énumèrent le nombre de façons de partitionner un ensemble de n objets en k sous-ensembles non vides et désignés par enter image description here ou enter image description here .

Sa relation récursive est:

enter image description here

pour k > 0 avec les conditions initiales:

enter image description here

.

Le calculer à l'aide de la programmation dynamique est plus rapide que l'approche récursive:

int secondKindStirlingNumber(int n, int k) {

    int sf[n + 1][n + 1];
    for (int i = 0; i < k; i++) {
        sf[i][i] = 1;
    }
    for (int i = 1; i < n + 1; i++) {
        for (int j = 1; j < k + 1; j++) {
            sf[i][j] = j * sf[i - 1][j] + sf[i - 1][j - 1];
        }
    }
    return sf[n][k];
}
4
aminography

Chaque appel countP considère implicitement un seul élément de l'ensemble, appelons-leA.

Le terme countP(n-1, k-1) provient du cas oùAest dans un ensemble par lui-même. Dans ce cas, il suffit de compter le nombre de façons de partitionner tous les autres éléments (N-1) en (K-1) sous-ensembles, carAoccupe un sous-ensemble à lui seul. 

Le terme k*countP(n-1, k) vient donc du cas oùAest pas dans un ensemble par lui-même. Nous calculons donc le nombre de façons de partitionner toutes les autres valeurs (N-1) en K sous-ensembles et nous les multiplions par K car il existe K sous-ensembles possibles auxquels nous pourrions ajouterA

Par exemple, considérons l'ensemble [A,B,C,D], avec K=2

Le premier cas, countP(n-1, k-1), décrit la situation suivante: 

{A, BCD}

Le deuxième cas, k*countP(n-1, k), décrit les cas suivants: 

2*({BC,D}, {BD,C}, {B,CD}) 

Ou:

{ABC,D}, {ABD,C}, {AB,CD}, {BC,AD}, {BD,AC}, {B,ACD}
2
wowserx

Comment pouvons-nous obtenir countP(n,k)? En supposant que nous ayons divisé l'élément n-1 précédent en un certain nombre de partitions, nous avons maintenant le n-ième élément et nous essayons de créer une partition k.

nous avons deux options pour cela: 

non plus  

  1. nous avons divisé les éléments n-1 précédents en partitions k (nous avons countP(n-1, k) façons de le faire) et nous plaçons ce nième élément dans l'une de ces partitions (nous avons k choix). Nous avons donc k*countP(n-1, k).

ou:

  1. nous divisons les éléments n-1 précédents en une partition k-1 (nous avons countP(n-1, k-1); façons de le faire), et nous faisons du n-ème élément une partition unique pour réaliser une partition k (nous n'avons qu'un choix: le mettre séparément). Nous avons donc countP(n-1, k-1);

Nous les résumons donc et obtenons le résultat.

1
ZhaoGang

Sur la base de This , une partition d'un ensemble est un regroupement des éléments de l'ensemble en sous-ensembles non vides, de manière à ce que chaque élément soit inclus dans un et un seul des sous-ensembles. Ainsi, le nombre total de partitions d'un ensemble de n éléments est le numéro de Bell qui est calculé comme suit: formule du nombre de Bell Donc, si vous voulez convertir le formule à une fonction récursive ce sera comme: k * nombreP (n-1, k) + nombreP (n-1, k-1);

1
Alireza.N