Générateur de dénombrement

Programmation d'applications complexes
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Générateur de dénombrement

Message par PAPIPP »

Bonjour à tous
Voici 5 procédures récursives permettant de générer 4 sortes de combinaisons.
Fact(x) factorielle de x est ici pour permettre le calcul dans chaque procédure, par cohérence elle est aussi récursive
Combin_tot() génère des arrangements avec remise
Combin() génère des combinaisons l’ordre n’ importe pas 012 ,021 ….210 ne compte que pour 1 combinaison
Arrang() génère des arrangements sans remise ici l’ordre différent donne des combinaisons différentes
Permute() génère des permutations

Chacune de ces procédures doit être déterminée par
1) Un nombre de cases à générer
2) Un minimum à obtenir pour chaque case
3) un maximum à obtenir pour chaque case

Chaque combinaison est un vecteur d’indice obtenu dans une table à une dimension.
Ceci permet pour chaque combinaison de générer des groupes de caractères ou des groupes de nombres dans l’ordre de l’indice de la combinaison
Ces générateurs peuvent par exemple générer en binaire les 256 combinaisons d’un octet
Init(8,0,1) => nombre de cases 8 cases minimum 0 maximum 1 => génère avec la procédure combin_tot()
Init(x,y,z) est la procédure d’initiation avec
x=nombre de case
y=indice minimum dans une case
z=indice maximum dans une case.

Pour l’exemple j’ai utilisé la fameuse phrase de Molière :
, "Belle Marquise, vos beaux yeux, me font mourir, d'amour ",
Elle contient 9 mots fact(9)= 362880 beaucoup trop important
j’ai donc limité à 4 groupes avec pour délimiteur virgule (3 virgules) donc 4 groupes fact(4)= 24
Avec ces deux instructions :

I

Code : Tout sélectionner

Global Dim Table_car$(0)
CreateRegularExpression(0, "[A-Za-z']+[^,]+");;;; retirer les espaces la virgule  et , ; : 
  NbResults = ExtractRegularExpression(0, "Belle  Marquise,  vos beaux yeux, me font mourir, d'amour  ", Table_car$())
Voici les procédures

Code : Tout sélectionner

; Macro _Q (__Q)
; _q_t_#__Q#=_q_t_+Str(__Q)+" "
; EndMacro
; Macro _n (__n)
; _q_t_#__n#=_q_t_+Str(__n)+" "
; EndMacro
  EnableExplicit
  Procedure init(nbcas,Minca,maxca)
;   Global Dim vect_permut(0)  
  Global Dim Table_car$(0)
  Global nb=0,nb1=0,nb2=0, nbpermute.q=0
  Global NBcase=8 ,Mincase=0 ,MAXcase=3 ;;;; prendre 0 pour generer à partir de 0 ou 1 pour generer à partir de 1 
  Global Dim tab(MAXcase+100)
;   Debug  "Mincase ="+Str(Minca)+" NBcase = "+Str(NBcase)+" MAXcase = "+Str(MAXca)
  nbcase=nbcas
  maxcase=maxca
  If Minca < maxca
    Mincase=Minca
  Else
    Mincase=MAXcase
  EndIf
  Debug  " NBcase = "+Str(NBcase)+" ,Mincase = "+Str(Mincase)+" ,MAXcase = "+Str(MAXcase)
EndProcedure
; ProcedureDLL.q FACT(Nb.q)
;   Define result.q
;   If Nb < 2
;     result.q = 1
;   Else
;     result.q = Fact(Nb-1)*Nb
;   EndIf
;   ProcedureReturn result
; EndProcedure
Procedure.q Fact(n.q) 
  If n<2
    ProcedureReturn 1
  Else
    ProcedureReturn n*Fact(n-1)
  EndIf
