Bonsoir
On sait que le nombre de dérangements de n éléments peut être extrait de la factorielle de n , en effet n ! = C(n,k).Dn-k ,k compris entre 0 et n
Pouvez vous écrire un algo dans le langage de votre choix permettant de calculer le nombre de dérangements de n objets . ( on choisit un entier quelconque n>2 et le prog retourne le nombre de derangements) on pourra partir du fait que Do=1 et 1=0
Salut,
je propose, en python
Une solution utilisant une autre formule que celle de verdurin
Une autre utilisant une simple factorielle et une division, mais avec une précision de "seulement" 10^9999, ce qui est largement assez en pratique
@Ulmiere
Oui, on peut.
Mais reversed(range(n+1)) retourne bien un itérateur. Essaye de faire next(reversed(range(10**200)) il n'y aura pas de soucis.
Essaye list(range(10**200)), aucune chance que ça passe.
Et ça parce que range implémente la méthode __reversed__(self).
D'un autre côté le coût le plus élevé du programme est le fact *= k (qui devient x*-y dans ta version).
Je trouve mon programme plus clair et plus proche de l'équation de départ le tout sans perte significative d'efficacité.
J'aurais pu même faire ceci :
def derangement(n):
""" Returns the number of derangement of n elements """
factorial = 1
partial_sum = 0
for k in reversed(range(n+1)):
partial_sum += (-1)**k * factorial
factorial *= k
return partial_sum
J'ai mesuré la durée d'exécution pour le calcul de des deux programmes de LittleFox et celle d'un programme utilisant sans récursivité.
def derangeD(n):
" calcule directement le nombre de dérangements pour un ensemble de taille n"
if n==0 : return 1
elif n==1 : return 0
elif n==2 : return 1
a,b = 0,1
for k in range(2,n):
c=k*(a+b)
a=b
b=c
return c
salut
en vba sous excel
Salut flight,
je ne connais pas vba et ( donc ) je comprends mal l'algorithme que tu utilises.
Peux tu le donner en pseudo-code ?
D'avance merci.
PS : tous les programmes précédemment donnés ( je les ai testés ) donnent
D20=895 014 631 192 902 121.
Es-tu d'accord avec cette valeur ?
Je ne peux pas tester to programme, je n'ai pas excel.
pour faire tourner mon code j'ai du bien sur créer deux autres fonction , une qui calcul les combinaisons et une autre les factorielles ( en pseudo code .. je ne vois pas trop ce que tu veux dire )
@verdurin
Évidemment ta formule est efficace. J'ai du mal à voir d'où elle vient par contre Mais elle marche nickel
Si c'est un concours de rapidité d'exécution je propose :
def D(n):
d, a = 1, -1
for k in range(1, n+1):
d *= k
d += a
a = -a
return d
Ah ben si c'est la vitesse qu'on cherche, je pense que cette formule est beaucoup plus rapide
def derangement(n):
u,v = 1,0
for i in range(1,n):
u,v = v, i*(u+v)
return v
print derangement(2000)
Je ne pensais pas vraiment à un concours de vitesse.
En fait je m'intéresse plus à l'efficacité « grossière » des formules qu'a leur optimisation.
Mais je vais regarder ça.
@LittleFox,
« ma » formule vient de ce que j'ai une mémoire de poisson rouge.
Et donc je recherche à chaque fois.
Or il est facile de voir comment obtenir un dérangement de n+1 éléments à partir d'une permutation de n éléments :
-- soit on part d'un dérangement des n premiers éléments et on échange l'élément supplémentaire avec un des éléments de départ ;
-- soit on part d'une permutation n'ayant qu'un point fixe et on échange le point fixe avec l'élément supplémentaire.
Ensuite je me souviens d'avoir démontré que la proba d'avoir une permutation sans point fixe tend vers 1/e, ce qui permet de retrouver la formule que tu utilisas.
Bon j'ai fait la course avec timeit pour le calcul de
Premier Ulmiere avec 485,9s
Second moi avec 489,8s
Troisième LittleFox avec 510,4s.
Soit des différences assez négligeables.
Et je suis curieux de savoir combien tu trouves pour mon approximation par en remplaçant fact(n) par functools.reduce(lambda x,y:x*y,range(2,n+1),1) ?
Mais je pense que ton script était bon car fact(n) n'était calculé qu'une fois, grâce au dictionnaire.
Si on le calcule deux fois ça va pas être bon au niveau temps.
Vous devez être membre accéder à ce service...
Pas encore inscrit ?
1 compte par personne, multi-compte interdit !
Ou identifiez-vous :