Inscription / Connexion Nouveau Sujet

1 2 +


Niveau Prepa (autre)
Partager :

python

Posté par
nullptr19
16-12-20 à 17:45

Bonjour à toutes et à tous , j'ai un test à rentrer en machine (python) mais je rame un peu .
voici un algorithme proposé  et celui à implémenter :

.Soit n un entier impaire
. calculer (b,n)
       .si (b,n)>1 , alors n n'est pas premier et le test est terminé
        .sinon , calculer b^{\frac{n-1}{2} }\mod(n) \ et \ ( \frac{b}{n}) ( (b/n) : symbole de Jacobi)
                 * si ces deux élément ne sont pas égaux alors n n'est pas premier et le test s'arrête.
                   * sinon recommencer le test pour un autre b ,puis un autre entier b1...

voici ce que je propose mais j'ai pas fat la dernière question qui consiste à vérifier pour un autre b

voici:

from pgc import pgcd
from random import *
from jac import Jacobi
from exp import expon

def test(n):
     b=randint(2,n-1)
     pgcd(b,n)
     i=0
     while (n%2)==0:
         n//=2
         i+=1
     if pgcd(b,n)>1 :
         return "{} n'est pas premier ".format(n)

     else :
         a=expon(b,(n-1)/2,n)
         b=jacobi(b,n)
         
         if a!=b:

             return "{} n'est pas premier".format(n)


PS: les modules importés contiennent des fonction déjà programmées

Posté par
nullptr19
re : python 16-12-20 à 17:58

j'avais oublié un détail voici l'énoncé légèrement modifié.


Soit n un entier impaire
.choisir un nombre b avec 1<b<n
. calculer (b,n)
       .si (b,n)>1 , alors n n'est pas premier et le test est terminé
        .sinon , calculer b^{\frac{n-1}{2} }\mod(n) \ et \ ( \frac{b}{n})
( (b/n) : symbole de Jacobi)
                 * si ces deux élément ne sont pas égaux alors n n'est pas premier et le test s'arrête.
                   * sinon recommencer le test pour un autre b ,puis un autre entier b1...

voici ce que je propose mais j'ai pas fat la dernière question qui consiste à vérifier pour un autre b

Posté par
carpediem
re : python 16-12-20 à 18:09

salut

le pb avec l'instruction b = randint (2, n - 1) c'est que tu eux retomber sur le "même  b" que précédemment ...

je travaillerai plutôt avec la structure set (ensemble) ou liste dans laquelle je mettrai les entiers de 2 à n - 1 puis à chaque fois que j'en choisis un je l'enlève ... pour ne plus le choisir ...

ensuite je ne comprends pas ton script ....

def test(n):
     b=randint(2,n-1)
     pgcd(b,n)                 à quoi sert cette instruction : tu fais appel à une fonction ... pour rien en faire !!!
     i=0
     while (n%2)==0:     ici aussi je ne comprends rien de ce que tu fais : pourquoi diviser n par 2
         n//=2
         i+=1                  que fais-tu avec ce i ensuite ?
     if pgcd(b,n)>1 :                                ces deux lignes devraient
         return "{} n'est pas premier ".format(n)    être au tout début

     else :
         a=expon(b,(n-1)/2,n)
         b=jacobi(b,n)
         
         if a!=b:

             return "{} n'est pas premier".format(n)


donc totalement incompréhensible ...

Posté par
carpediem
re : python 16-12-20 à 18:18

en fait je traiterai simplement tous les entiers de 2 à n - 1 dans une boucle ...

Posté par
nullptr19
re : python 16-12-20 à 18:18

while (n%2)==0:
         n//=2
         i+=1
parceque n est donné impaire

Posté par
nullptr19
re : python 16-12-20 à 18:19

ok j'essaie de ton idée

Posté par
carpediem
re : python 16-12-20 à 18:44

je ne comprends pas !!!

tu veux tester si un entier impair est premier

donc tu rentre un entier n et il suffit de tester au si cet entier est pair ou impair tout simplement

j'écrirai simplement :

