2010-09-27 32 views
7

Prima di tutto - Ho controllato molto in questo forum e non ho trovato qualcosa abbastanza veloce. Cerco di creare una funzione che restituisca i numeri primi in un intervallo specificato. Per esempio ho fatto questa funzione (in C#) usando il setaccio di Eratostene. Ho provato anche setaccio Atkin ma quella Eratostene corre più veloce (nel mio implementazione):Algoritmo veloce per trovare i numeri primi?

public static void SetPrimesSieve(int Range) 
    { 
     Primes = new List<uint>(); 
     Primes.Add(2); 
     int Half = (Range - 1) >> 1; 
     BitArray Nums = new BitArray(Half, false); 
     int Sqrt = (int)Math.Sqrt(Range); 
     for (int i = 3, j; i <= Sqrt;) 
     { 
      for (j = ((i * i) >> 1) - 1; j < Half; j += i) 
       Nums[j] = true; 
      do 
       i += 2; 
      while (i <= Sqrt && Nums[(i >> 1) - 1]); 
     } 
     for (int i = 0; i < Half; ++i) 
      if (!Nums[i]) 
       Primes.Add((uint)(i << 1) + 3); 
    } 

Si corre circa due volte più veloce di codici & algoritmi che ho trovato ... C'è dovrebbe essere un modo più veloce per trovare i numeri primi, potresti aiutarmi?

+1

In quale range stai cercando per i numeri primi? Solo tra 0 e max int? Inoltre, quanto è ampia la gamma? – Gleno

+0

diciamo qualcosa come miliardi/2 – Ohad

+6

Ci sono 50 minuti primi meno di 10^9, quindi precomputerli ti darebbe una tabella di 200MB. Sarebbe effettivamente più piccolo per memorizzare solo il setaccio (10^9 bit è di 125 MB, e non è necessario memorizzare i bit pari, in modo che si possa inserire tutto in meno di 64 MB). – Gabe

risposta

9

Durante la ricerca di algoritmi su questo argomento (per il progetto Eulero) non ricordo di aver trovato nulla più veloce. Se la velocità è davvero la preoccupazione, hai pensato di archiviare i numeri primi in modo tale che devi semplicemente cercarli?

MODIFICA: ricerca rapida su google trovata this, confermando che il metodo più veloce sarebbe solo per visualizzare i risultati e cercarli secondo le necessità.

Un'altra modifica: è possibile trovare ulteriori informazioni here, essenzialmente un duplicato di questo argomento. Il primo post afferma che il setaccio di atkin è stato più veloce di quanto non lo fosse al momento della generazione al volo.

+0

no, quelli non sono veloci, anche il mio codice è più veloce. Ho visto davvero qualcosa che dice che è molto veloce (in qualche caso non mi fido di niente ...) lo controllerò domani, devo andare. grazie comunque. (non è un duplicato dell'altro argomento, c'erano risposte lente) – Ohad

+0

Questo è un articolo fantastico, +1 –

+0

ci sono algoritmi molto molto più veloci di questo semplice, vedi la mia risposta –

0

Diversi commenti.

  1. Per la velocità, pre-calcolare quindi caricare dal disco. È super veloce. L'ho fatto in Java molto tempo fa.

  2. Non archiviare come array, archiviare come bitrdenza per numeri dispari. Più efficiente sulla memoria

  3. Se la tua domanda di velocità è che vuoi che questo particolare calcolo funzioni velocemente (devi giustificare il motivo per cui non puoi precomputerlo e caricarlo dal disco) devi codificare un setaccio migliore di Atkin. È più veloce Ma solo leggermente.

  4. Non è stato indicato l'utilizzo finale di questi numeri primi. Potremmo perdere qualcosa completamente perché non ci hai detto l'applicazione. Diteci uno schizzo dell'applicazione e le risposte saranno mirate meglio per il vostro contesto.

  5. Perché mai pensi che esista qualcosa di più veloce? Non hai giustificato la tua impressione. Questo è un problema molto difficile. (Che è quello di trovare qualcosa di più veloce)

+0

Test per un primo è così noioso, che io completamente d'accordo con jlv ... semplicemente archiviare e cercare. In effetti, dovrebbe esserci un servizio web globale gratuito che viene memorizzato nella cache a livello globale, che può fornire le risposte ... o meglio ancora, java dovrebbe memorizzare tutti i numeri primi a max int in una ricerca; nel mondo Docker dovrebbe esserci un'immagine con un'applicazione che fornisce una gamma di servizi sui primi, inclusa la ricerca. È semplicemente così noioso doverlo testare, e quindi cercare il metodo più performante in qualunque lingua si scelga. – Beezer

0

Si può fare di meglio con il Sieve of Atkin, ma è abbastanza difficile da implementare in fretta e correttamente. Una semplice traduzione dello pseudo-codice di Wikipedia probabilmente non è abbastanza buona.

+0

sì, ho provato a fare il setaccio di atkins ... il mio array conteneva anche numeri pari ma non li ho toccati ... era 1.5 volte più lento del setaccio degli eroathenes. (la maggior parte dei codici che ho trovato sono stati raddoppiati dal mio eroa). e, naturalmente, ho usato anche le proprietà dei primi e diciamo che so fare l'ottimizzazione ... ma è ancora più lento (ci sono byte non utilizzati nel mio array ... che non dovrebbero avere importanza). – Ohad

+0

Perché non mostrare questo codice pure? – Landei

+0

Un'implementazione C molto veloce da uno degli autori del documento che la descrive è su http://cr.yp.to/primegen.html – Olathe

2

L'algoritmo più veloce nella mia esperienza finora è il setaccio di Erathostenes con fattorizzazione della ruota per 2, 3 e 5, in cui i numeri primi tra i numeri rimanenti sono rappresentati come bit in una matrice di byte. In Java su un nucleo del mio computer portatile di 3 anni ci vogliono 23 secondi per calcolare i numeri primi fino a 1 miliardo.

Con la scomposiz- zazione delle ruote, il setaccio di Atkin era circa un fattore due più lento, mentre con un ordinario BitSet era circa il 30% più veloce.

Vedere anche this answer.

1

Ho fatto un algoritmo in grado di trovare numeri primi nell'intervallo 2-90.000.000 per 0.65 sec su I 350M-notebook, scritto in C .... devi usare operazioni bit a bit e avere "codice" per ricalcolare l'indice del tuo array per indicizzare il bit concreto che desideri. per esempio Se vuoi le pieghe del numero 2, i bit concreti saranno ad esempio .... 10101000 ... quindi se leggi da sinistra ... ottieni indice 4,6,8 ... questo è

Problemi correlati