π
<-

Aide pour un algo récursif

Discussions scientifiques et scolaires

Aide pour un algo récursif

Unread postby Bisam » 16 Feb 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: Select all
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.
User avatar
BisamAdmin
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 69.6%
 
Posts: 5670
Joined: 11 Mar 2008, 00:00
Location: Lyon
Gender: Male
Calculator(s):
MyCalcs profile

Re: Aide pour un algo récursif

Unread postby Lionel Debroux » 19 Feb 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.
User avatar
Lionel DebrouxSuper Modo
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Level up: 11.3%
 
Posts: 6865
Joined: 23 Dec 2009, 00:00
Location: France
Gender: Male
Calculator(s):
MyCalcs profile
Class: -
GitHub: debrouxl

Re: Aide pour un algo récursif

Unread postby Bisam » 20 Feb 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: Select all
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)
User avatar
BisamAdmin
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 69.6%
 
Posts: 5670
Joined: 11 Mar 2008, 00:00
Location: Lyon
Gender: Male
Calculator(s):
MyCalcs profile

Re: Aide pour un algo récursif

Unread postby Excale » 23 Feb 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: Select all
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.
User avatar
ExcaleAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 3.9%
 
Posts: 2955
Images: 3
Joined: 10 Sep 2010, 00:00
Gender: Male
Calculator(s):
MyCalcs profile

Re: Aide pour un algo récursif

Unread postby Bisam » 23 Feb 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 !
User avatar
BisamAdmin
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 69.6%
 
Posts: 5670
Joined: 11 Mar 2008, 00:00
Location: Lyon
Gender: Male
Calculator(s):
MyCalcs profile

Re: Aide pour un algo récursif

Unread postby Bisam » 23 Feb 2014, 19:54

Et YESS ! Merci Excale....
User avatar
BisamAdmin
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Level up: 69.6%
 
Posts: 5670
Joined: 11 Mar 2008, 00:00
Location: Lyon
Gender: Male
Calculator(s):
MyCalcs profile

Re: Aide pour un algo récursif

Unread postby Excale » 23 Feb 2014, 21:00

Bisam wrote: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 wrote:Et YESS ! Merci Excale....

;)

Comme quoi, c'est parfois vicieux le Python. T'as plus qu'à donner ça à tes élèves en TD :D.
User avatar
ExcaleAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 3.9%
 
Posts: 2955
Images: 3
Joined: 10 Sep 2010, 00:00
Gender: Male
Calculator(s):
MyCalcs profile


Return to Maths, physique, informatique et autre...

Who is online

Users browsing this forum: ClaudeBot [spider] and 10 guests

-
Search
-
Social TI-Planet
-
Featured topics
Grand Concours 2024-2025 - Programmation Python
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
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1174 utilisateurs:
>1125 invités
>43 membres
>6 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)