n = 0
while n%2 == 0 :
    n = int(input( "entrer un entier impair"))
...

Posté par
carpediem
re : python 16-12-20 à 18:44

et la structure set peut être effectivement intéressante pour choisir au hasard ...

Posté par
nullptr19
re : python 16-12-20 à 18:46

ah oui , ok je reviens vers toi

Posté par
perroquet
re : python 16-12-20 à 19:34

Bonjour à tous les deux.

@carpediem:
Je pense que l'algorithme qui est demandé à nullptr est un algorithme probabiliste de détection d'un nombre premier.

Lorsqu'il répond que le nombre n n'est pas premier, alors, n n'est pas premier, c'est certain. Par contre, lorsqu'il répond que n est premier, alors, il y a une probabilité non nulle que ce nombre ne soit pas premier (cette probabilité pouvant être très faible).

Cet algorithme est habituellement employé pour de très grands nombres (au moins plusieurs dizaines de chiffres dans l'écriture décimale). Il est donc impossible en python  de créer des ensembles dont le cardinal soit égal à n-2. Donc, l'instruction randint doit faire l'affaire . Il peut arriver que l'entier ait déjà été testé mais cela n'arrivera que rarement.

Posté par
nullptr19
re : python 16-12-20 à 19:48

merci perroquet , je m'en doutais en cours le prof m'avait dit que randint fait l'affaire ce pendant , le programme que j'ai proposé , qu'est ce que j'ai mal fait du coup histoire de rectifier et ranger un peu tout ça

Posté par
carpediem
re : python 16-12-20 à 20:00

perroquet : ha d'accord ...et merci

effectivement j'avais compris qu'on était certain d'une affirmation mais pas certain de sa négation

alors peut-être pour éviter la répétition du même choix de b ajouter les valeurs choisies dans une liste et comparer le "nouveau b" avec ceux de la liste ...

mais effectivement la probabilité de retomber sur le même b ... est de l'ordre de 1/n donc très faible pour de "très grand" nombre !!

Posté par
nullptr19
re : python 16-12-20 à 20:52

carpediem pour à chaque fois renvoyer sous forme de liste le résultat issue de randint , comment devrais je m'y prendre ? j'ai essaye avec une boucle for et effectuer des petit calcul à l'intérieur mais ça me renvoi que le premier nombre choisi c'est assez ennuyeux

Posté par
nullptr19
re : python 16-12-20 à 20:55

random.random()  fait l'affaire je crois

Posté par
carpediem
re : python 16-12-20 à 21:05

L = []
b = randint (2, n - 1)
while b in L :
   b = randint (2, n - 1)
L.append (b)
... suite du traitement

Posté par
nullptr19
re : python 16-12-20 à 21:22

def ref (n):
    L = []
    b = randint (2, n - 1)
    while b  in  L :
        b=randint (2, n - 1)
        L.append (b)
    return L
print (ref(20))


j'ai testé mais j'ai pas la liste de tout les élément tirés aléatoirement

Posté par
nullptr19
re : python 16-12-20 à 21:31

oupss c'est bon j'ai pu trouver une autre solution , je la met en pratique et je reviens vers vous

Posté par
carpediem
re : python 16-12-20 à 21:49

nullptr19 @ 16-12-2020 à 21:22

def ref (n):
    L = []
    b = randint (2, n - 1)
    while b  not in  L :
        b=randint (2, n - 1)
        L.append (b)
    return L
print (ref(20))


j'ai testé mais j'ai pas la liste de tout les élément tirés aléatoirement


et il ne faut pas créer une liste à priori mais au fur et à mesure car si un b convient on arrête : n n'est pas premier ...

Posté par
nullptr19
re : python 17-12-20 à 10:33

voici ce que je propose , mais le seul probleme est que ca ne me renvoit rien j'ai l'impression que la boucle tourne infiniment sans pour autant trouver un candisat

import random
def test(n):
    i=0
    liste=[]
    while (n%2)==0:
        n//=2
        i+=1
    for a in range (n):
            x=random.randint(2,n)
            liste.append(x)
    for b1 in liste:
        pgcd(b1,n)
        if pgcd(b1,n)>1 :
            return "{} n'est pas premier ".format(n)

        else :
         expon(b1,(n-1)//2,n)
         jacobi(b1,n)
         
         a=expon(b1,(n-1)//2,n)
         b=jacobi(b1,n)
         if a!=b:
             return "{} n'est pas premier".format(n)

        return "premier"


mais le seul problème est que ça ne me revoit rien j'ai l'impression que ma 2eme boucle for tourne infiniment sans pour autant trouver un candidat

Posté par
carpediem
re : python 17-12-20 à 12:16

à quoi sert le test : while n%2 == 0 ?

si n est pair on est certain que n n'est pas premier et on s'arrête immédiatement ...

et je ne comprends pas non plus à quoi sert la variable i ...

nullptr19 @ 17-12-2020 à 10:33

import random
def test(n):
    i=0
    liste=[]
    while (n%2)==0:
        n//=2
        i+=1
    for a in range (n):
            x=random.randint(2,n)
            liste.append(x)
    for b1 in liste:
        pgcd(b1,n)
        if pgcd(b1,n)>1 :
            return "{} n'est pas premier ".format(n)

        else :
         expon(b1,(n-1)//2,n)
         jacobi(b1,n)
         
         a=expon(b1,(n-1)//2,n)
         b=jacobi(b1,n)
         if a!=b:
             return "{} n'est pas premier".format(n)

        return "premier"

Posté par
nullptr19
re : python 17-12-20 à 12:26

OK mais en procédant au modification je ne trouve pas des résultats vrais

import random
def test(n):
    liste=[]
    for a in range (n):
        x=random.randint(2,n)
        liste.append(x)
    
    for b1 in liste:
        if pgcd(b1,n)>1 :
            return "{} n'est pas premier ".format(n)

        else :
         a=expon(b1,(n-1)//2,n)
         b=jacobi(b1,n)
         if a!=b:
             return "{} n'est pas premier".format(n)

    return "premier"

Posté par
nullptr19
re : python 17-12-20 à 12:46

carpediem @ 17-12-2020 à 12:16

à quoi sert le test : while n%2 == 0 ?

si n est pair on est certain que n n'est pas premier et on s'arrête immédiatement ...

et je ne comprends pas non plus à quoi sert la variable i ...

nullptr19 @ 17-12-2020 à 10:33

import random
def test(n):
    i=0
    liste=[]
    while (n%2)==0:
        n//=2
        i+=1
    for a in range (n):
            x=random.randint(2,n)
            liste.append(x)
    for b1 in liste:
        pgcd(b1,n)
        if pgcd(b1,n)>1 :
            return "{} n'est pas premier ".format(n)

        else :
         expon(b1,(n-1)//2,n)
         jacobi(b1,n)
         
         a=expon(b1,(n-1)//2,n)
         b=jacobi(b1,n)
         if a!=b:
             return "{} n'est pas premier".format(n)

        return "premier"


n est supposé impaire , qu'il soit premier ou non .

Posté par
carpediem
re : python 17-12-20 à 12:56

j'éliminerai dès le début le cas n pair et j'écrirai simplement :

import random
def test(n) :
  if n%2 == 0 :
     return "{} n'est pas premier ".format(n)
  liste = []
  for k in range (2, n - 1)
    b = random.randint (2, n - 1)
    while b in liste :
       b = random.randint (2, n - 1)
    liste.append(b)
    if pgcd(b1, n) > 1 :
      return "{} n'est pas premier ".format(n)
    else :
       if expon(b,(n - 1)//2, n) != jacobi(b1, n) :
           return "{} n'est pas premier".format(n)

  return "premier"

Posté par
nullptr19
re : python 17-12-20 à 13:40

Je comprend ce vous me proposez et je suis d'accord du moins de ne relevé aucune ambiguïté , sauf que ça compile pas toujours correctement

Posté par
nullptr19
re : python 17-12-20 à 13:57

J'ai du faire quelque rajustement : et avec ceci ça marche bien :

import random
def test(n) :
  if n%2 == 0 :
     return "{} n'est pas premier ".format(n)
  liste = []
  for k in range (2, n - 1):
    b = random.randint (2, n - 1)
    while b in liste :
       b = random.randint (2, n - 1)
       liste.append(b)
  for b1 in liste :
    if pgcd(b1, n) > 1 :
      return "{} n'est pas premier ".format(n)
    else :
       a=expon(b1,(n - 1)//2, n) 
       c=jacobi(b1, n)
       if a!= c :
           return "{} n'est pas premier".format(n)
  return "premier"

Posté par
nullptr19
re : python 17-12-20 à 14:04

il ne vérifie pas pour tout le monde

Posté par
carpediem
re : python 17-12-20 à 16:01

oui il y avait une erreur d'indentation ...

en fait il y a encore une "erreur" : ce devrait être : for k in range (2, n)

puisque n n'est pas pris en compte ... enfin à voir ...

je ne comprends pas ton dernier msg ni la boucle avec b1

ton nouveau b tu l'as !!! tu choisis b au hasard tant qu'il n'est pas déjà dans la liste (pour éviter une répétition inutile) et tu fais ton traitement avec ce nouveau b ...

mais en même temps tu fais éventuellement des tours et des tours dans cette boucle pour avoir un b que tu n'as pas déjà

on peut donc faire mieux et plus efficace si tu veux une liste complète dès le départ il y a beaucoup plus simple : il y a une fonction python qui mélange aléatoirement une liste

import random
def test(n) :
  if n%2 == 0 :
     return "{} n'est pas premier ".format(n)
  liste = [i for i in range (2, n)]
  random.schuffle(liste)
  for b in liste :
    if pgcd(b1, n) > 1 :
      return "{} n'est pas premier ".format(n)
    else :
       if expon(b,(n - 1)//2, n) != jacobi(b1, n) :
           return "{} n'est pas premier".format(n)

  return "premier"

Posté par
carpediem
re : python 17-12-20 à 16:19

on peut même encore simplifier :

import random
def test(n) :
  if n%2 == 0 :
     return "{} n'est pas premier ".format(n)
  liste = [i for i in range (2, n)]
  random.schuffle(liste)
  for b in liste :
    if pgcd(b, n) > 1 or  expon(b,(n - 1)//2, n) != jacobi(b1, n) :
           return "{} n'est pas premier".format(n)

  return "premier"

Posté par
nullptr19
re : python 17-12-20 à 17:23

même ceci j'essaie mais ça renvois des erreurs

Posté par
nullptr19
re : python 17-12-20 à 17:38

quand j'essaie avec 5 , tanto ça me renvois premier tanto pas premier

Posté par
carpediem
re : python 17-12-20 à 17:46

dans jacobi j'ai oublié de remplacé b1 par b :

import random
def test(n) :
  if n%2 == 0 :
     return "{} n'est pas premier ".format(n)
  liste = [i for i in range (2, n)]
  random.schuffle(liste)
*
  for b in liste :
    if pgcd(b, n) > 1 or  expon(b,(n - 1)//2, n) != jacobi(b, n) :
           return "{} n'est pas premier".format(n)

  return "premier"


là où j'ai mis une étoile * mets y un print(liste) pour voir ce que contient ta liste ...

Posté par
nullptr19
re : python 17-12-20 à 18:04

excuser moi je vous embête un peu trop mais étant donné que dans mes différents test il peut arriver par exemple que quand je test 5 ça m'affiche non premier et au bout de quelques tour j'obtiens le résultat , n'est ce pas même ça le sens de test de primalité  probabiliste ? et que des que j'ai un résultat vrai "premier" je conclut que le nombre est premier ?

Posté par
carpediem
re : python 17-12-20 à 20:11

ça n'est pas normal puisqu'on test tous les entiers entre 2 et n - 1

et le test pgcd(b, 5) > 1 est toujours faux  ... reste à voir ce que donne jacobi en théorie ...

Posté par
nullptr19
re : python 17-12-20 à 20:20

Moi non plus je ne comprend pas , j'ai l'impression que le test se fait à chaque fois que je compile

Posté par
nullptr19
re : python 17-12-20 à 20:24

et cela varie y'a certains b qui vérifie , d'autre pas du coup un temps pour 5 ça affiche premier et  quand je compile à nouveau le résultat change .

Posté par
carpediem
re : python 17-12-20 à 20:37

il serait bien d'avoir tes fonctions jacobi et expon ...

Posté par
nullptr19
re : python 17-12-20 à 20:41

sûrement du à la présence des faux témoins d'Euler ? J e sais pas mais les résultats me semble logiques à cause du mot probabiliste , pour un nombre premier il ya une certaine probabilité que à un certain tour  il soit premier , vous me direz si je raconte un peu n'importe quoi , mais j'essaie juste de traduire la manière selon laquelle mon cerveau traduit tout ça

Posté par
nullptr19
re : python 17-12-20 à 20:44

carpediem @ 17-12-2020 à 20:37

il serait bien d'avoir tes fonctions jacobi et expon ...


elles sont correcte et ont été corrigées en TP avec le prof à ce niveau il n'y a pas de problème , je les utilise régulièrement dans les travaux qui nécessitent leurs présences

Posté par
nullptr19
re : python 17-12-20 à 20:48

def jacobi(a, n):
    if n <= 0:   
        return False
    if n % 2 == 0:
        return False  
    a %= n  
    ValeurJacobi = 1
     
    
    while a != 0 and pgcd(a,n)!=0:  
        while a % 2 == 0:     
                             
            a //= 2        
            r= n % 8 
            if r in (3,5):  
                ValeurJacobi = -ValeurJacobi
            if r in (1,7):          
                ValeurJacobi        
        a, n = n, a  
        if (a % 4) == 3 and (n % 4) == 3:   
                                        
            ValeurJacobi = -ValeurJacobi
        a %= n
    if n == 1:                       
        return ValeurJacobi
    else:
        return 0     

Posté par
nullptr19
re : python 17-12-20 à 20:49

def expon (a,k,n): 
    compteur=1
    while(k>0):                     
        if k%2!=0:           
            compteur=(compteur*a)%n 
        a=(a*a)%n
        k=k//2                          
    return compteur 

Posté par
carpediem
re : python 17-12-20 à 21:23

rien à dire sur la fonction expon qui traduit l'exponentiation "rapide" : on élève au carré tant qu'on peut

j'utiliserai plutôt la notation p (pour puissance) que compteur qui n'en est pas un ...

pour la fonction jacobi la première partie se résume simplement en

def jacobi(a, n):
    if n <= 0 or n%2 == 0 :   
        return False
    a %= n  
    ValeurJacobi = 1


ensuite à nouveau je ne comprends ce qui est fait dans le test
Citation :
            if r in (1,7):          
                ValeurJacobi


par contre j'y pense peut-être qu'ily a un pb en regroupant les deux derniers en un seul avec un or ... à voir en essayant comme tu 'avais proposé au début ...

Posté par
nullptr19
re : python 17-12-20 à 21:33

En ce qui est de Jacobi , je n'ai fait qu'utiliser les propriétés :

pour a un nombre entier et  n entier  naturel positif impaire ,
(a/n)= 1 si n ≡ 1 ou 7 (mod 8), et -1 si n ≡ 3 ou 5 (mod 8)

Posté par
nullptr19
re : python 17-12-20 à 21:36

Du coup je comprend pas trop bien ce que vous me suggérez de faire :

voici du coup quelques modifs  apportées mais toujours rien de bien concret


from random import shuffle 
import random
def test(n) :
  if n%2 == 0 : 
      return "{} nest pas premier le test est inutil d'etre refait".format(n)
  liste = [i for i in range (2, n)] 
  random.shuffle(liste) 
  for b1 in liste : 
      if pgcd(b1, n) > 1:
          return "{} n'est pas premier , le test est terminé".format(n)
      else :
          expon(b1,(n-1)/2,n)
          jacobi(b1,n)
          if expon(b1,(n-1)/2,n)!=jacobi(b1,n):
              return "{} nest pas premier , le test est terminé".format(n)
      
      return "premier " 

Posté par
verdurin
re : python 17-12-20 à 21:47

nullptr19 @ 17-12-2020 à 21:33

En ce qui est de Jacobi , je n'ai fait qu'utiliser les propriétés :

pour a un nombre entier et  n entier  naturel positif impaire ,
(a/n)= 1 si n 1 ou 7 (mod 8), et -1 si n   3 ou 5 (mod 8)

Il me semble t'avoir signalé que cette propriété est fausse.

Par exemple \Bigl(\frac37\Bigr)=-1

Posté par
verdurin
re : python 17-12-20 à 22:21

En cherchant un peu, on trouve un algorithme de calcul du symbole de Jacobi sur le net.
Par exemple ici

Posté par
nullptr19
re : python 17-12-20 à 22:30

merci verdulin , en gros c'était mon programme sur Jacobi qui causait soucis dans le test primalité probabiliste ?

Posté par
carpediem
re : python 17-12-20 à 22:43

Citation :
      else :
          expon(b1,(n-1)/2,n)
          jacobi(b1,n)

          if expon(b1,(n-1)/2,n)!=jacobi(b1,n):
              return "{} nest pas premier , le test est terminé".format(n)
les deux premières instructions ne servent strictement à rien ... puisque tu n'en fais rien !!!

tu appelles deux fois la fonction pour rien !!!

donc
Citation :

          if expon(b1,(n-1)/2,n)!=jacobi(b1,n):
              return "{} nest pas premier , le test est terminé".format(n)
suffit

le if étant indenté comme le précédent !!

Posté par
verdurin
re : python 17-12-20 à 22:43

Je ne sais pas si c'était le seul soucis, mais il est certain que s'en était un.

Posté par
nullptr19
re : python 18-12-20 à 12:30

verdurin ,carpediem Bonjour à vous .

voici pour le symbole de Jacobi

def jacobi(a,n):
    ValeurJacobi=1
    while a!=0:
        while (a%2)==0:
            a//=2
            if (n%8==3 or n%8==5):
                ValeurJacobi=-ValeurJacobi
        a,n=n,a  
        if (a%4==3 and n%4==3):
            ValeurJacobi=-ValeurJacobi
        a=a%n
    if n==1:
        return ValeurJacobi
    else:
        return 0


j'ai ressayé le test mais la fonction a toujours le même comportement , pour les nombres premier ,tanto "n'est pas impaire" et au bout d'un nombre de compilation je tombe sur premier , je sais plus , mais pour les nombre impaire ca ne change pas , cela affiche juste "n'est pas impaire " à chaque fois , jamais paire

Posté par
verdurin
re : python 18-12-20 à 19:26

Bonsoir,
je crois voir où est le problème :
jacobi(2,5) retourne -1 et expon(2,(5-1)/2,5) retourne 4.
Ces deux valeurs sont évidement égales modulo 5 mais ne sont pas égales pour le programme.

Pour donner un avis plus général l'usage de random.shuffle me semble complètement inutile.
Un test aléatoire n'a d'intérêt que pour les grandes valeurs de n.
Si n est « petit » disons inférieur à 1010 il est certainement beaucoup plus rapide de tester la divisibilité par les valeurs inférieures à  \sqrt{n}.

Et faire le test jacobi(b,n)%n==expon(b,(n-1)//2,n) est beaucoup trop long.

1 2 +




Vous devez être membre accéder à ce service...

Pas encore inscrit ?

1 compte par personne, multi-compte interdit !

Ou identifiez-vous :


Rester sur la page

Inscription gratuite

Fiches en rapport

parmi 1674 fiches de maths

Désolé, votre version d'Internet Explorer est plus que périmée ! Merci de le mettre à jour ou de télécharger Firefox ou Google Chrome pour utiliser le site. Votre ordinateur vous remerciera !