Bonjour
Je vous propose l'exercice suivant , on se donne les entiers allant de 1 à 10 , on effectue un tirage successif et sans remise au hasard de 5 entiers dans cet ensemble , Quelle est la probabilité que la différence entre deux entiers successifs du tirage soit strictement supérieure à 1 en valeur absolue ? exemple de tirage qui convient: 8 2 5 1 6
exemple de tirage qui ne convient pas : 8 2 5 4 6
D'où vient le 14700 ?
D'où vient le 5!
Et on voit assez bien d'où vient le 10!
Le 5! me paraît très suspect.
Ici, à part un recensement exhaustif des 10!configurations, je ne vois pas trop de méthode.
Le gros problème, c'est que les tirages ne sont pas du tout indépendants. Si on commence par 6,3,5 ... ou par 7,3,5, la proba que la 4ème boule donne un clash n'est pas la même.
Bonjour,
Je suis d'accord avec ty59847, je ne sais pas comment calculer cette probabilité facilement et comme les valeurs sont faibles, le plus rapide pour moi est de demander à un esclave numérique de le faire. Il me répond 967/2520 mais si vous avez plus élégant, je veux bien regarder.
import itertools
def ecart(list,n):
compt=0
nb=0
for subset in itertools.permutations(list,int(n)):
nb+=1
for i in range(n-1):
if subset[i+1]==subset[i]+1 or subset[i+1]==subset[i]-1:
compt+=1
break
return((nb-compt)/nb)
print(ecart([1,2,3,4,5,6,7,8,9,10],5))
merci à Vassillia de m'avoir obligé à aller voir ce qu'est ce module itertools que je rencontrais souvent sans savoir ce qu'il faisait !!
from math import gcd, comb, factorial
import itertools
def ecart(N, n):
nb = comb(N,n)*factorial(n)#30240#__import__("math").comb(len(list),5)
compt = sum( any( (subset[i+1]-subset[i])**2<2 for i in range(n-1) ) for subset in itertools.permutations(range(N), n) )
u, v, g = nb-compt, nb, gcd(nb-compt,nb)
return "%d/%d"%(u//g,v//g)
N,n = 10,5
print(ecart(N,n))
Il y a un commentaire en trop qui correspond à des tests que j'effectuais.
Si quelqu'un qui a les droits pour éditer mon post pouvait supprimer "#30240#__import__("math").comb(len(list),5)" du code ci-dessus, ainsi que le présent message, ce serait peut-être plus lisible
Et voici une version pour les gens qui n'ont pas au moins python 3.8 (pour la fonction comb)
Désolé du triple post
def ecart(N, n):
nb = __import__("functools").reduce(lambda x,y:x*y,range(N-n+1,N+1),1)
compt = sum(all((s[i+1]-s[i])**2>1 for i in range(n-1))for s in __import__("itertools").permutations(range(N),n))
g = __import__("math").gcd(compt,nb)
return "%d/%d"%(compt//g, nb//g)
print(ecart(10,5))
J'avoue que je n'ai pas cherché à optimiser le code, je savais vu les petites valeurs que ça passerait sans problème donc j'y suis allée tranquille.
Mais même si j'avais voulu, je n'aurais pas fait aussi bien que toi. Je connais mal python, je m'y suis mise comme c'est le langage à la mode sur les forums et il faut admettre que c'est facile à lire et à écrire. Merci Ulmiere pour la sommation des booléens, j'aime bien et je ne savais pas donc je m'en reservirai à l'occasion
Carpediem, c'est surtout de la flemme de ma part, il y avait fort à parier que lister les combinaisons et les permutations avait deja été fait par quelqu'un et une petite recherche me l'a donné directement. Tant mieux si ça peut te resservir, je présume que c'est mieux optimisé que tout ce que j'aurais pu faire.
Vassillia et Ulmiere : je ne suis pas très doué en python même si j'avais bien vu qu'on pouvait "un peu" optimiser le code ...
mais l'optimisation de Ulmiere dépasse mes connaissances ... et donc le rend plus "kabbalistique" et ésotérique !!!
J'explique, donc
Il y'a deux optimisations différentes. La première consiste à éviter d'incrémenter nb de tour de boucle en tour de boucle à lui donner directement sa valeur finale (5 parmi 10)*(5!). C'est évidemment beaucoup plus rapide que de faire 30240 tours de boucle à la fin desquels on ferait nb <- nb +1. La seconde c'est autre chose.
***
for subset in itertools.permutations(range(N), n)
énumère toutes les suites de 5 éléments tous différents de [1,2,3,4,5,6,7,8,9,10]
def any(iterable):
for x in iterable:
if (x == True):
return True
else:
return False
sum( any(iterable) for iterable in conteneur )
je suis en train de sommer des 0 et des 1. Le résultat de ce truc est le nombre d'élements de conteneur ayant au moins un élément qui est True
compt = sum( any( (subset[i+1]-subset[i])**2<2 for i in range(n-1) ) for subset in itertools.permutations(range(N), n) )
merci beaucoup à Ulmiere pour tes éclaircissements
j'avais à peu près compris mais voulais être sûr ne connaissant pas vraiment l'utilisation de any et all ...
c'est vraiment très efficace donc
Bonjour,
Comme j'avais listé les 11604 candidats,j'ai voulu dénombrer ceux qui étaient premiers.
Ils sont 966 de 1 3 5 9 7 à 9 7 10 6 3 (13 597 à 971 063 )
Bonne chance aux vérificateurs
N = 10, n = 1, nb = 10 : (7, 7)
N = 10, n = 2, nb = 90 : (107, (10, 7))
N = 10, n = 3, nb = 720 : (8101, (8, 10, 1))
N = 10, n = 4, nb = 5040 : (97103, (9, 7, 10, 3))
N = 10, n = 5, nb = 30240 : (971063, (9, 7, 10, 6, 3))
N = 10, n = 6, nb = 151200 : (9758101, (9, 7, 5, 8, 10, 1))
N = 10, n = 7, nb = 604800 : (97581041, (9, 7, 5, 8, 10, 4, 1))
N = 10, n = 8, nb = 1814400 : (975864103, (9, 7, 5, 8, 6, 4, 10, 3))
N = 10, n = 9, nb = 3628800 : (9758631041, (9, 7, 5, 8, 6, 3, 10, 4, 1))
N = 10, n = 10, nb = 3628800 : (97586210413, (9, 7, 5, 8, 6, 2, 10, 4, 1, 3))
Vous devez être membre accéder à ce service...
Pas encore inscrit ?
1 compte par personne, multi-compte interdit !
Ou identifiez-vous :