IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Algorithme: Fonction récursive de partition d'un ensemble et temps de calcul


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    pas informaticien
    Inscrit en
    Mai 2020
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : pas informaticien

    Informations forums :
    Inscription : Mai 2020
    Messages : 2
    Par défaut Algorithme: Fonction récursive de partition d'un ensemble et temps de calcul
    Bonjour,

    Je cherche à écrire une fonction partition(n) qui prend en argument un entier (n = nombre d'élements) et qui renvoie une matrice représentant tous les sous ensembles possibles avec des 0 et des 1 (si un élement est dans le sous ensemble on lui affecte 1,0 sinon).
    Le nb de sous ensemble d'un ensemble à n élements est 2^n, donc partition(n) est une matrice de taille n*2^n (ca grossit très vite).

    Je ne suis pas du tout familier avec la syntaxe VBA et mes souvenirs d'informatique sont assez anciens mais j'ai réussi à écrire un algorithme trivial qui fonctionne, le code est le suivant.
    La fonction est récursive:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     Function Partition(n_elem As Integer) As Variant 
     
    Dim Tab_temp(1024, 1024) As Integer
     
    If n_elem = 1 Then
     Tab_temp(0, 0) = 0
     Tab_temp(0, 1) = 1
    Else
    For k = 0 To 2 ^ (n_elem - 1) - 1
      Tab_temp(0, k) = 0
      Tab_temp(0, 2 ^ (n_elem - 1) + k) = 1
    Next k
    For i = 0 To n_elem - 2
      For k = 0 To 2 ^ (n_elem - 1) - 1
       Tab_temp(i + 1, k) = Partition(n_elem - 1)(i, k)
       Tab_temp(i + 1, 2 ^ (n_elem - 1) + k) = Partition(n_elem - 1)(i, k)
      Next k
    Next i
    End If
     
    Partition = Tab_temp
     
    End Function
    J'étais content, jusqu'à ce que je me rende compte que pour n=4 ca met déjà plusieurs secondes à s'exécuter... j'en ai pas besoin pour des valeurs très elevées de n (jusqu'à n=6/7) mais ca prendra trop de temps à tourner car je l'utilise plusieurs fois cette fonction après.
    Donc j'essaye d'optimiser la syntaxe de la fonction.
    Je pense que ce qui prend du temps c'est que je calcule beaucoup de fois Partition(n_elem-1) dans mes boucles. Donc j'ai essayé de stocker dans un tableau temporaire la valeur Partition(n_elem-1) et appeler ce tableau temporaire:

    > temp_part = Partition(n_elem-1)

    et appeler temp_part(i,k) dans la suite du code mais ça me met "erreur d'exécution 7: mémoire insuffisante.

    Est-ce qu'une âme charitable peut m'aider pour faire marcher tout ça plus rapidement?
    Aussi, peut-on créer des tableaux de dimension variable genre Tab(n_elem) par exemple? Je n'ai pas l'impression que ce soit possible. Lié à ça, un mystère est que le nombre d'initialisation de la matrice Dim Tab_temp(1024, 1024) joue énormément dans la vitesse de calcul je ne sais pas pourquoi car je boucle seulement sur les éléments qui m'intéressent.

    Merci d'avance pour vos conseils éclairés

  2. #2
    Expert confirmé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Juillet 2014
    Messages
    2 676
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 2 676
    Par défaut
    Bonjour,

    Pour le joli code il te suffit de mettre les balise code (bouton # dans l'interface)
    Pour tes questions sur les variables tableaux, notamment le fait de pouvoir faire un tableau de taille variable, je te conseille la lecture de ce tuto: https://silkyroad.developpez.com/vba/tableaux/#LII-B

  3. #3
    Candidat au Club
    Homme Profil pro
    pas informaticien
    Inscrit en
    Mai 2020
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : pas informaticien

    Informations forums :
    Inscription : Mai 2020
    Messages : 2
    Par défaut
    Merci halaster pour le lien je vais voir si je peux améliorer tout ça avec les tableaux dynamiques. En attendant j'ai trouvé la syntaxe pour sortir l'étape n-1 de la boucle (c'était tout bête je placais la variable auxiliaire au mauvais endroit) et le temps de calcul est drastiquement réduit.

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur VBA
    Inscrit en
    Décembre 2015
    Messages
    93
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur VBA

    Informations forums :
    Inscription : Décembre 2015
    Messages : 93
    Par défaut
    Bonjour,

    Sympa c't histoire, bien que l'on ne connaisse pas le but de la fonction.

    J'ai regardé ce que cela donnait comme résultat en l'intégrant dans une feuille Excel. peut-être qu'il y a encore plus simple, mais le résultat donne le même que vous.
    et niveau vitesse d'exécution…. je vous laisse tester ^^

    L'idée est que le tableau doit avoir :
    - Nombre de colonne : n_elem ^ 2
    - Nombre de ligne : n_elem

    Ensuite il faut remplir les cellules
    - pour la ligne 1, nbCol / 2 = 0, nbCol/2 = 1
    - pour la ligne 2, nbCol / 4 = 0, nbCol/4 = 1
    - pour la ligne 3, nbCol / 8 = 0, nbCol/8 = 1

    Nom : Annotation 2020-05-05 170541.jpg
Affichages : 227
Taille : 19,1 Ko

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    Function FCpartition(n_elem As Integer) As Variant
     
       Dim C As Integer        'Nombre de colonnes
       Dim L As Integer        'Nombre de lignes
       Dim tb_temp
       Dim diviseur As Integer 'Nombre de partitions par ligne
       Dim result As Integer   'Donne un nombre entier, numéro de partition dans la ligne
     
       Dim i As Integer
       Dim y As Integer
     
       L = n_elem
     
       If n_elem = 0 Then
          MsgBox "n_elemen à 0 (zéro)", vbExclamation
          Exit Function
       End If
     
       C = 2 ^ n_elem
       ReDim tb_temp(1 To L, 1 To C)
     
       'Boucle les lignes
       For y = 1 To C
          'Boucle les colonnes
          For i = 1 To L
             diviseur = C / 2 ^ i
             'Défini le numéro de partition de la ligne
             result = WorksheetFunction.RoundUp(y / diviseur, 0)
     
             If result Mod 2 = 0 Then
                'Si numéro de partition paire
                tb_temp(i, y) = 1
             Else
                'Si numéro de partition impaire
                tb_temp(i, y) = 0
             End If
     
          Next
       Next
     
       FCpartition = tb_temp
     
    End Function
    J'ai modifié le nom de votre fonction car une fonction native vba s'appelle déjà Partition.

    Wouana

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. algorithme comportant une fonction récursive
    Par TraxX dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 21/02/2008, 16h09
  2. [XSLT] fonction récursive à N niveaux
    Par Mike35 dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 10/03/2006, 12h30
  3. Fonction récursive renvoi sur page d'erreur
    Par peck dans le forum Langage
    Réponses: 1
    Dernier message: 23/12/2005, 10h08
  4. Problème de fonction récursive avec un TcxDBTreeList
    Par isachat666 dans le forum Composants VCL
    Réponses: 1
    Dernier message: 05/12/2005, 13h12
  5. [VB6] partitions d'un ensemble
    Par perduuu dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 13/09/2004, 16h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo