Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

CRIBLE D'ERATOSTHENE


Information sur la source

Description

Un petit programme de recherche des nombres premiers en utilisant la méthode d'Eratosthene.
Algorithme différent de celui posté la semaine dernière.
Celui de la semaine dernière cherchait les nombres premiers d'une façon classique : le nombre n'est pas premier s'il existe au moins un seul le precedant telle que le modulo est <> de zero.
Par contre pour celui là, pour chaque nombre (non eliminé donc premier), il faut éliminer  tous ses multiples (d'où le tableau utilisé).
 

Source

  • /**
  • * @author chabacha
  • *
  • */
  • class Eratosthene {
  • /*Recherche des nombres tels qu'ils ne sont divisibles
  • que par eux même (ou 1!)*/
  • public static void main (String args[]) {
  • int i,j,borne_sup=1100,nbr_int_premier=0;
  • boolean []tableau_premiers = new boolean [borne_sup-1];
  • for (i=0;i<=tableau_premiers.length-1;i++)
  • {
  • tableau_premiers[i]=true;
  • }
  • // le chiffre 2 est premier "par defaut", d'ailleurs, tous au debut.
  • for (i=2;i<=borne_sup;i++)
  • {
  • if (tableau_premiers[i-2]==true){ // bypass les nbres non 1ers
  • j=i+1;
  • while (j<=borne_sup)
  • {
  • if ((j%i)==0) tableau_premiers[j-2]=false;
  • j++;
  • }
  • nbr_int_premier++;
  • if (nbr_int_premier%13!=0) System.out.print(i+" ");
  • else System.out.println(i+" ");
  • }
  • }
  • /*for (i=0;i<=tableau_premiers.length-1;i++)
  • {
  • if (tableau_premiers[i]==true)
  • {
  • nbr_int_premier++;
  • if (nbr_int_premier%13!=0) System.out.print(i+2+" ");
  • else System.out.println(i+2+" ");
  • }
  • }*/
  • System.out.println("");
  • System.out.println("Nomre de nbr premiers : "+nbr_int_premier+" entre "+2+" et "+borne_sup);
  • }
  • }
/**
 * @author chabacha
 *
 */

class Eratosthene {
	/*Recherche des nombres tels qu'ils ne sont divisibles
	que par eux même (ou 1!)*/
	public static void main (String args[]) {
	    int i,j,borne_sup=1100,nbr_int_premier=0;
	    boolean []tableau_premiers = new boolean [borne_sup-1];
	    
	    for (i=0;i<=tableau_premiers.length-1;i++) 
	    {
	        tableau_premiers[i]=true;
	    }
	    // le chiffre 2 est premier "par defaut", d'ailleurs, tous au debut.
	    for (i=2;i<=borne_sup;i++) 
	    {
	    	if (tableau_premiers[i-2]==true){ // bypass les nbres non 1ers
		        j=i+1;
		        while (j<=borne_sup) 
	 	        {
			        if ((j%i)==0) tableau_premiers[j-2]=false;
			        j++;
		        }
		        nbr_int_premier++;
		   	    if (nbr_int_premier%13!=0) System.out.print(i+" ");
		   	    	else System.out.println(i+" ");
	    	}
	    }
		/*for (i=0;i<=tableau_premiers.length-1;i++) 
		{
		    if (tableau_premiers[i]==true)
		    {
		 	    nbr_int_premier++;
		   	    if (nbr_int_premier%13!=0) System.out.print(i+2+" ");
		   	    	else System.out.println(i+2+" ");
		    }
		}*/
	    System.out.println("");
	    System.out.println("Nomre de nbr premiers : "+nbr_int_premier+" entre "+2+" et "+borne_sup);
	}
}

Conclusion

Devinez quel est le traitement le plus long ?
voilà la prochaine foi je posterai une animation (SWT, lib GC) d'un tableau de cent cases.

 

Commentaires et avis

signaler à un administrateur
Commentaire de yvkoe le 10/10/2007 16:58:05

Bonjour,
très classe ,c'est important, la technique est primordiale mais après il faut sortir des chantiers battus.
Et là c'est le cas
Bravo!

signaler à un administrateur
Commentaire de yvkoe le 12/10/2007 11:40:37 10/10

ma note désolé j'avais oublié .
Je trouve que tes codes sont originaux et que tu creuses plus avant même quand le premier code posté est satisfaisant(cf Nbres premiers)
Une question: tu bosses pour le moment...?

signaler à un administrateur
Commentaire de ltb69 le 16/10/2007 12:49:22

Trois petites remarques :
- Tu déclare la variable du compteur (i) en début de méthode. Il est plus clair de la mettre directement dans le for => en plus çà évite les effets de bord si tu veux réutiliser la variable
- Tu fais des tas de calcul, pour ne utiliser le tableau dans sa totalité (les "-2" qui trainent) => pourquoi ne pas plutôt perdre les deux premières cases (0 et 1). le code serait plus clair.
- Tu utilise -1 dans les conditions d'arrêt des for ( par ex i<=tableau_premiers.length-1). Par habitude, j'utilise plutôt : i<tableau_premiers.length. La condition d'arrêt est calculée à chaque boucle.


L'inconvénient de ta méthodes est qu'elle est de complexité n² => Pour tous les chiffres, tu reparcours tout les chiffres suivant (même si tu ne fais pas d'action) ==> somme ==> n²/2
Il vaudrait mieux du code en complexite n (lineaire) du style :
    for (i = 2; i <= borne_sup; i++)
    {
      if (tableau_premiers[i])
      { // bypass les nbres non 1ers
        mult = 2;
        toto = i * mult;
        while (toto <= borne_sup)
        {
          tableau_premiers[(int) toto] = false;
          mult++;
          toto = i * mult;
        }
      }
    }

Pour info, on obtient un temps équivalent (8-9s), pour les nombres entre 2 à 10000, pour 50 appels à ta méthode ou 15000 appels de l'autre version.

Quant à lequel de tes deux algo est le plus rapide ... je dirais qu'ils se valent en performance pur, si ce n'est qu'ici tu fait l'impasse sur pas mal de calcul. Tu passes, en gros, de 10000² à 1229² (soit de 100000000 à 1510441 soit un gros facteur 60). En améliorant la complexité, tu as en plus un facteur 300.
Comme me disais un prof : Il vaut mieux améliorer la complexité de l'algo plutôt que l'algo lui même.

signaler à un administrateur
Commentaire de LeFauve42 le 17/10/2007 11:21:29 7/10

Salut,

Le crible est une bonne methode si tu veux obtenir rapidement tous les nombres premiers de 1 a n.
Cependant, il est possible de l'optimiser de plusieurs manieres.

La plus importante (et la plus simple) est de virer tous les nombres pairs de ton tableau.
En clair, tu commences a 1, et pour les nombres i que tu trouves, le nombre premier correspondant est (2*i)+1.
Ca te permet entre autre d'utiliser un tableau de booleens deux fois plus petits pour obtenir les memes resultats.

Sinon tu remarqueras si tu fais un peu de bench que les premieres iterations sont les plus longues.
De plus, ton tableau contient toujours une "pattern" qui se repete jusqu'a la fin.
Cette "pattern" est tres courte au debut, donc, tu peux preremplir ton tableau avec la pattern des 6 ou 7 premieres iterations par exemple, ce qui devrait diviser encore par 4 ou 5 le temps de calcul total.

Eric

signaler à un administrateur
Commentaire de chabacha le 19/10/2007 15:23:19

Bah !
Bonjour à tous

merci Yvkoe pour la note et merci ltb69 et LEFAUVE42 pour les remarques.
C vrai, mais si on veut aller plus loin dans notre optimisation ... il suffit de combiner plusieurs théorèmes.
Par exemple, le plus facile et immediat, serait d'appliquer le théoreme (conséquence du théoreme de Bertrand) suivant :
un nombre naturel n qui n'est divisible par aucun nombre premier p <= racine(n) est automatiquement lui-même premier.
Il est inutile, donc, de prolonger les recherches au-delà de racine de n. Il suffit d'atteindre le dernier nbre premier (p) telque p<=racine(borne superieure choisie) pour sortir de la boucle ...(ça tombe bien : par defaut le tableau est à true, donc à la sortie selon cette condition on aura nos nbres premiers jusqu'à la borne_sup).
exemple : borne_sup =100 donc il suffit de terminer le crible au nombre 7 !
Sauf que l'affichage devra se faire en dehors de la boucle ...
voici le code modifié :
class Eratosthene {
/*Recherche des nombres tels qu'ils ne sont divisibles
que par eux même (ou 1!)*/
public static void main (String args[]) {
    int i,j,borne_sup=35100,nbr_int_premier=0;
    boolean []tableau_premiers = new boolean [borne_sup-1];
    
    for (i=0;i<=tableau_premiers.length-1;i++)
    {
        tableau_premiers[i]=true;
    }
    // le chiffre 2 est premier "par defaut", d'ailleurs, tous au debut.
    for (i=2;i*i<=borne_sup;i++) // i<=racine(borne_sup)
    {
     if (tableau_premiers[i-2]==true){ // bypass les nbres non 1ers
        j=i+1;
        while (j<=borne_sup)
        {
        if ((j%i)==0) tableau_premiers[j-2]=false;
        j++;
        }
       // nbr_int_premier++;
      // if (nbr_int_premier%13!=0) System.out.print(i+" ");
      // else System.out.println(i+" ");
     }
    }
for (i=0;i<=tableau_premiers.length-1;i++)
{
    if (tableau_premiers[i]==true)
    {
    nbr_int_premier++;
       if (nbr_int_premier%13!=0) System.out.print(i+2+" ");
        else System.out.println(i+2+" ");
    }
}
    System.out.println("");
    System.out.println("Nomre de nbr premiers : "+nbr_int_premier+" entre "+2+" et "+borne_sup);
}
}

signaler à un administrateur
Commentaire de LeFauve42 le 22/10/2007 13:06:39

En fait, tout depends de ce que tu veux faire:
- Trouver les n premiers nombres premiers ou
- Savoir si un nombre est premier.

Dans l'absolu, ce genre d'algo n'est pas tres utile a part pour se faire la main ou se taper la bourre entre potes (genre "celui qui va calculer le plus vite les nombres premiers < 1000000" :o) ).

Sinon, si tu as vraiment besoin de savoir rapidement si des nombres sont premiers, tu peux preconstruire une liste en memoire pour quelques centaines de kilo et chercher dedans par dicotomie (ou bien carrement un gros tableau de booleens :o) ). C'est moins cool, mais beaucoup plus efficace...

Eric

Ajouter un commentaire

Discussions en rapport avec ce code source dans le forum

Nombres amis - (en Java) [ par HEVs ] Bonjour,Je recherche un algorithme qui donne les nombres amis (ou amicaux).Si vous avez encore les exercicres de vos études... alors merci!David---Ave Les nombres négatifs et le complément à 2 [ par Tara ] Bonjour à tous,Je désire lire un fichier au format binaire dans lequel chaque bit a une signification précise et donc son importance. A la lecture du changement de base pour la representation des nombres [ par fox66 ] bonjour,je suis debutant, je dois effectué un prog en java d'un outil pedagogique pour comprendre les pbs de changement de base pour la representation probleme nombres d'un tableau [ par Skyffer3 ] Salut a tous ! Voila quand je fais un tableau, par exemple :x = new int[3];for (i = 0; i &lt; 3; i++){int[i] = 0;}La boucle for remplit donc le table SteamTokenizer - lire les nombres dans un fichier [ par guns17 ] bonjour, voila le code (le plus important): type == StreamTokenizer.TT_NUMBER; String mot = Integer.toString(type); System.out.println(mot); dans débutante en java [ par hananetsdi ] <TD id=HB_Focus_Element vAlign=top width="100%" background="" height=250 UNSELECTAB Premiers pas ... [ par Akamaru88 ] Bonjour &#224; tous, Jusqu'&#224; pr&#233;sent je programmais uniquement en Basic sur ma calculatrice (Ti-89 titanium),&nbsp;je me d&#233;brouillais&n la factorisation d'un entier par le crible algébrique [ par infcrypt ] samicomment je peut factoriser un entier en un produit de 2 nombres premiers en utilisantla methode (le crible alg&#233;brique)..je souhaite un algori nombres aléatoires entiers ? [ par s_lannois ] Bonjour,Je voudrais créer un petit programme qui calculerait la somme des nombres pairs compris entre deux nombres aléatoires compris entre 0 et 100. Lecture fichier java - texte + nombres [ par Roxxx ] Bonjour,je dois créer un programme java dont une partie consiste à lire un fichier.txt qui contient des informations à récupérer de divers types: Stri


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Comparez les prix Nouvelle version


HTC G1

Entre 449€ et 449€


Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,421 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.