TiMad Le 18/04/2002 à 13:29 Bon puisque je fais un TIPE sur la recherche des nombres premiers, je me doit de chercher l'algo le plus pratique.
En pratique sur pc, on utilise il me semble le crible.
Or, si je veux appliquer ceci sur ti, je serai vite depassé en memoire!
C'est donc la raison pour laquelle j'ai commencer a chercher une formule, et j'ai trouver:
ISPRIME(k)=k-sum(E(k/p),pE|P(k))
ISPRIME = 1 si le nombre est premier, 0 sinon.
explication sur la formule:
E(k/p) est la parite entiere de k/p, ce qui est tres pratique pour les calcules sur pc (pas de float)
pE|P(k), est p, appartenant a l'ensemble |P(k) etant l'ensemble des nombres premiers inferieurs a k.
L'avantage, est que l'on ne stoque en memoire que les nombres premiers qui demande moins de plance que tous les nombres naturels. (il suffit de regarder l'etude de pi(x)...)
XLib v1.00 Powerrrrrrrrrrrrrrrrrrrr!
Je comprends que tu veuilles eviter l'utilisation d'un tableau, mais il permettrait un gain monumental
au niveau du temps de calcul non ? De toute façon, quelque soit la méthode que tu utiliseras, pour
determiner si un nombre n est premier, tu devras calculer dans tout les cas tout les nombres premiers
inferieurs à E(n/2) (en fait il s'agit de l'ensemble des nombres premiers inférieurs à la racine de n mais
comme tu l'as signalé, il est preferable en termes de performances d'éviter les opérations "exotiques")
et ça risque d'être (terriblement) gourmand en temps de calcul. Tu aurais donc tout interet à disposer
au minimum d'un tableau contenant les premiers nombres premiers tu gagnerais un temps fou sur les
nombres pas trop géants. Enfin bon, le sujet est vaste ... jete un coup d'oeil à ça si ça t'interesse (oui
c'est du pascal pour PC, mais que veux tu, moi aussi j'attends des compilo on-calc performant pour le
prototypage (à ce propos bon courage à tout les developpeurs de compilo on-calc (Thibault par exemple,
mais tout les autres aussi) ) ).
program n_primes;
uses Crt;
const MAX_SIZE = 8192;
type primes_array = array [1 .. MAX_SIZE] of LongInt;
primes_file = file of LongInt;
var primes : primes_array;
max_num : integer;
procedure init_results_array;
var i:integer;
begin
write('Initialising result''s array ...');
for i:=1 to max_num+1 do primes[i] := 0;
writeln(' done');
end;
function is_prime(n:longint):boolean;
var i:integer;
res : boolean;
begin
i:=1;
res := true;
while primes[i]<>0 do
begin
if n mod primes[i] = 0 then res := false;
i := i+1;
end;
is_prime:=res;
end;
procedure disp(var p : primes_array);
var i : integer;
begin
ClrScr;
for i:=1 to max_num do
begin
write(p[i]:8);
if i mod 8 = 0 then writeln;
if i mod 160 = 0 then
begin
writeln('Page ',i div 160,' on ',max_num div 160);
readln;
ClrScr;
end;
end;
readln;
ClrScr;
end;
procedure get_max_num;
begin
repeat
writeln('Please input a positiv number below ',MAX_SIZE,' :');
readln(max_num);
until (MAX_SIZE >= max_num) and (max_num >= 0);
end;
procedure calculate;
var i : integer;
n : LongInt;
begin
i := 1;
n := 2;
write('Start calculations ... you may go drink a(nother) coffee ...');
while i <= max_num do
begin
if is_prime(n) then
begin
primes[i] := n;
i := i + 1;
end;
n := n + 1;
end;
writeln(' done');
end;
procedure save(name:string);
var save_file : primes_file;
i : integer;
begin
assign(save_file,name);
rewrite(save_file);
write('Saving in file ',name,' ...');
for i:=1 to max_num do write(save_file,primes[i]);
writeln(' done');
close(save_file);
end;
procedure load(name:string);
var save_file : primes_file;
i : integer;
begin
i := 1;
assign(save_file,name);
reset(save_file);
write('Loading from file ',name,' ...');
while not eof(save_file) do
begin
read(save_file,primes[i]);
i := i + 1;
end;
max_num := i;
writeln(' done');
close(save_file);
end;
begin
ClrScr;
get_max_num;
init_results_array;
calculate;
disp(primes);
end.
TiMad Le 22/04/2002 à 12:15 zewoo: je pense que cela demande beaucoup trop de resource systeme... en effet, les divisiopn avec reste, c'est pas ce qu'il y a de mieux..
XLib v1.00 Powerrrrrrrrrrrrrrrrrrrr!
Les algo les plus rapide pour la recherche de nombres premiers sont les alogos probabilistes. Le plus connu est celui de Miller Rabin il te permet de déterminer très rapidement si un nombre est premier ou pas (mais pas d'en trouver le facteurs)
Idée d'un book d'algorithmique :
Utilisez des tableaux pour les listes chainées, et des indices de forme int plutôt que des pointeurs; ça gagne de la place, et c'est pas forcément plus lent (d'autant plus que le compilo C saura qu'il n'y a pas d'aliasing possible !)
Pour les allocations mémoires, il suffit de garder une liste des noeuds libres... c'est ce que j'utilise dans mon compilo COMA.
C'est pas une mauvaise idée mais dans ce cas je ne vois pas trop l'intéret d'une liste chainée. Pour ma part je les utilise pour avoir des tableaux dynamiques qui peuvant la moité de ces éléments puis dans la seconde en avoir 20 fois plus : un tableau dynamique quoi.
Avec ta technique il faudrait créer un tableau enorme qui se remplira et se desemplirai dynamiquement mais le probleme c'est que tu vas utiliser bcp de memoire pour rien....
Pour répondre à TiMad :
En ti68k tu peux faire des listes chainées mais de peu d'element c'est vrai, de meme tu peux faire des fonctions récursive mais elles ne doivent pas utiliser trop de mémoire ou bien faire peu de tour pour ne pas remplir la pile et avoir des erreurs a la con.
Ma technique permet juste d'utiliser tester tous les nombres entre deux bornes de maniere a savoir s'il ils sont 1ers ou pas en les divisants par uniquement par tous les nbr 1er inférieurs existant, il est donc en soit relativement efficace mais peut etre pas exploitable sur ti, je l'ai pas essayé.
Le fait est que je ne vois pas d'autre méthode réellemnt plus efficace puisque aucune eqution mathematique ne permet de dire si un nombre est 1er, tt du moins pour des grand nombres : le petit th de fermat marche pour peu de nombre je crois me souvenir.
"Le fait est que je ne vois pas d'autre méthode réellemnt plus efficace puisque aucune eqution mathematique ne permet de dire si un nombre est 1er, tt du moins pour des grand nombres "
Eh bien si, les algorithmes probabilistes!
regardez mon post plus haut (#12)!
pour répondre à Kevin Kofler, bien sur que je connais realloc, mais c'est vrai que je ne connais pas assez bien les compilateurs pour savoir si il est plus efficace de faire des realloc avec un tableau que de faire des listes chainée et je trouve les principe des listes chainées assez sympas pour faire des tableaux dynamiques genre la liste des tirs d'un gusgus dans un jeu ou autre (faut m'excuser).
pour repondre a The_beast, le fait est qu'il n'existe aucune formule qui permet de savoir si un nombre est premier ou pas, les algos probabilistes, je suppose, teste si un nombre est divisble par des nombres 1er plus ou moins probable, ou bien teste d'autre propriétées des nombres. S'il existe des equations qui decrivent les nbrs 1er alors je me demande pq des mathematiciens cherchent tjs les nbr 1er les plus gds?
ps : Kevin kofler pourrai tu m'eclairer sur l'utilité alors des listes chainées?
"il n'existe aucune formule qui permet de savoir si un nombre est premier ou pas"
->FAUX c'est précisement le role des algos probalistes
Un algorithme probabiliste te dis avec un certaine certitude (élevé donc tu est sur) si un nombre est premier ou pas. Ce que ne fait pas un tel algorithme c'est de donner les facteurs.
>> je me disais bien aussi que les listes chainées deviaent bien servir a qqchose. De tte maniere, mon algo n'etait pas optimisé pour les ti comme je l'ai dit dans mon 1er post, je l'avais fait pour PC. C clair que sur TI tt ce qui est recursif n'est pas aidé vu la taille de la pile.
>> pourrais tu me dire the_beast comment fonctionne un algo probabiliste? Parce qu'un algo comme le mien ne donne qu'un seul des facteurs ce qui permet d'etre sur qu'il n'est pas 1er puisqu'il a un factuer qui n'est ni un ni lui meme.
C'est la magie des algo probabilste, on sait si un nombre est premier ou pas sans en trouver un seul facteur. Il y en a deux types: ceux dont on est sur qu'un nombre est premier (et donc peut etre factorisable ceux-ci sont bcp plus longs), et ceux dont on est sure qu'un nombre est factorisable.
Voici l'exemple de l'algo de Miller-Rabin
(écrit par moi en basic)
function isprim(n)
d=3
for d=3 to 41 step 2
if n-INT(n/d)*d=0 then
"Non premier"
goto [fin]
end if
next d
r=(n-1)/2
e=1
j=0
for i= 1 to 5
a=INT(RND(1)*(n-4))+2
y=mod2(a,r,n)
if y<>1 and y<>n-1 then
j=1
while j<r and y<>n-1
y=mod(y*y,n)
if y=1 then
"Non premier"
goto [fin]
end if
j=j+1
if y<>n-1 then
"Non premier"
goto [fin]
end if
wend
end if
next i
"Surement premier"
[fin]
end function
mod(a,b) est le modulo (le reste de a par b)
mod2(a,b,c) est: modulo (a^b,c)
INT est la partie entière
Cet algo fonctionne tjs parfaitement avec des nombres de 231 chiffres
Ces algorithme font appel a des test (évidemment) et à des calculs de modulo (reste)
Merde, il manque plein de mots clés...
Quoique c'est juste de l'algo, faudrait peu etre rajouter un langage pur algo!
C'est du QBASIC, donc c'est normal qu'il n'y a pas tous les mots-clés quand on fait de la coloration TI-BASIC. Ceci dit, il en faudrait une pour le QBASIC...
Mon algo n'est pas en Qbasic mais ca y ressemble beaucoup.
La 89 inclus effectivement une fonction probabiliste pour savoir si un nombre premier: ISPRIME(n) ou ESTPREM(n)
Et pour factoriser un nombre FACTOR(n)
kim Le 11/05/2002 à 18:05 au faite #pub# si tu es interessé par les recherches approchées de nombres premiers y'a un pti passage sur mon tuto#pub#

Il n'a pas de mots
Décrire son mépris
Perdre les rênes
Il a perdu la foi