Ricerca numeri primi
effettivamente dati $ ~n $ numeri $ ~a_i $ esistono infiniti polinomi di grado $ ~n $ che passano per i punti $ ~(k,a_k) $
un po' dura scegliere il successivo.
Una sequenza casuale e' quella ottenuta basandosi su processi fisici noti per essere casuali, come fenomeni quantistici & similia (v. generatore hardware di numeri casuali)
un po' dura scegliere il successivo.
Una sequenza casuale e' quella ottenuta basandosi su processi fisici noti per essere casuali, come fenomeni quantistici & similia (v. generatore hardware di numeri casuali)
impara il [tex]~\LaTeX[/tex] e mettilo da par[tex]\TeX~[/tex]
Software is like sex: it's better when it's free (Linus T.)
membro: Club Nostalgici
Non essere egoista, dona anche tu! http://fpv.hacknight.org/a8.php
Software is like sex: it's better when it's free (Linus T.)
membro: Club Nostalgici
Non essere egoista, dona anche tu! http://fpv.hacknight.org/a8.php
Una definizione di sequenza casuale è quella di Kolmogorov: fissato un linguaggio di programmazione di riferimento, si dice casuale una sequenza che non può essere generata da un programma più corto della sequenza stessa.
Se la adottiamo allora curiosamente (questo è relativo...) i primi da 1 a N, per N abbastanza grande, non sono una sequenza casuale, perchè sappiamo scrivere una procedura di lunghezza C + log N, dove C è costante dipendente solo dal linguaggio e log N è la lunghezza del contatore, che genera i primi da 1 a N, ed essendoci circa N/logN primi nella sequenza questa diverrà inevitabilmente più lunga del programma al crescere di N.
Se la adottiamo allora curiosamente (questo è relativo...) i primi da 1 a N, per N abbastanza grande, non sono una sequenza casuale, perchè sappiamo scrivere una procedura di lunghezza C + log N, dove C è costante dipendente solo dal linguaggio e log N è la lunghezza del contatore, che genera i primi da 1 a N, ed essendoci circa N/logN primi nella sequenza questa diverrà inevitabilmente più lunga del programma al crescere di N.
Per trovare tutti i primi da 1 ad n basta applicare il crivello di eratostene (sempre che non si abbiano particolari esigenze computazionali).
Una veloce (e senza alcuna pretesa) implementazione in matlab è:
In C è la stessa cosa (si usa l'operatore %), la traduzione è davvero molto vicina (ma non ho idea di quale sia il linguaggio richiesto quindi me la risparmio
).
Una veloce (e senza alcuna pretesa) implementazione in matlab è:
Codice: Seleziona tutto
n = input('inserisci il numero di partenza ');
L = [0, 2 : n];
for i = 2 : sqrt(n)
for j = 1 : n-i
if ( mod(L(1,i+j), i) == 0 )
L(1,i+j)=0;
end
end
end
for i=1:n
if L(1,i) ~= 0
disp(L(1,i));
end
end

