Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Algoritmi - Test di primalità più veloce
Forum - Algoritmi - Test di primalità più veloce

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
lorelapo (Ex-Member)
Expert


Messaggi: 355
Iscritto: 28/02/2007

Segnala al moderatore
Postato alle 11:46
Sabato, 19/05/2007
Un test di primalità serve a definire se un numero diverso da uno è primo cioè divisibile solo per se stesso e per uno. Un primitivo codice potrebbe essere :

Codice sorgente - presumibilmente Algoritmi

  1. primo(n)
  2. m=1,div=0;
  3. while(m<=n)
  4. {
  5. if(n%m==0)div++;
  6. m++;
  7. }
  8. if(div==2)return true;
  9. else return false;
  10. end primo



Una semplice ottimizzazione verrebbe in mente a chiunque, cioè che nessun numero puo essere divisibile per un numero maggiore della sua metà per cui
Codice sorgente - presumibilmente Algoritmi

  1. m=1,div=0;
  2. while(m<=n/2)
  3. {
  4. if(n%m==0)div++;
  5. m++;
  6. }
  7. if(div==1)return true;
  8. else return false;
  9. end primo



Ma siccome io l'altro ieri non avevo niente di meglio da fare io scritto questo

Codice sorgente - presumibilmente Algoritmi

  1. primo(n)
  2. if(n<=3)return true;
  3. m=2;
  4. while(m<=(n\m))
  5. {
  6. if(n%m==0)return false;
  7. m++;
  8. }
  9. return true



Che non solo si ferma se trova un numero per cui n è divisibile, ma via via restringe la quantità di numeri controllati diminuendo le iterazioni, perchè se n non è disibile per 2 non sarà divisibile neanche per la sua metà e così per tutti gli altri numeri e questo rende molto più veloce l'algoritmo. Inoltre con una piccola modifica si può rendere il procedimento utile per la fattorizzazione semplicemente ritornando n se il numero è primo o m se n è divisibile per m.

Codice sorgente - presumibilmente Algoritmi

  1. primo(n)
  2. if(n<=3)return n;
  3. m=2;
  4. while(m<=(n\m))
  5. {
  6. if(n%m==0)return m;
  7. m++;
  8. }
  9. return n;


PM Quote
Avatar
P4p3r0g4 (Member)
Guru


Messaggi: 1319
Iscritto: 29/12/2006

Segnala al moderatore
Postato alle 17:37
Sabato, 19/05/2007
più che la metà direi la radice quadrata.
se non trovi numeri che dividono il numero prima della sua radice quadrata il numero è primo.

Ultima modifica effettuata da P4p3r0g4 il 19/05/2007 alle 17:39
PM Quote
Avatar
lorelapo (Ex-Member)
Expert


Messaggi: 355
Iscritto: 28/02/2007

Segnala al moderatore
Postato alle 17:43
Sabato, 19/05/2007
Apparte il fatto che l'ultimo algoritmo interrompe eccome il ciclo, viavia restringe il tutto per cui anche se non è divisibile per 3i numeri possibili diventeranno un 1/3 del numero originale se non è divisibile per 5 allora saranno 1/5 e la radice quadrata sarebbe la migliore se il calcolo fosse più veloce 8-| e la divisione già di per sé è lenta per cui . . .

ps: la radice quadrata o la radice cubica o la radice n sarebbero tutte possibili perchè se non è divisibile per due non lo è neanche per 4 8 16 32 e tutti multipli di 2 e allora si torna al crivello di Eratostene, cioè per sapere + velocemente se un numero è primo dovresti saperlo anche di tutti i numeri minori di lui !!!

Ultima modifica effettuata da lorelapo il 19/05/2007 alle 17:47
PM Quote
Avatar
P4p3r0g4 (Member)
Guru


Messaggi: 1319
Iscritto: 29/12/2006

Segnala al moderatore
Postato alle 22:50
Sabato, 19/05/2007
sul ciclo scusa avevo visto dopo ho appunto editato.
con la radice intendevo che la condizione che un numero non sia primo necessita di almeno due numeri che lo dividono uno oltre e uno prima ( o coincidenti ) della sua radice quadrata. se non ne hai trovato uno prima della sua radice quadrata non è possibile che ne sia uno dopo perchè non potrebbe più avere la corrispondenza prima.
era un modo x eliminare casi superflui.

PM Quote
Avatar
lorelapo (Ex-Member)
Expert


Messaggi: 355
Iscritto: 28/02/2007

Segnala al moderatore
Postato alle 15:47
Lunedì, 04/06/2007
Si ma già di suo non può superare la radice quadrata osserva bene il ciclo.

PM Quote
Avatar
P4p3r0g4 (Member)
Guru


Messaggi: 1319
Iscritto: 29/12/2006

Segnala al moderatore
Postato alle 17:15
Domenica, 10/06/2007
Testo quotato

Postato originariamente da lorelapo
Codice sorgente - presumibilmente Algoritmi

  1. primo(n)
  2. if(n<=3)return n;
  3. m=2;
  4. while(m<=(n\m))
  5. {
  6. if(n%m==0)return m;
  7. m++;
  8. }
  9. return n;



scusami avevo letto
while(n<=(n\m)) 'appunto mi sembrava strano un controllo del genere.
scusa ancora il codice è una bomba.

PM Quote
Avatar
Black Shadow (Founder Member)
Expert


Messaggi: 323
Iscritto: 30/03/2006

Segnala al moderatore
Postato alle 12:07
Martedì, 12/06/2007
Testo quotato

Postato originariamente da lorelapo
Codice sorgente - presumibilmente Algoritmi

  1. primo(n)
  2. if(n<=3)return true;
  3. m=2;
  4. while(m<=(n\m))
  5. {
  6. if(n%m==0) return false;
  7. m++;
  8. }
  9. return true;




Io direi che si possa semplificare ulteriormente il codice in:

Codice sorgente - presumibilmente Algoritmi

  1. primo(n)
  2. if(n<=3)return true;
  3. m=1;
  4. while(++m<=(n\m))
  5.    if(!n%m) return false;
  6. return true



;)

Ultima modifica effettuata da Black Shadow il 12/06/2007 alle 12:09
PM Quote
Avatar
lorelapo (Ex-Member)
Expert


Messaggi: 355
Iscritto: 28/02/2007

Segnala al moderatore
Postato alle 15:09
Martedì, 12/06/2007
È ovvio che non ci volesse tanto a semplificare il codice, il potenziamento è però la cosa più importante dell'algoritmo sopra, Black Shadow la tua versione più sintetica ed ugualmente veloce (come l'ho scritta io in C) ma qui cercavo solo di rendere più comprensibile il codice, cmq grazie per aver postato.

PM Quote
Avatar
albertking82 (Member)
Pro


Messaggi: 112
Iscritto: 14/08/2006

Segnala al moderatore
Postato alle 11:10
Lunedì, 16/07/2007
Hai fatto un buon lavoro!!:k:

PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo