π
<-

Aide pour un algo récursif

Discussions scientifiques et scolaires

Aide pour un algo récursif

Message non lude Bisam » 16 Fév 2014, 23:03

Bonsoir,

Je suis en galère avec un algorithme récursif destiné à la résolution d'un problème de Project Euler.
Je ne veux pas vraiment que vous me donniez une solution mais que vous me disiez si vous voyez ce qui ne va pas...

Voici le code Python (pour ceux qui ne le maîtrisent pas, ça se lit presque comme du pseudo-code).
Les """ servent à encadrer des commentaires

Le but est de trouver le nombre d'ensembles constitués de nombres premiers dont les chiffres sont les chiffres de 1 à 9 écrits une et une seule fois chacun.
Code: Tout sélectionner
def pb118()

    """On calcule une liste de True et False, servant d'oracle pour savoir si un entier est premier."""

    isprime = eratho(10 ** 8)

    """Avec cet oracle, on fait une liste des nombres premiers qui ne contiennent pas le chiffre 0.
    On les enregistre sous forme de chaînes de caractères."""

    primes = [str(i) for i in range(10 ** 8) if isprime[i] and '0' not in str(i)]

    """Ensuite, on fait une liste des ensembles des chiffres composant les nombres premiers
    qui ne contiennent aucun chiffre répété. C'est de cette liste qu'on se servira dans la fonction récursive."""

    primedigits = [{int(j) for j in a} for a in primes if all(u not in a[k + 1:] for k, u in enumerate(a))]

    """res contiendra le résultat cherché. On utilise une liste car cela évite d'avoir à la déclarer globale..."""

    res = [0]

    def search(currentdigits, nextindex):
        """Cherche récursivement des nombres premiers à rajouter au panier et fait le compte
        des paniers trouvés."""
        l = len(currentdigits)
        if l == 9:
        """Dans ce cas, on a forcément : currentdigits = {1, 2, 3, 4, 5, 6, 7, 8, 9}"""
            res[0] += 1
        else:
            for i, newDigits in enumerate(primedigits[nextindex:]):
                if len(newDigits) + l > 9:
        """Inutile de poursuivre si les nombres premiers suivants ont trop de chiffres."""
                    break
                if currentdigits.isdisjoint(newDigits):
        """On rajoute les nouveaux chiffres et on continue à chercher récursivement à partir
        du rang suivant dans la liste des premiers."""
                    search(currentdigits | newDigits, i + 1)

    """On commence à chercher à partir d'un ensemble vide, et à partir de l'indice 0."""
    search(set(), 0)

    return(res[0])


Ce programme ne renvoie malheureusement pas le bon résultat... mais je ne sais pas pourquoi.
Si vous comprenez ce code et que vous voyez pourquoi ça ne marche pas... merci de me le dire !

PS : Pour ceux qui voudraient essayer l'algorithme chez eux, c'est du Python 3.
Pour info, le calcul de "primedigits" au départ prend 540Mo de RAM environ et un peu moins de 4 minutes.
Ensuite, la recherche récursive ne prend que 3 minutes environ.
Avatar de l’utilisateur
BisamAdmin
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Prochain niv.: 69.6%
 
Messages: 5670
Inscription: 11 Mar 2008, 00:00
Localisation: Lyon
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: Aide pour un algo récursif

Message non lude Lionel Debroux » 19 Fév 2014, 19:28

Tiens, je ne l'avais jamais fait, cet algorithme-là du projet Euler. En même temps, je n'en avais fait qu'exactement 50 ^^

{1, 2, 3, 4, 5, 6, 7, 8, 9} n'est pas constitué exclusivement d'éléments premiers ?
Il ne doit pas y avoir beaucoup d'ensembles d'éléments appartenant au problème qui ont 6 éléments ou plus.
Parmi les éléments permettant l'élagage des possibilités, toutes les entrées où 1, 4, 6, 8 et 9 sont présents ne répondent pas au critère.
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Avatar de l’utilisateur
Lionel DebrouxSuper Modo
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 11.4%
 
Messages: 6875
Inscription: 23 Déc 2009, 00:00
Localisation: France
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: -
GitHub: debrouxl

Re: Aide pour un algo récursif

Message non lude Bisam » 20 Fév 2014, 22:06

J'étais sûr que tu répondrais, Lionel...

À vrai dire, même si gagner en rapidité est toujours bon à prendre, cet algorithme est déjà suffisamment performant à mon goût.
Il est certain qu'on pourrait élaguer pas mal (même si je n'ai pas bien compris ton idée) mais ce n'était pas vraiment le but de ma question.

Mais c'est déjà gentil de t'être penché sur la question...