-
- Messaggi: 112
- Iscritto il: 28 feb 2005, 00:27
- Località: Livorno
allora, partecipo alla discussione dato che è un problema che styo' riaffrontando in questi giorni...avevo un buon programma ma ho perso il codice, adesso ne sto riscrivendo uno e cercando di renderlo efficace.
Il primo metodo che mi è venuto in mente è stato spiegato subito, chè creare un array e infilarci i primi uno dietro l'altro, e per trovare altri primi usare i primi a nostra disposizione nell'array. Ottimizzazioni aggiunte: controlla fino a sert(x) e salta i numeri pari.
Tuttavia usando un array normale in C non sono riuscito ad andare oltre 150000 numeri primi (se creo array più grossi crasha). Allora ho fatto una cosa così:
Questa funziona tranquillamente fino a p<100000000 sul mio pc (credo dipenda dalla ram, per calcolarne i primi <100000000 ne cosumanva 700MB). Da questo ho dedotto che un programma così è fortemente limitato....certo, con i primi <100000000 potrei calcolarli fino a 100000000^2 ma ci ha messo quasi 20 minuti a farne 100000000).
Pensavo allora di usare il crivello di eratostene. Andrea M. ha sviluppato questo programma allora:
A lui su linux va molto veloce, ma a me su windows va estremamente lento (più dell'altro, per esempio per calcolare i primi <3000000 il mio ci mette sui 5 secondi, il suo (sul mio pc) 80 secondi, sul suo pc 2 secondi. Ancora non abbiamo capito perchè. A qualcuno viene in mente un metodo più veloce (non solo a livello di algoritmo matematico, ma anche si programma in C)?
Il primo metodo che mi è venuto in mente è stato spiegato subito, chè creare un array e infilarci i primi uno dietro l'altro, e per trovare altri primi usare i primi a nostra disposizione nell'array. Ottimizzazioni aggiunte: controlla fino a sert(x) e salta i numeri pari.
Tuttavia usando un array normale in C non sono riuscito ad andare oltre 150000 numeri primi (se creo array più grossi crasha). Allora ho fatto una cosa così:
Codice: Seleziona tutto
#include "numerip.h"
#include <stdio>
#include <vector>
#include <malloc>
#include <algorithm>
using namespace std;
vector<unsigned> numerip;
vector<unsigned>::iterator it;
void main()
{
unsigned long long int i=1, n, j, r;
// struct elemento *lista = NULL;
bool primo;
// unsigned long int numerip[250000]={2, 3};
printf("Inserisci l'estremo superiore dell'intervallo\n");
scanf("%llu", &n);
numerip.resize(n);
numerip[0]=2;
numerip[1]=3;
j=5;
/* dichiara lo stream e il prototipo della funzione fopen */
FILE * stream;
/* apre lo stream del file */
stream = fopen("primi.txt", "w");
/* controlla se il file viene aperto */
if ((stream = fopen("primi.txt", "w")) == NULL)
{
printf("Non posso aprire il file %sn", "primi.txt");
}
fprintf(stream, "%llu, ", numerip[0]);
fprintf(stream, "%llu, ", numerip[1]);
while (j<n>=numerip[h]*numerip[h]) {
r=j%numerip[h];
if(r==0) {
primo=false;
break;
}
h++;
}
if(primo==true) {
i++;
numerip[i]=j;
fprintf(stream, "%llu, ", numerip[i]);
}
j=j+2;
}
printf("Ho trovato %d numeri\n", i);
}
Pensavo allora di usare il crivello di eratostene. Andrea M. ha sviluppato questo programma allora:
Codice: Seleziona tutto
#include <stdio>
#include <vector>
#include <algorithm>
using namespace std;
unsigned long long int N;
vector<bool> V;
vector<bool>::iterator it;
int
main()
{
FILE *fw;
fw=fopen("output.txt","w");
if(fw==NULL){printf("ERROR while opening output.txt\n");return 1;}
printf("Inserisci N\n");
scanf("%llu",&N);
V.resize(N);//settati tutti a 0: 0 se è primo 1 se no
for(unsigned long long int i=2;i<N;i++)
{
if(!V[i])
for(unsigned long long int j=2 ;i*j<N;j++)
V[i*j]=true;
}
//STAMPA
for(unsigned long long int i=2;i<N;i++)
if(!V[i])fprintf(fw,"%llu ",i);
return 0;
}
Migliorato
Gli ho dato una buona ottimizzazione, che ne pensate?
N = 1000000000 Sul mio computer l'ho portato a 1 secondo di uso cpu
Meglio di così cosa c'è?
N = 1000000000 Sul mio computer l'ho portato a 1 secondo di uso cpu
Meglio di così cosa c'è?
Codice: Seleziona tutto
#include "stdafx.h"
int main(){
__w64 unsigned int t, i, j;
bool* V = new bool[1000000000];
V[0] = V[1] = false;
for(j=4; j<1000000000; j+=2)
V[j] = false;
for(i=3; i<1000000000; i+=2)
if(V[i])
for(j=i*i, t=2*i; j<1000000000; j+=t)
V[j] = false;
//FILE *fw = fopen("output.txt", "w");
//fprintf(fw, "%i\n", 2);
//for(i=3; i<1000000000; i+=2)
// if(V[i])
// fprintf(fw,"%i\n",i);
return 0;
}
La ditta consiglia:
Codice: Seleziona tutto
#define N 1000000000
--federico
[tex]\frac1{\sqrt2}\bigl(\left|\text{loves me}\right\rangle+\left|\text{loves me not}\right\rangle\bigr)[/tex]
[tex]\frac1{\sqrt2}\bigl(\left|\text{loves me}\right\rangle+\left|\text{loves me not}\right\rangle\bigr)[/tex]
L'array è dinamico perché è troppo grosso 1000000000 bool tengono circa un giga di ram, troppo per essere dichiarato normalmente.
Non mi funziona, non ho la più vaga idea del perchè.
Potrei naturalmente inserire una nuova variabile N = 1000000000, ma l'algoritmo sarebbe più lento.
Codice: Seleziona tutto
#define N 1000000000
Potrei naturalmente inserire una nuova variabile N = 1000000000, ma l'algoritmo sarebbe più lento.
Re: Migliorato
si puo' cercare di eliminare i pari, ricordando che il primo pari e' ovviamente primo
in modo che V mi dia indicazioni su $ ~2i+1 $
(soprattutto dato che tu gia' stampi il 2 come primo a priori del valore in V[2])
in modo che V mi dia indicazioni su $ ~2i+1 $
(soprattutto dato che tu gia' stampi il 2 come primo a priori del valore in V[2])
Codice: Seleziona tutto
#include "stdafx.h"
int main(){
__w64 unsigned int t, i, j;
bool* V = new bool[1000000000];
V[0] = false;
for(i=1; i<1000000000; i++)
if(V[i])
for(j=i*(i+1)<<1, t=2*i+1; j<1000000000; V[j+=t] = false);
//FILE *fw = fopen("output.txt", "w");
//fprintf(fw, "%i\n", 2);
//for(i=1; i<1000000000; i++)
// if(V[i])
// fprintf(fw,"%i\n",2*i+1);
return 0;
}
impara il [tex]~\LaTeX[/tex] e mettilo da par[tex]\TeX~[/tex]
Software is like sex: it's better when it's free (Linus T.)
membro: Club Nostalgici
Non essere egoista, dona anche tu! http://fpv.hacknight.org/a8.php
Software is like sex: it's better when it's free (Linus T.)
membro: Club Nostalgici
Non essere egoista, dona anche tu! http://fpv.hacknight.org/a8.php
Nuova versione
@SkZ: Ci stavo già pensando ieri, ed oggi l'ho fatto:
Ora i pari vengono saltati e V da indicazioni su 2i +1 esattamente come diceva SkZ:
Tempo sul mio computer(ottimizzato tutto) 44-45 secondi.
Mi è venuta un'idea per aumentare ancora la capacità, provo a metterla in pratica
Ora i pari vengono saltati e V da indicazioni su 2i +1 esattamente come diceva SkZ:
Codice: Seleziona tutto
#include "stdafx.h"
#include <iostream>
#include <math>
using namespace std;
int main(){
#define MAX 2000000000
__w64 unsigned int t, i, j,
HALFMAX = (MAX+1)/2,
RADMAX = (int)sqrt((long double)MAX)+1,
HALFRADMAX = (RADMAX+1)/2;
bool* V = new bool[HALFMAX];
V[0] = false;
for(i=1; i<HALFMAX; i++)
V[i] = true;
for(i=1; i<HALFRADMAX; i++)
if(V[i])
for(j= i*(t=2*i+2), t--; j<HALFMAX; j+=t)
V[j] = false;
//FILE *fw;
//fopen_s(&fw, "output.txt", "w");
//fprintf(fw, "%i\n", 2);
//for(i=1; i<HALFMAX; i++)
// if(V[i])
// fprintf(fw,"%i\n",2*i+1);
cout << 2 << endl;
for(i=j=1; i<HALFMAX; i++){
if(!V[i])
continue;
cout << 2*i+1;
if(++j%20)
cout << endl;
else{
char pause[2];
cin.getline(pause, 1);
}
}
cout << ">- Finito -<" << endl;
char pause[2];
cin.getline(pause, 1);
return 0;
}
Mi è venuta un'idea per aumentare ancora la capacità, provo a metterla in pratica
Lascio perdere
Lascio perdere.
Se qualcuno ha voglia di provarci...
In questo modo si ottiene un risparmio di memoria dell'87,5%
Ma mi sono perso.
Buona notte.
Se qualcuno ha voglia di provarci...
Codice: Seleziona tutto
union bools{
public:
unsigned char byte;
struct bits{
public:
unsigned char _0:1, _1:1, _2:1, _3:1, _4:1, _5:1, _6:1, _7:1;
} bit;
};
//Permette di accedere ai singoli bit.
bools V;
V.byte = 0XFF; // reset
V.bit._3 = 0;
Ma mi sono perso.
Buona notte.
Provamykelyk ha scritto:Non mi funziona, non ho la più vaga idea del perchè.Codice: Seleziona tutto
#define N 1000000000
Potrei naturalmente inserire una nuova variabile N = 1000000000, ma l'algoritmo sarebbe più lento.
Codice: Seleziona tutto
const int N = 1000000000;
Why would anybody want empathy?
l'effetto e' diverso:
col define la sostituzione viene fatto dal preprocessore, quindi al momento della compilazione, mentre definendo la variabile la sostituzione viene al momento dell'esecuzione con accesso alla memoria
hai controllato che il tuo sistema non usi gia' 1bit per i bool?
col define la sostituzione viene fatto dal preprocessore, quindi al momento della compilazione, mentre definendo la variabile la sostituzione viene al momento dell'esecuzione con accesso alla memoria
hai controllato che il tuo sistema non usi gia' 1bit per i bool?
impara il [tex]~\LaTeX[/tex] e mettilo da par[tex]\TeX~[/tex]
Software is like sex: it's better when it's free (Linus T.)
membro: Club Nostalgici
Non essere egoista, dona anche tu! http://fpv.hacknight.org/a8.php
Software is like sex: it's better when it's free (Linus T.)
membro: Club Nostalgici
Non essere egoista, dona anche tu! http://fpv.hacknight.org/a8.php
Ti riferisci al const N = ... ?SkZ ha scritto:l'effetto e' diverso:
col define la sostituzione viene fatto dal preprocessore, quindi al momento della compilazione, mentre definendo la variabile la sostituzione viene al momento dell'esecuzione con accesso alla memoria
hai controllato che il tuo sistema non usi gia' 1bit per i bool?
Mi sa che e' la stessa cosa di define..
Why would anybody want empathy?