[Algorytmy] Znajdowanie liczb pierwszych

Leszek9238
Użytkownik
Użytkownik
Posty: 5
Rejestracja: 15 gru 2011, o 21:46
Płeć: Mężczyzna
Lokalizacja: Miasto

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: Leszek9238 »

Witajcie
Od pewnego czasu zastanawiam się jak można przyśpieszyć wyszukiwanie którejś tam z kolei liczby pierwszej przez program pisany w języku C++
Kiedyś trochę się wziąłem i napisałem mały algorytm, który podawał liczbę pierwszą (np. 10 000 z kolei).
Obecnie znalazłem początkowy projekt tej realizacji napisany w Devc++. W miarę optymalizacji program sprawdza każdą nieparzystą liczbę i dzieli ją przez poprzednie znalezione liczby pierwsze. Niestety nie wiem jak jeszcze zwiększyć wydajność tego programu. Poprosiłbym o pomoc. A program wygląda tak:

Kod: Zaznacz cały

#include <cstdlib>
#include <iostream>
#include <cstdio>

using namespace std;

int main(int argc, char *argv[])
{
    int t[100000];
    int a=11,i=0,c=3,b,d;
    t[0]=3;
    t[1]=5;
    t[2]=7;
    cout<<"Podaj ktora z kolei liczba pierwsza ma byc wyswietlona"<<endl<<endl;
    cin>>b;
    do
    {                                     
           if(a%t[i]==0)
           {
                        a=a+2;
                        i=-1;
           }
           i=i+1;
           if(i==c)
           {
                   t[i]=a;
                   if((c+1)==(b-1))
                   {
                   cout<<char()<<endl;            
                   cout<<t[i]<<endl<<endl;
                   }
                   a=a+2;
                   c=c+1;
                   d=c;
                   i=0;
           }
           if(d>10000)
           {
                      
           }
    }
    while(d<b);
    cout<<"Wykonano dla portalu Matematyka.pl"<<endl<<"Przez Leszek9238"<<endl;
    system("PAUSE");
    return EXIT_SUCCESS;
}
Ostatnio zmieniony 16 gru 2011, o 19:05 przez Afish, łącznie zmieniany 1 raz.
Powód: Staraj się lepiej dobierać nazwy tematów, tak by wskazywały o czym jest treść zadania. Tagi code!
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: Afish »

Sito Eratostenesa. Polecam googlowanie, jest mnóstwo metod szybkiego wyszukiwania liczb pierwszych, nie ma co odkrywać koła na nowo.
Xitami

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: Xitami »

oj, wszystkie koła już zostały odkryte (poza nieodkrytymi)
a gimnastyka jest zdrowa (choć bezpośrednio nie wpływa na PKB)
szczyptę lżejsze rozwiązanie, szczyptę tylko bo liczby małe

Kod: Zaznacz cały

#include <iostream>
#include <ctime>
using namespace std;

int main() {
	int
		t[100000]={2, 3, 5}, n= 3,
		ktora, nowa = 7,
		i, krok=4,
		czas;
	cin >> ktora;
	czas= clock();
	while( ktora > n ) {
		for( i=2; i<n; i++ )  
			if( nowa % t[i] == 0 )
				break;
		if( i == n )
			t[n++]= nowa;
		nowa += krok; krok= 6 - krok; }
	czas= clock() - czas;
	cout << t[n-1] << '\n' << czas/1000 << '.' << czas%1000/100;
	return 0; }
adambak
Użytkownik
Użytkownik
Posty: 1272
Rejestracja: 8 sty 2011, o 18:18
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 295 razy
Pomógł: 115 razy

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: adambak »

fakt dużo jest metod i temat często spotykany, jednak ja wciąż uważam go za ciekawy
ostatnio widziałem zadanie w którym trzeba było podać \(\displaystyle{ n}\)-tą liczbę pierwszą dla \(\displaystyle{ n \le 5\cdot 10^7}\) i google nie pomogło.. sito nie da rady, będzie wymagało ogromnej ilości pamięci, poza tym jeszcze czas na przypisanie indeksów tym liczbom pierwszym po wykonaniu sita (tzn może i to jeszcze do przeżycia.. \(\displaystyle{ 5\cdot 10^7}\)-ta liczba pierwsza to \(\displaystyle{ 982451653}\)), także ja bym temat jeszcze pociągnął, bo ciekawy..
Xitami

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: Xitami »



-- 17 grudnia 2011, 12:08 --
5e7 to mała liczba, a zwykłym Eratostenesem ją
można by troszkę optymalizować, ale tak jak jest solidny komputer załatwi w jakieś 20 sekund
na pytania można odpowiadać "bisekcyjnie"

Kod: Zaznacz cały

#define N  982451653
unsigned char t[N/16+1];

int primes[50000000];

void clr(int n){
	t[n/16] &=      ~(1 << ( n % 16 / 2 ) ); }