EndProcedure 
; Procedure vtab()
;   res$=""
;   For vi=1  To Nbcase
;     res$+Str(Tab(vi))+","
;   Next
;   Debug res$
; EndProcedure
; Procedure exploite_ind(chaine$)
;   result$=""
; ;   max=Len(chaine$)
;   For ixi=1 To nbcase
; ;     result$+Mid(chaine$,Random(Len(chaine$)),1)
;     result$+Mid(chaine$,tab(ixi),1)
;   Next
;   Debug chaine$+"    "+result$
; EndProcedure  
Procedure Combin_tout(ind=1)
  Define nbcombintot.q, i, j, deb$
  Static xx
  If xx=0 ;;; test pour exécuter une seule fois au premier appel avec l'option static xx
    xx+1
    Debug "******** Combinaison avec répétition ou arrangement avec remise ********"
    nbcombintot.q=Pow(maxcase+(1-Mincase),Nbcase)
    Debug  " Arrangements avec remise = pow("+Str(maxcase+(1-Mincase))+","+Str(nbcase)+") = "+Str(nbcombintot)
  EndIf
  
  If ind<NBcase+1
    For i=Mincase To MAXcase ; prendre 0 pour generer à partir de 0 ou 1 pour generer à partir de 1
      tab(ind)=i
      Combin_tout(ind+1)
    Next
  Else
    deb$=""
    For j=1 To NBcase
      deb$+Str(tab(j))+","
      ;       tab(j)=0
    Next
    nb+1
    Debug deb$+"  ="+Str(nb)
    ;     exploite_ind("Pierre")
    
  EndIf
EndProcedure
Procedure combin(ind=1)
  Define nbcombin.q, i, j, deb$ , ix
  Static xx
  If xx=0 ;;; test pour exécuter une seule fois au premier appel avec l'option static xx
    xx+1
    Debug "******** Combinaisons sans répétition  ********"
    nbcombin.q=fact(maxcase+(1-Mincase))/(fact(maxcase+(1-Mincase)-Nbcase)*fact(nbcase))
    Debug  " Combinaisons s = fact("+Str(maxcase+(1-Mincase))+") / (fact("+Str(maxcase+(1-Mincase)-nbcase)+") * fact("+Str(nbcase)+") = "+Str(nbcombin)
  EndIf
  
  If ind<NBcase+1
    If ind>1 
      ix=tab(ind-1)+1
    Else 
      ix=Mincase
    EndIf  
    For i=ix To MAXcase ; prendre 0 pour generer à partir de 0 ou 1 pour generer à partir de 1
      tab(ind)=i
      combin(ind+1)
    Next
  Else
    deb$=""
    For j=1 To NBcase
      deb$+Str(tab(j))+","
      ;       tab(j)=0
    Next
    nb1+1
    Debug deb$+"  ="+Str(nb1)
    
    ;     exploite_ind("Pierre")
    ;     vtab()
  EndIf

EndProcedure
Procedure arrang(ind=1)
  Define nbarrang.q, ic, jc, deb$, imp, result$, i,vp,resu$
  Static xx
  If xx=0 ;;; test pour exécuter une seule fois au premier appel avec l'option static xx
    xx+1
    Debug "******** Arrangements sana remise  ********"
    If (maxcase+(1-Mincase)-Nbcase)>-1
      nbarrang.q=fact(maxcase+(1-Mincase))/(fact(maxcase+(1-Mincase)-Nbcase))
    Else
      nbarrang.q=0
    EndIf
    Debug  " Arrangements sans remise s = fact("+Str(maxcase+(1-Mincase))+") / fact("+Str(maxcase+(1-Mincase)-nbcase)+") = "+Str(nbarrang)
  EndIf
  If ind<NBcase+1
    For i=Mincase To MAXcase ; prendre 0 pour generer à partir de 0 ou 1 pour generer à partir de 1
      tab(ind)=i
      arrang(ind+1)
    Next
  Else
    result$=""
    For ic=1 To Nbcase
      For jc=ic+1 To Nbcase
        If tab(ic)<>tab(jc)
        Else
          imp-1
          Break
          result$=""
        EndIf 
      Next
      ;;;;;**********  test pour passer de la table des indices à la genération  on peut utiliser cette option
      ;;;;;;           pour les autres fonctions combin_tout combin 
      If  Table_car$(0)=""
        result$+Str(tab(ic))+","
      Else
        result$+table_car$(tab(ic))+" "
      EndIf 
   ;;;;;********** fin du test pour passer de la table des indices à la genération     
     
    Next 
    If imp=0
      nb2+1
      
      Debug result$+"  ="+Str(nb2)
      ;     exploite_ind("Pierre")
      ;       vtab()
      ;       exploite_ind("Pierre")
    EndIf
    imp=0
  EndIf
