|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Jun 2008
Messaggi: 40
|
[c++ / calcolo numeri primi] - Mi salta il numero 1 !
Ciao a tutti,
ho risolto un esercizio nel quale veniva chiesto di restituire in output tutti i numeri primi da 1 a 100.000. Per calcolare se un numero è primo ho creato la funzione prime. Nella prima versione ho filtrato l'elaborazione nella funzione prime escludendo a priori tutti i numeri che modulo 2 restituivano 0. Nella seconda versione ho filtrato l'elaborazione nella funzione prime escludendo (grazie all'aiuto di Ziosilvio!) tutti i numeri la cui radice quadrata fosse intera. Per ottimizzare le prestazioni ho creato una versione 3 del programma che nella funzione prime, prima di procedere all'elaborazione, esclude sia tutti i numeri che nodulo 2 restituiscono 0 sia la cui radice quadrata sia intera. Prima versione: 58 secondi Seconda versione: 1' e 31 secondi Terza version: 40 secondi L'ottimizzazione delle prestazioni c'è stata ma il mistero è che la versione 3 non mi mostra il numero 1 come primo ![]() La cosa strana è che il numero 1 è proprio il primo argomento passato alla funzione prime che, tra l'altro, lo tratta esplicitamente. Nelle altre 2 versioni il numero 1 viene outputtato. Codice:
// Esercizio 630.cpp : definisce il punto di ingresso dell'applicazione console. // #include "stdafx.h" #include <iostream> using std::cin; using std::cout; using std::endl; #include <cmath> using std::sqrt; int _tmain(int argc, _TCHAR* argv[]) { return 0; } bool prime(int); int main() { int counter = 0; for (int number = 1; number <= 100000; number++) { if (prime(number) == 1) { cout << "Il numero " << number << " e' un numero primo" << endl; counter++; } } cout << counter; return 0; } bool prime(int number) { int a = 0; double number2 = number; int b = (int)sqrt(number2); if (number == 1) return number != number; else if (number == 2) return number == number; else if (number % 2 == 0) return number != number; else if (b == number * number) return number != number; else { for (int counter = number - 1; counter > 1; counter--) { if (number % counter == 0) a = 1; } if (a == 1) return number != number; else return number == number; } } Unslee Ultima modifica di unslee : 18-07-2008 alle 18:07. |
![]() |
![]() |
![]() |
#2 |
Member
Iscritto dal: Jun 2008
Messaggi: 40
|
Problema risolto ....
un riavvio del pc e il mistero del numero 1 si è risolto! Unslee |
![]() |
![]() |
![]() |
#3 |
Moderatore
Iscritto dal: Nov 2003
Messaggi: 16211
|
Il numero 1 non è considerato un numero primo.
In caso contrario, l'enunciato del teorema fondamentale dell'aritmetica "ogni intero positivo si riscrive in un modo e uno solo come prodotto di potenze di primi" non sarebbe vero (perché si può moltiplicare per 1 tutte le volte che si vuole) e bisognerebbe usarne uno più complicato. EDIT: oltretutto, il numero 1 si può comunque ottenere come prodotto vuoto di potenze di primi.
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" ![]() Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu Ultima modifica di Ziosilvio : 20-07-2008 alle 13:25. |
![]() |
![]() |
![]() |
#4 |
Member
Iscritto dal: Jun 2008
Messaggi: 40
|
Non si finisce mai di imparare... grazie per la spiegazione. Ho risistemato il programma perché era stato tarato sulla mia ignoranza in materia! Ora gira correttamente.
: ![]() Ultima modifica di unslee : 18-07-2008 alle 18:08. |
![]() |
![]() |
![]() |
#5 |
Member
Iscritto dal: Jun 2008
Messaggi: 40
|
Trovandoci a parlare dei numeri primi, avrei bisogno di aiuto per capire il testo dell'esercizio (del libro dei fratelli Deitel che sto studiando e non di un corso) che recita così:
Un numero intero si dice primo se è divisibile soltanto per se stesso. a) Scrivere una funzione che determina se il suo parametro è un numero primo b) Utilizzare questa fuzione per scrivere un programma che determina e visualizza i numeri primi compresi tra 1 e 100.000. Quandi numeri avete bisogno di provare realmente prima di trovare tutti i numeri primi di questo intervallo? c) Inizialmente penserete che non serve andare oltre n/2 per verificare se n è un numero primo, ma in realtà potete anche fermarvi alla sua radice quadrata. Perché? Riscrivere il programma ed eseguire le due versioni. Che miglioramento avete ottenuto sulle prestazioni? Mi mette in crisi la c. Ho pensato di filtrare inizialmente i numeri escludendo quelli il cui modulo 2 restituiva 0 (divisibili per due) e mi trovo allineato. Quando si fa riferimento alla radice quadrata di n l'unica cosa che mi è venuta in mente è che un numero che abbia una radice quadrata intera non sia un numero primo. Il fatto è che se filtro per la seconda condizione (radice quadrata non intera) che ho pensato il programma degrada in termini di prestazioni rispetto alla prima soluzione (esclusione dei numeri divisibili per due). Nel testo dell'esercizio mi sembra chiaro che le prestazioni debbano aumentare e quindi credo di non aver capito esattamente cosa stia cercando di dirmi il libro nel punto c). Grazie sempre per l'aiuto, Unslee |
![]() |
![]() |
![]() |
#6 | ||||
Moderatore
Iscritto dal: Nov 2003
Messaggi: 16211
|
Quote:
Un numero intero maggiore di 1 si dice primo se è divisibile soltanto per 1 e per se stesso. Equivalentemente: un numero p intero maggiore di 1 si dice primo se le uniche soluzioni intere positive dell'equazione p=x*y sono x=1, y=p ed x=p,y=1. Quote:
(A parte il fatto che l'algoritmo ingenuo opera in tempo superpolinomiale nella lunghezza dell'input.) Quote:
![]() ![]() ![]() ![]() ![]() ![]() Ma chi è il redattore, Luca Giurato? ![]() Quote:
Pensa a cosa succederebbe se un numero composto avesse solo fattori primi maggiori della propria radice quadrata... Il libro dovrebbe voler dire che, se fai un confronto tra il tempo che ci mette la versione che prova i divisori fino a n/2 e quella che prova i divisori fino a sqrt(n), noti che la seconda è molto più veloce. Il problema è che fare delle misurazioni affidabili non è banale, e non so se a questo punto dei tuoi studi conosci già le funzioni di libreria per il computo del tempo...
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" ![]() Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu |
||||
![]() |
![]() |
![]() |
#7 |
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Ma il punto "b" vorrebbe essere uno spunto per arrivare da soli al crivello di eratostene? Perchè se è cosi mi sembra un pò "vago"...
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
![]() |
![]() |
![]() |
#8 |
Member
Iscritto dal: Jun 2008
Messaggi: 40
|
Ciao Ziosilvio,
peccato per la lontananza altrimenti di chiederei di farmi lezioni di matematica perché sei un asso! Allora, relativamente alla definizione, quello da decapitare sono io: mi sono sbagliato ed ho mancato un pezzo nella trascrizione! Anche "quandi" è una mia creazione ... ... chiedo venia e dovrò cercare di essere più attento. Nel merito del problema sei riuscito a farmi capire (ardua impresa!) esattamente la richiesta del libro. Effettivamente ho fatto girare il programma in entrambi i modi e, anche usando un semplice cronometro (tenendo a bada il più possibile i vari tasks), la differenza di prestazioni è molto visibile. Questo per me è incomprensibile: "A parte il fatto che l'algoritmo ingenuo opera in tempo superpolinomiale nella lunghezza dell'input" Se pensi che per me capire quest'ultima cosa sia utile magari puoi darmi qualche indicazione così mi metto a studiare. Grazie ancora per l'aiuto, Unslee |
![]() |
![]() |
![]() |
#9 | |
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Quote:
Se li devi testare nel range 1:100000 non so se arrivi in fondo in tempo utile...(no forse fino a 100000 si...ma ad 1 milione credo proprio di no).
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
|
![]() |
![]() |
![]() |
#10 | ||
Moderatore
Iscritto dal: Nov 2003
Messaggi: 16211
|
Quote:
Il caso peggiore, è che n sia primo oppure il quadrato di un primo, e sia necessario fare tutte le prove. Se conti il numero T(n) delle operazioni che devi fare nel caso peggiore, e tieni a mente che una stringa binaria che rappresenta il numero n è lunga L=log{2}(n), scopri che per ogni potenza k-esima e per ogni costante C ti ritrovi un valore N(C,k) tale che T(n) >= C*L^k per ogni n > N(C,k) Si tratta di una branca dell'informatica teorica nota come teoria della complessità. Puoi vedere qualcosa già su Wikipedia, o sul testo di Cormen, Leiserson e Rivest (se la tua biblioteca ce l'ha). Quote:
__________________
Ubuntu è un'antica parola africana che significa "non so configurare Debian" ![]() Scienza e tecnica: Matematica - Fisica - Chimica - Informatica - Software scientifico - Consulti medici REGOLAMENTO DarthMaul = Asus FX505 Ryzen 7 3700U 8GB GeForce GTX 1650 Win10 + Ubuntu |
||
![]() |
![]() |
![]() |
#11 | |
Senior Member
Iscritto dal: Jul 2005
Città: Bologna
Messaggi: 1130
|
Quote:
Io mi riferivo al più semplice crivello di eratostene, dato che deve trovare i numeri primi in un range...
__________________
-> The Motherfucking Manifesto For Programming, Motherfuckers |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 00:03.