[Exel 2010] croiser combinaisons possible pour calcul proba

Résolu/Fermé
jeje1712 Messages postés 17 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 11 octobre 2013 - 2 oct. 2013 à 12:20
 jeje1712 - 18 oct. 2013 à 14:18
Bonjour,

je dispose d'une liste regroupant un nom, une probabilité, et une valeur (un débit en l'occurence).

je cherche à lister toutes les probabilités d'évènement simple, double, triple, quadruple, .... jusqu'à l'évènements "tout arrive en même temps" (bien que sa probabilité soit faible...)


sur un exemple simplifié à 3 noms :


débit Proba Nom
15 0.1 A
10 0.2 B
5 0.5 C
5 0.1 D


je cherche à créer dans ma nouvelle feuille :


débit proba évènement
25 0.02 A B
30 0.05 A C
15 0.1 B C
30 0.01 A B C
30 0.002 A B D
25 0.005 B C D
....





je pensais réussir en travaillant sur une boucle, mais je me rend compte que ça passeras pas :




wsPOccurence -> ma feuille de résumé
wsDataSimu -> ma feuille où se trouve mes data source
dblNbTool -> le nombre total d'équipement présent dans ma liste


dblNbTool = Application.WorksheetFunction.CountA(wsDataSimu.Range("A:A")) - 1

With wsPOccurence
.Range("A1").Value = "Q (L/min)"
.Range("B1").Value = "P Occurence"
.Range("C1").Value = "nom des tools croisés"

For intNbToolCross = 0 To dblNbTool

For intTool = 1 To dblNbTool - intNbToolCross
.Range("B1").Offset(intTool + intNbToolCross * dblNbTool, 0).Value = wsDataSimu.Range("K1").Offset(intTool, 0).Value
.Range("C1").Offset(intTool + intNbToolCross * dblNbTool, 0).Value = wsDataSimu.Range("B1").Offset(intTool, 0).Value
.Range("A1").Offset(intTool + intNbToolCross * dblNbTool, 0).Value = wsDataSimu.Range("C1").Offset(intTool, 0).Value

Next intTool

Next intNbToolCross


ça n'a pas trop de sens, j'avais construit mon premier cycle (zéro cross), mais je n'arrive pas à rendre ma boucle et son exécution dépendante du niveau de cross (doublette, triplette..), ou du moins j'y arrive avec la position où j'écris mais pas sur le contenu (multiplication des proba dépendante du nombre d'équipement crossé)







bon c'est pas facile à expliquer, n'hésitez pas à demander des éclaircissements ou à me proposer une démarche (je pense que la méthode des boucles tel que je le vois n'est pas la bonne)


merci
A voir également:

2 réponses

Zoul67 Messages postés 1959 Date d'inscription lundi 3 mai 2010 Statut Membre Dernière intervention 30 janvier 2023 149
2 oct. 2013 à 13:49
Bonjour,

Je pencherais pour un dictionnaire que tu complètes au fur et à mesure...
- initialisation avec tous les événements unitaires (A, B, ...) ;
- par récursivité, ajout d'une lettre à chaque mot contenu dans le dictionnaire (de préférence à partir de la dernière lettre du mot traité +1 - car je pense que ABC=BAC - pour limiter le temps de calcul) avec stock éventuelle dans une list à 2 dimensions ;
- arrêt du processus quand le mot ajouté contient le même nombre de lettres que le nombre d'événements unitaires.

Une fois que tu as listé tous les mots, je pense qu'il n'y a plus de problème pour le débit et la proba.

A+
0
jeje1712 Messages postés 17 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 11 octobre 2013
2 oct. 2013 à 16:50
okaye ! je ne connais pas les dictionnaires, je me doutais bien qu'il pouvait y avoir autre chose de mieux construit qu'une boucle
et de même pour les récursivités (et oui mes connaissances sont infimes !)

Je vais creuser tout ça, je reviendrais ici dès que ce sera mieux débrouissallé

merci
0
jeje1712 Messages postés 17 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 11 octobre 2013
Modifié par jeje1712 le 4/10/2013 à 10:05
bonjour,



Concernant la méthode dictionnaire, de ce que j'ai compris, ça me permettra de créer ma liste de noms croisés. pourquoi pas, mais je perds l'info de localisation de la cellule, du coup une foix ma liste créée, je vais devoir identifier les différents termes, puis faire une recherche type vlookup pour trouver la ligne, puis multiplier mes valeurs.
pourquoi pas. J'ai commencé dessus.


parrallèlelement, j'ai continué par des boucles for incrémentées les unes dans les autres selon le niveau de cross que je cherche. ça donne ça :







lngPosition me sers à me positionner tout au long de ma feuille résumé pour lister tout ça



'1er niveau de bouclage, on forme des doubles

intNbToolCross = 1

j = 2
For i = 1 To dblNbTool - intNbToolCross

For jb = j To dblNbTool
.Range("B1").Offset(lngPosition, 0).Value = wsDataSimu.Range("K1").Offset(i, 0).Value * wsDataSimu.Range("K1").Offset(jb, 0).Value

.Range("C1").Offset(lngPosition, 0).Value = wsDataSimu.Range("B1").Offset(i, 0).Value
.Range("C1").Offset(lngPosition, 1).Value = wsDataSimu.Range("B1").Offset(jb, 0).Value

.Range("A1").Offset(lngPosition, 0).Value = wsDataSimu.Range("C1").Offset(i, 0).Value + wsDataSimu.Range("C1").Offset(jb, 0).Value

lngPosition = lngPosition + 1


Next jb
j = j + 1 '

Next i






'2eme niveau de bouclage, on fait des triplettes



intNbToolCross = 2


j = 2
k = 3
For i = 1 To (dblNbTool - intNbToolCross)


For jb = j To dblNbTool


For kb = k To dblNbTool

.Range("B1").Offset(lngPosition, 0).Value = wsDataSimu.Range("K1").Offset(i, 0).Value * wsDataSimu.Range("K1").Offset(jb, 0).Value * wsDataSimu.Range("K1").Offset(kb, 0).Value

.Range("C1").Offset(lngPosition, 0).Value = wsDataSimu.Range("B1").Offset(i, 0).Value
.Range("C1").Offset(lngPosition, 1).Value = wsDataSimu.Range("B1").Offset(jb, 0).Value
.Range("C1").Offset(lngPosition, 2).Value = wsDataSimu.Range("B1").Offset(kb, 0).Value

.Range("A1").Offset(lngPosition, 0).Value = wsDataSimu.Range("C1").Offset(i, 0).Value + wsDataSimu.Range("C1").Offset(jb, 0).Value + wsDataSimu.Range("C1").Offset(kb, 0).Value

lngPosition = lngPosition + 1

Next kb
k = k + 1

Next jb
j = j + 1
k = j + 1

Next i



'3eme niveau de bouclage, on fait des quadriplets

intNbToolCross = 3
j = 2
k = 3
l = 4
For i = 1 To (dblNbTool - intNbToolCross)


For jb = j To dblNbTool


For kb = k To dblNbTool

For lb = l To dblNbTool

.Range("B1").Offset(lngPosition, 0).Value = wsDataSimu.Range("K1").Offset(i, 0).Value * wsDataSimu.Range("K1").Offset(jb, 0).Value * wsDataSimu.Range("K1").Offset(kb, 0).Value * wsDataSimu.Range("K1").Offset(lb, 0).Value

.Range("C1").Offset(lngPosition, 0).Value = wsDataSimu.Range("B1").Offset(i, 0).Value
.Range("C1").Offset(lngPosition, 1).Value = wsDataSimu.Range("B1").Offset(jb, 0).Value
.Range("C1").Offset(lngPosition, 2).Value = wsDataSimu.Range("B1").Offset(kb, 0).Value
.Range("C1").Offset(lngPosition, 3).Value = wsDataSimu.Range("B1").Offset(lb, 0).Value

.Range("A1").Offset(lngPosition, 0).Value = wsDataSimu.Range("C1").Offset(i, 0).Value + wsDataSimu.Range("C1").Offset(jb, 0).Value + wsDataSimu.Range("C1").Offset(kb, 0).Value + wsDataSimu.Range("C1").Offset(lb, 0).Value

lngPosition = lngPosition + 1


Next lb
l = l + 1

Next kb
k = k + 1
l = k + 1

Next jb
j = j + 1
k = j + 1
l = k + 1

Next i












----------------------------

voilà, tout fonctionne très bien, je pourrais continuer en écrivant chaque niveau, mais bon sur 30 niveaux se serait long.

Je cherche donc un moyens de boucler sur le nombre N total de nom que j'ai initialement, mais du coup il faut que ça crée le nombre d'incrémentation de boucle for au fur et à mesure que l'on augmente dans les cross




quelqu'un a une idée ???











MAJ :

le niveau 7 :
intNbToolCross = 7
j = 2
k = 3
l = 4
m = 5
n = 6
o = 7
p = 8

For i = 1 To (dblNbTool - intNbToolCross)


For jb = j To dblNbTool


For kb = k To dblNbTool

For lb = l To dblNbTool

For mb = m To dblNbTool

For nb = n To dblNbTool

For ob = o To dblNbTool

For pb = p To dblNbTool

.Range("B1").Offset(lngPosition, 0).Value = wsDataSimu.Range("K1").Offset(i, 0).Value * _
wsDataSimu.Range("K1").Offset(jb, 0).Value * wsDataSimu.Range("K1").Offset(kb, 0).Value * _
wsDataSimu.Range("K1").Offset(lb, 0).Value * wsDataSimu.Range("K1").Offset(mb, 0).Value * _
wsDataSimu.Range("K1").Offset(nb, 0).Value * wsDataSimu.Range("K1").Offset(ob, 0).Value * _
wsDataSimu.Range("K1").Offset(pb, 0).Value

.Range("C1").Offset(lngPosition, 0).Value = wsDataSimu.Range("B1").Offset(i, 0).Value
.Range("C1").Offset(lngPosition, 1).Value = wsDataSimu.Range("B1").Offset(jb, 0).Value
.Range("C1").Offset(lngPosition, 2).Value = wsDataSimu.Range("B1").Offset(kb, 0).Value
.Range("C1").Offset(lngPosition, 3).Value = wsDataSimu.Range("B1").Offset(lb, 0).Value
.Range("C1").Offset(lngPosition, 4).Value = wsDataSimu.Range("B1").Offset(mb, 0).Value
.Range("C1").Offset(lngPosition, 5).Value = wsDataSimu.Range("B1").Offset(nb, 0).Value
.Range("C1").Offset(lngPosition, 6).Value = wsDataSimu.Range("B1").Offset(ob, 0).Value
.Range("C1").Offset(lngPosition, 6).Value = wsDataSimu.Range("B1").Offset(pb, 0).Value

.Range("A1").Offset(lngPosition, 0).Value = wsDataSimu.Range("C1").Offset(i, 0).Value + _
wsDataSimu.Range("C1").Offset(jb, 0).Value + wsDataSimu.Range("C1").Offset(kb, 0).Value + _
wsDataSimu.Range("C1").Offset(lb, 0).Value + wsDataSimu.Range("C1").Offset(mb, 0).Value + _
wsDataSimu.Range("C1").Offset(nb, 0).Value + wsDataSimu.Range("C1").Offset(ob, 0).Value + _
wsDataSimu.Range("C1").Offset(pb, 0).Value

lngPosition = lngPosition + 1

Next pb
p = p + 1

Next ob
o = o + 1
p = o + 1

Next nb
n = n + 1
o = n + 1
p = o + 1

Next mb
m = m + 1
n = m + 1
o = n + 1
p = o + 1

Next lb
l = l + 1
m = l + 1
n = m + 1
o = n + 1
p = o + 1

Next kb
k = k + 1
l = k + 1
m = l + 1
n = m + 1
o = n + 1
p = o + 1

Next jb
j = j + 1
k = j + 1
l = k + 1
m = l + 1
n = m + 1
o = n + 1
p = o + 1

Next i


mais je suis très vite limité par l'affiage de nombre de ligne excel : 1 048 576.


comment passer outre?
0
jeje1712 Messages postés 17 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 11 octobre 2013
4 oct. 2013 à 16:16
mais je suis très vite limité par l'affiage de nombre de ligne excel : 1 048 576.


comment passer outre?
.

--> l'array ! ok merci
0
jeje1712 Messages postés 17 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 11 octobre 2013
4 oct. 2013 à 16:23
et voici le 6ème niveau en plus propre :


    i = 1

intNbToolCross = 6
dblFactorielleNP = 1

While (i <= (dblNbTool - intNbToolCross - 1))
dblFactorielleNP = dblFactorielleNP * i
i = i + 1
Wend


i = 1
dblFactorielleP = 1
While (i <= (intNbToolCross + 1))
dblFactorielleP = dblFactorielleP * i
i = i + 1
Wend

i = 1
dblFactorielleN = 1
While (i <= (dblNbTool))
dblFactorielleN = dblFactorielleN * i
i = i + 1
Wend

dblFactorielle = dblFactorielleN / (dblFactorielleP * dblFactorielleNP)
lngSizeArray = lngSizeArray + dblFactorielle
ReDim Preserve arrDataCross(3, lngSizeArray)



le calcul factoriel permet d'grandir la taille de l'array en fonction du nombre total d'évènements, à chaque fois j'additionne à lngSizeArray la taille calculée de l'évènement en question (ici les sextuplets)






j = 2
k = 3
l = 4
m = 5
n = 6
o = 7
For i = 1 To (dblNbTool - intNbToolCross)


For jb = j To dblNbTool


For kb = k To dblNbTool

For lb = l To dblNbTool

For mb = m To dblNbTool

For nb = n To dblNbTool

For ob = o To dblNbTool

arrDataCross(0, lngPosition) = _
wsDataSimu.Range("C1").Offset(i, 0).Value + _
wsDataSimu.Range("C1").Offset(jb, 0).Value + _
wsDataSimu.Range("C1").Offset(kb, 0).Value + _
wsDataSimu.Range("C1").Offset(lb, 0).Value + _
wsDataSimu.Range("C1").Offset(mb, 0).Value + _
wsDataSimu.Range("C1").Offset(nb, 0).Value + _
wsDataSimu.Range("C1").Offset(ob, 0).Value


arrDataCross(1, lngPosition) = _
wsDataSimu.Range("K1").Offset(i, 0).Value * _
wsDataSimu.Range("K1").Offset(jb, 0).Value * _
wsDataSimu.Range("K1").Offset(kb, 0).Value * _
wsDataSimu.Range("K1").Offset(lb, 0).Value * _
wsDataSimu.Range("K1").Offset(mb, 0).Value * _
wsDataSimu.Range("K1").Offset(nb, 0).Value * _
wsDataSimu.Range("K1").Offset(ob, 0).Value

arrDataCross(2, lngPosition) = _
CStr(wsDataSimu.Range("B1").Offset(i, 0).Value) & " " & _
CStr(wsDataSimu.Range("B1").Offset(jb, 0).Value) & " " & _
CStr(wsDataSimu.Range("B1").Offset(kb, 0).Value) & " " & _
CStr(wsDataSimu.Range("B1").Offset(lb, 0).Value) & " " & _
CStr(wsDataSimu.Range("B1").Offset(mb, 0).Value) & " " & _
CStr(wsDataSimu.Range("B1").Offset(nb, 0).Value) & " " & _
CStr(wsDataSimu.Range("B1").Offset(ob, 0).Value)



lngPosition = lngPosition + 1

Next ob
o = o + 1

Next nb
n = n + 1
o = n + 1

Next mb
m = m + 1
n = m + 1
o = n + 1

Next lb
l = l + 1
m = l + 1
n = m + 1
o = n + 1

Next kb
k = k + 1
l = k + 1
m = l + 1
n = m + 1
o = n + 1

Next jb
j = j + 1
k = j + 1
l = k + 1
m = l + 1
n = m + 1
o = n + 1

Next i
0
jeje1712 Messages postés 17 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 11 octobre 2013
4 oct. 2013 à 16:29
et encore une question :


je valide la méthode en affichant l'array dans une feuille, à chaque fin de traitement de cross, via :

 .Range("A2").Resize(lngPosition, 3).Value = Application.WorksheetFunction.Transpose(arrDataCross)

mais alors à la fin des quadriplets, j'ai un message d'erreur ;
Run-time error '13' . type mismatch

je ne comprend pas pourquoi .... alors que ce message n'apparait pas pour les 2 niveaux précédents (duo et triplet)

lngPosition = 74518
et arrDataCross(3, lngSizeArray)
avec lngSizeArray = 74518


des idées?
0
Zoul67 Messages postés 1959 Date d'inscription lundi 3 mai 2010 Statut Membre Dernière intervention 30 janvier 2023 149
7 oct. 2013 à 12:44
Bonjour,

Je n'étais pas disponible à partir de vendredi.
Tu as pu avancer ? Tu souhaites de l'aide ?
Avec 30 événements redoutés, ça amène à un nombre de combinaisons gigantesque (la valeur de C(30,15) est effrayante). L'exhaustivité ici apporte sans doute de la confusion...

A+
0
jeje1712 Messages postés 17 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 11 octobre 2013
10 oct. 2013 à 09:47
Bonjour,



J'ai pas mal avancé à ce sujet, et j'ai réussi à construire ma macro en la stockant dans un array. C'était les quantitées de lignes affiché qui me faisait buguer, dans les grandes lignes :

- la limite en ligne est de 1 048 000 (arondi)
- la limte en colonne est vers 13 000
- et la fonction transpose limite automatique à 65 000 lignes

maintenant mon array reste virtuel et je le traite directement.

Mon dernier soucis est de chercher à simplifier ce code :


intNbToolCross = 4
j = 2
k = 3
l = 4
m = 5
For i = 1 To (dblNbTool - intNbToolCross)


For jb = j To dblNbTool


For kb = k To dblNbTool

For lb = l To dblNbTool

For mb = m To dblNbTool
arrDataCross(0, lngPosition) = _
wsDataPhoto.Range("C1").Offset(i, 0).Value + _
wsDataPhoto.Range("C1").Offset(jb, 0).Value + _
wsDataPhoto.Range("C1").Offset(kb, 0).Value + _
wsDataPhoto.Range("C1").Offset(lb, 0).Value + _
wsDataPhoto.Range("C1").Offset(mb, 0).Value


arrDataCross(1, lngPosition) = _
wsDataPhoto.Range("K1").Offset(i, 0).Value * _
wsDataPhoto.Range("K1").Offset(jb, 0).Value * _
wsDataPhoto.Range("K1").Offset(kb, 0).Value * _
wsDataPhoto.Range("K1").Offset(lb, 0).Value * _
wsDataPhoto.Range("K1").Offset(mb, 0).Value

arrDataCross(2, lngPosition) = _
CStr(wsDataPhoto.Range("B1").Offset(i, 0).Value) & " " & _
CStr(wsDataPhoto.Range("B1").Offset(jb, 0).Value) & " " & _
CStr(wsDataPhoto.Range("B1").Offset(kb, 0).Value) & " " & _
CStr(wsDataPhoto.Range("B1").Offset(lb, 0).Value) & " " & _
CStr(wsDataPhoto.Range("B1").Offset(mb, 0).Value)


lngPosition = lngPosition + 1

Next mb
m = m + 1
Next lb
l = l + 1
m = l + 1

Next kb
k = k + 1
l = k + 1
m = l + 1

Next jb
j = j + 1
k = j + 1
l = k + 1
m = l + 1

Next i


En effet, ci-dessus se trouve le niveau 4 (5 noms simultanément) pour l'exemple, mais j'aimerais que cette routine, basée sur l'incrémentation de x boucles for, se crée automatiquement en fonction du paramètre x justement.

Ainsi, soit je boucle sur ce paramètre x jusqu'à mon xmax, limité par ma mémoire.

Soit je traite un niveau x avec les calculs associé, puis je vide la mémoire et traite le x+1, puis x+2 ... Ce qui m'intéresserait car je pourrais traité un niveau plus élevé.

comme tu l'as remarqué, le nombre de combinaison va passer le cap des milliards, mais je n'irais pas aussi loin ^^. Nénamoins, avec cette méthode, je pourrais gratter un ou deux niveaux en plus :)


Bref, ce que je cherche donc c'est que ma macro crée le nombre d'incrémentation de boucle for selon une variable x.


Aurais-tu une idée ?
0