int test(int n){
	return t[n/16] & (1 << ( n % 16 / 2 ) ); }

int main(){
	int i, j;
	printf("sito %d
", sizeof(t));
	for( i=0; i<=N/16; i++ ) t[i]=255;
	for( i=3; i*i <= N; i+=2 )
		if( test( i ) )
			for( j = i*i; j <= N; j += 2*i )
				clr( j );
	for( j=i=0; i < N/2 + 1; i++ )
		if( test( i*2 + 1 ) )
			primes[ j++ ] = 2*i + 1;
	printf("%d", primes[ j-1 ]);
	return 0;
}
-----dopisek---------------------------------------
dość łatwo można by w jednym bajcie sita zmieścić nie 16, a 30 liczb
adambak
Użytkownik
Użytkownik
Posty: 1272
Rejestracja: 8 sty 2011, o 18:18
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 295 razy
Pomógł: 115 razy

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: adambak »

całkiem fajnie działa ale na to zadanie o którym myslałem jeszcze za wolno.. chociaż, chyba właśnie w sito trzeba iść, bo liczby jak mówisz nie są jeszcze takie tragiczne.. ale nie rozumiem jeszcze jak to działa.. funkcje test i clr to zagadka, a trik z pamiętaniem w jednym bajcie 16 liczb to już w ogóle.. ja chciałem zrobić właśnie przedział \(\displaystyle{ N/16}\) i na każdym z nich walnąć sito, ale teraz boję się pomyśleć jak to by wolno działało.. także jakbyś miał chwilkę czasu na wytłumaczenie...
Xitami

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: Xitami »

w skrócie: sito tutaj to bitowa tablica tylko dla nieparzystych indeksów

piszesz, że zbyt wolne. Uuu to ciekawe, jakie były wymagania?
abc666

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: abc666 »

Xitami, pewnie chodzi o to zadanie
Przy tych zabawach na bitach tworzenie sita trwa jeszcze dłużej.
adambak
Użytkownik
Użytkownik
Posty: 1272
Rejestracja: 8 sty 2011, o 18:18
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 295 razy
Pomógł: 115 razy

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: adambak »

tak, o to zadanie chodzi.. niby 30s a i tak ciężko, dużo już próbowałem..
Xitami

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: Xitami »

10'000 liczb nie problem (odpowiedź bisekcją)
limit 30 sekund, mój skromny Atom 1.6 GHz potrzebował 49, porównywałem z Ideone, jest około 2.5 raza szybsze.
Awatar użytkownika
Zordon
Użytkownik
Użytkownik
Posty: 4977
Rejestracja: 12 lut 2008, o 21:42
Płeć: Mężczyzna
Lokalizacja: Kraków
Podziękował: 75 razy
Pomógł: 910 razy

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: Zordon »

To zadanie jest daremne i bezsensowne, trzeba mnostwo niskopoziomowych optymalizacji zeby to weszlo, nie na tym polega algorytmika. W każdym razie odradzam, żeby się tym zajmować, strata czasu.
adambak
Użytkownik
Użytkownik
Posty: 1272
Rejestracja: 8 sty 2011, o 18:18
Płeć: Mężczyzna
Lokalizacja: Warszawa
Podziękował: 295 razy
Pomógł: 115 razy

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: adambak »

ok, dzięki Zordon bo myślałem, że jest to na jakiś istotny algorytm i koniecznie chciałem go poznać od dosyć dawna, męczyło mnie to już jakiś czas.. ale jeśli to kolejne kiepskie zadanie to wolę się zabrać za coś innego.. w takim razie pewnie te dwa:


są również na brudne triki, szkoda..
Awatar użytkownika
Zordon
Użytkownik
Użytkownik
Posty: 4977
Rejestracja: 12 lut 2008, o 21:42
Płeć: Mężczyzna
Lokalizacja: Kraków
Podziękował: 75 razy
Pomógł: 910 razy

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: Zordon »

Generalnie oszczędza się tam w ten sposób: sito najwięcej czasu spędza nad liczbami 2,3,5,7,11, no więc wyrzućmy z sita wszystkie liczby \(\displaystyle{ x}\), t. ze \(\displaystyle{ x\mod (2*3*5*7*11)}\) jest podzielne przez którąś z nich, oraz zacznijmy procedurę od 13, teraz sito nam maleje kilkukrotnie i w dodatku przyspiesza. Kolejna sztuczka to to, że np. vector<bool> zajmuje 8 razy mniej pamięci niż tablica bool o tej samej pojemności
Xitami

[Algorytmy] Znajdowanie liczb pierwszych

Post autor: Xitami »

to że trzeba podłubać to fajne, strasznie nie fajnym jest, że trzeba babrać się z we/wy
a maszynki spojowe też jakieś słabiutkie, ale za to mamy tyle pięknych krzyży

-- 17 grudnia 2011, 22:30 --

szerzej opisana o której wspomniał Zordon
ODPOWIEDZ