Pour ceux qui voudraient tester, je fournis également le code de mon crible d'Érathostène, qui est utilisé au début du programme.
Show/Hide spoilerAfficher/Masquer le spoiler
Code: Tout sélectionner
def eratho(N):
    """Renvoie une liste de True ou False, indiquant si un entier entre 0 et N-1 est premier par le crible d'Érathosthène"""
    t = [i % 2 == 1 for i in range(N)] # on initialise tous les pairs à False
    t[1], t[2] = False, True
    r = int(N ** .5)
    i = 3
    while i <= r:
        if t[i]:
            for j in range(i ** 2, N, i):
                t[j] = False
        i += 2
    return(t)
Avatar de l’utilisateur
BisamAdmin
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Prochain niv.: 69.6%
 
Messages: 5670
Inscription: 11 Mar 2008, 00:00
Localisation: Lyon
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: Aide pour un algo récursif

Message non lude Excale » 23 Fév 2014, 15:57

Sur le principe de l'algo, je ne vois pas de problème. Dans le détail, j’espère que ça n'est pas un problème de Python qui fait que ça ne marche pas.

Code: Tout sélectionner
for i, newDigits in enumerate(primedigits[nextindex:]):

i commence bien à nextindex et finit à len(primedigits)?
(j'y connais rien en serpents)

Et puis j'ai rien compris à enumerate, mais c'est sans doute de ma faute ça :P.
Avatar de l’utilisateur
ExcaleAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Prochain niv.: 3.9%
 
Messages: 2955
Images: 3
Inscription: 10 Sep 2010, 00:00
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: Aide pour un algo récursif

Message non lude Bisam » 23 Fév 2014, 19:11

En fait, "enumerate" permet de nommer à la fois l'indice (ici "i") et l'élément de la liste (ici "newDigits") et le "primedigits[nextindex:]", c'est la liste "primedigits" mais commencée à l'indice "nextindex"...

Mais ça me fait penser qu'il y a bien un truc qui foire dans ce code !! En effet, "enumerate" compte à partir de 0, par défaut... et le fait que je modifie la liste n'y change rien ! Par conséquent, je ne renvoie pas le bon indice quand je fais ma récursion, puisque je renvoie l'indice à partir du rang "nextindex"... et non à partir du début.

Bon, j'aurais tendance à dire que, du coup, j'en fais plus que nécessaire, et non pas moins... mais peut-être bien que je fais des doublons.
En tout cas une erreur est une erreur, donc, je vais déjà corriger ça et après on verra !

Merci pour avoir involontairement relevé ce problème !
Avatar de l’utilisateur
BisamAdmin
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Prochain niv.: 69.6%
 
Messages: 5670
Inscription: 11 Mar 2008, 00:00
Localisation: Lyon
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: Aide pour un algo récursif

Message non lude Bisam » 23 Fév 2014, 19:54

Et YESS ! Merci Excale....
Avatar de l’utilisateur
BisamAdmin
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Prochain niv.: 69.6%
 
Messages: 5670
Inscription: 11 Mar 2008, 00:00
Localisation: Lyon
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: Aide pour un algo récursif

Message non lude Excale » 23 Fév 2014, 21:00

Bisam a écrit:Mais ça me fait penser qu'il y a bien un truc qui foire dans ce code !! En effet, "enumerate" compte à partir de 0, par défaut... et le fait que je modifie la liste n'y change rien ! Par conséquent, je ne renvoie pas le bon indice quand je fais ma récursion, puisque je renvoie l'indice à partir du rang "nextindex"... et non à partir du début.

Ben voilà pourquoi ça correspondait pas avec la doc et que je ne comprenais rien!

Bisam a écrit:Et YESS ! Merci Excale....

;)

Comme quoi, c'est parfois vicieux le Python. T'as plus qu'à donner ça à tes élèves en TD :D.
Avatar de l’utilisateur
ExcaleAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Prochain niv.: 3.9%
 
Messages: 2955
Images: 3
Inscription: 10 Sep 2010, 00:00
Genre: Homme
Calculatrice(s):
MyCalcs profile


Retourner vers Maths, physique, informatique et autre...

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 52 invités

-
Rechercher
-
Social TI-Planet
-
Sujets à la une
Ndless for CX 4.5.5 / CX II 6.2.0
Comparaisons des meilleurs prix pour acheter sa calculatrice !
"1 calculatrice pour tous", le programme solidaire de Texas Instruments. Reçois gratuitement et sans aucune obligation d'achat, 5 calculatrices couleur programmables en Python à donner aux élèves les plus nécessiteux de ton lycée. Tu peux recevoir au choix 5 TI-82 Advanced Edition Python ou bien 5 TI-83 Premium CE Edition Python.
Enseignant(e), reçois gratuitement 1 exemplaire de test de la TI-82 Advanced Edition Python. À demander d'ici le 31 décembre 2024.
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
12345
-
Faire un don / Premium
Pour plus de concours, de lots, de tests, nous aider à payer le serveur et les domaines...
Faire un don
Découvrez les avantages d'un compte donateur !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partenaires et pub
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
3517 utilisateurs:
>3497 invités
>12 membres
>8 robots
Record simultané (sur 6 mois):
32248 utilisateurs (le 01/09/2025)
-
Autres sites intéressants
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)