EndProcedure
Procedure permute()
  Global M_nbcase, m_mincase,m_maxcase
  Static xx
  If xx=0 ;;; test pour exécuter une seule fois au premier appel avec l'option static xx
    M_nbcase=nbcase
    m_mincase=mincase
    m_maxcase=maxcase
;     Debug _nl+_n(nbcase)+_n(mincase)+_n(maxcase)

    If nbcase>(maxcase+1-mincase)
      nbcase=maxcase+1-mincase
     EndIf  
    xx+1
    Debug "******** permutations  ********"
;     Debug  "Mincase ="+Str(Mincase)+" NBcase = "+Str(NBcase)+" MAXcase = "+Str(MAXcase)
    nbpermute.q=fact(Nbcase)
;     ReDim vect_permut(nbcase)
    Debug  " Permutations =  fact("+Str(nbcase)+") = "+Str(nbpermute)
    nb2=0
  EndIf
;    Debug _nl+_n(nbcase)+_n(mincase)+_n(maxcase)
   mincase=0
  maxcase=nbcase-(1-Mincase)
  arrang()
;     Debug _nl+_n(nbcase)+_n(mincase)+_n(maxcase)
  nbcase=M_nbcase
  mincase=m_mincase
  maxcase=m_maxcase
;   Debug _nl+_n(nbcase)+_n(mincase)+_n(maxcase)
;   Debug _nl+_n(m_nbcase)+_n(m_mincase)+_n(m_maxcase)

EndProcedure
;;;init(nbcas,Mincase,maxcase)
init(3,0,4)
Combin_tout()
combin()
arrang()
permute()
DisableExplicit

; ;;;*************Création d'une table de caractères ******"
; ;;; If CreateRegularExpression(0, "[A-Za-z']+[^  ,;:]+");;;; retirer les espaces la virgule  et , ; : 
If CreateRegularExpression(0, "[A-Za-z']+[^,]+");;;; retirer les espaces la virgule  et , ; : 
  NbResults = ExtractRegularExpression(0, "Belle  Marquise,  vos beaux yeux, me font mourir, d'amour  ", Table_car$())
;   Debug "Nb matchs found: " + NbResults
;   For i = 0 To NbResults - 1
;     Debug Table_car$(i)
;   Next
Else
  MessageRequester("Error", RegularExpressionError())
EndIf
nbcase=ArraySize(Table_car$())+1
    nbpermut.q=fact(Nbcase)
    Debug  " ******* Permutations du groupe de caractères =  fact("+Str(nbcase)+") = "+Str(nbpermut)
nb2=0
permute()

A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Ollivier
Messages : 4197
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Générateur de dénombrement

Message par Ollivier »

Je découvre à l'instant ce sujet. Pas facile depuis la nouvelle présentation du forum : très contre-productif, car, au moins sur smartphone, on ne voit rien. Il faut chercher, perdre beaucoup de temps. Ça casse la dynamique. Peut-être une remarque si c'est le même problème sur ordinateur, peut-être pas...

@papipp

merci pour ce partage, il va falloir du temps pour l'analyse, chercher l'utilité, et produire un retour. Et ce temps n'est pas toujours là...
Répondre