1. sayfa
| Asal sayı bulurken brute force kullanmak artık eskide kaldı. Asal sayı bulmaya yardımcı olan daha guzel algoritmalar var onları denersen bi sıkıntı olacagını sanmıyorum. |
| Ilginiz icin tesekkur ederim ama yazdigim koddaki sikinti tam olarak nerede bakabilir misiniz? |
|
Merhaba, 10000. asal sayi sanirim 104729. Bu sayiyi bulmak icin main fonksiyonundaki while dongun 104729 kere donuyor ve controllingPrimeNumber fonksiyonunu cagiriyor. Bu fonksiyon ise kendisine verilen parametre kadar donuyor. Toplamda 104729! kadar islem yapiyorsun yani. Bu sayi o kadar buyuk ki hayatin boyunca calissa bu kod sonucu bulamayabilirsin. :) Sadece siyah ekran cikmasinin sebebi bu. Bazi iyilestirmeler yapman gerekiyor kodunda ya da yukarda dendigi gibi hizli calisan algoritmalar aramalisin. |
|
Asal Sayı Test Fonskiyonunuzu Aşağıdaki Mantıkla Çalışır Hale Getirirseniz, Uygulamanızın Hızlandığını Göreceksiniz. Kendim Test Ettim (İşlem Süreleri Aşağıda) 10001. Asal Sayı = 1.81 saniye 20000. Asal Sayı = 7.54 saniye 30000. Asal Sayı = 18.79 saniye 40000. Asal Sayı = 36.21 saniye 50000. Asal Sayı = 57.83 saniye
Şu an için değil, ama ileride kendinizi geliştirdiğinizde, lütfen aynı uygulamayı farklı threadler kullanarak yapmayı deneyin. örneğin eş zamanlı olarak 2-3 thread çalıştırıp iş yükünü bölün, harcanan sürenin %30 gibi bir oranda azaldığını göreceksiniz :) Yazmış olduğunuz kodtaki sıkıntı Siz hangi sayı olursa olsun, tüm sayıları kalansız bölüyor mu diye kontrol ediyorsunuz, halbuki 1 - n arasındaki herhangi bir sayı n'i kalansız olarak bölüyorsa, o an evet bu asal değil diye işleme devam etmelisiniz, bunun yerine siz, en sona kadar gidiyorsunuz. örneğin : 3 - 10 arasındaki sayıların testini yapacak olursak (sizin programın mantığı) 3 -> 3 kere döner 4 -> 4 kere döner 5 -> 5 kere döner 6 -> 6 kere döner 7 -> 7 kere döner 8 -> 8 kere döner 9 -> 9 kere döner 10 -> 10 kere döner toplam = 52 kez aynı işlem tekrar edilir. (benim verdiğim örnekteki mantık) 3 -> 1 kere döner 4 -> 1 kere döner 5 -> 3 kere döner 6 -> 1 kere döner 7 -> 5 kere döner 8 -> 1 kere döner 9 -> 2 kere döner 10 -> 1 kere döner toplam = 14 kez aynı işlem tekrar edilir. eğer sayıları büyütecek olursak farkı anlarsınız 10000 - 10005 arasındaki sayıların testi : (sizin programın mantığı) 10000 -> 10000 kere döner 10001 -> 10001 kere döner 10002 -> 10002 kere döner 10003 -> 10003 kere döner 10004 -> 10004 kere döner 10005 -> 10005 kere döner toplam = 60015 kere aynı işlem tekrar edilir (benim verdiğim örnekteki mantık) 10000 -> 1 kere döner 10001 -> 73 kere döner 10002 -> 1 kere döner 10003 -> 6 kere döner 10004 -> 1 döner 10005 -> 2 kere döner toplam = 84 kere aynı işlem tekrar edilir. umarım örnekler açıklayıcı olmuştur. |
Daha iyi algoritmalar da var: http://en.wikibooks.org/wiki/Efficient_Prime_Number_Generating_Algorithms Burada bakicak olursak en son verilen algoritma 10000. ci sayiyi 0.01 saniyede veriyor. Ilk algoritma bile 10000. ci sayiyi 1.6 saniyede veriyor. Yapilmasi basit ve anlasilir olan 3. algoritma. Tabi bunu anlamak icin ilk 2 algoritmayi anlamak gerekiyor. 1. algoritma: Sayi asal mi degil mi bunu ogrenmek icin elimizde bir liste olur ve bu listede sadece karsilastigimiz asal sayilar bulunur, mevcut sayi bu listedeki sayilara bolunmuyorsa mevcut sayi bu listeye eklenir. Mevcut listeye 2 sayisini ekleyerek basliyoruz ve 3 ten itibaren baslayarak bu algoritmayi uyguluyoruz. (100 000 inci sayiya 130 saniyede ulasiyor bu algoritma) 2. algoritma: 2 den baska hic bir cift sayi asal degildir. O zaman neden 2 ile ugrasiyoruz ki? 3 ten baslayip sayiyi cifter cifter arttirirsak hep tek sayilara bakmis oluruz. (100 000 inci sayiya 65 saniyede ulasiyor) 3. algoritma: Baktigimiz sayinin karekoku eger listedeki bolmeyi kontrol ettigimiz sayidan buyukse o zaman listeye bakmaya devam etmeye gerek yoktur, cunku karekokunden buyuk sayilar asal sayinin kendi bolumu olamaz. (100 000 inci sayiya 27 saniyede ulasiyor) |
| gösterdiginiz ilgiden dolayı hepinize teşekkür ederim :) |
Yukarıda verilen sitedeki algoritma n. asal sayıyı değil, n'e kadar olan asal sayıları veriyordu dolayısıyla biraz bi değişiklik yaptım, 10000. asal sayıyı (değişiyor sürekli ama) 300-350 ms'de falan buluyorum, kullandığım kod şu (birebir geçirmeye çalıştım, C#); static List<long> allPrimes(long n) Benzer bir mantıkla çalışan kendi kodum ise 350-450 ms arasında sonuç veriyor; static long ninciAsal(int n) Bu 100 ms'lik fark nereden kaynaklanıyor olabilir? Kodumda değişiklik yapılması gereken yerler mi var acaba? Kullanım;
|
|
En cok kullanilan yontemlerden bir tanesi kriptografide. http://en.wikipedia.org/wiki/Fermat_primality_test |
ama başlangıç seviyesi için, ve arkadaşın yazdığı kodta, döngüyü sonuna kadar devam ettirip, ettirmemenin neleri farkettiğini göstermek için bu algoritma üstünde durdum :) |
While loopunda sadece 1 ekliyorsun 2 eklemek yerine. asallar.Add(2) deyip l i 3 ten baslatirsan while dongusunun icindede l i 2 ser 2 ser arttirirsan algoritma hizlanir gibi duruyor. 2. olarak ise asal methodunda foreach loop ile for loopun var. For loop gereksiz duruyor. Foreach loopunda yapmak istedigini direkt yapmalisin gerek yok maxi yapip saymaya. Yapicagini orada yap (sayi buyuk mu check et, daha sonra bolunuyor mu onu check et) |
Teşekkür ederim, deniyim, bir de okulda bir derste (Discreate Math di galiba) bir algoritmanın çalışma süresi ile ilgili birşey öğrenmiştik. Döngüler, tekrar edilen şeyler polinom olarak yazıp (iki iç içe döngü sanırım n^2 olarak yazılıyordu [ikisi de n kere dönüyorsa]), matematiksel işlemleri vs. constant olarak varsayıp işlem yapıyorduk (ve hesaba katmıyorduk, ama buradaki süre ölçerler herşeyi hesaba katıyor dolaylı olarak). Demek istediğim, bu süreler sadece bir deney sonucu, mesela benim kodum diğer algoritmadan çoğu denememde yaklaşık 100-150 ms uzun sürüyor ama belki de matematiğini yapsam, n sayısı çok büyüdüğünde 2 katı 10 katı vs. uzun sürecek. Dolayısıyla bu sürelere güvenmeli mi, yoksa oturup matematiksel hesabını mı yapmalı? Sitedeki algoritmaların mantığı çok anlaşılır da burada paylaşılan o efsane kodu çözemedim, adresleme bilgimden kaynaklanıyor olabilir * ve & gördüğüm yerde bi korku basıyor, açıklaması var mıdır bi yerde? Edit: efsane kod şu konudaymış kafa gitmiş; http://forum.donanimhaber.com/m_98945826/tm.htm |
| buyuk hesaplamalarda divide and conquer metodunu kullanamk iyi bir secenek olabilir. |
Sorunun hacmine gore degisir bu soru. Yeri gelir bir sorun icin bir algoritma kurman gerekir bu algoritma O((n^2)/1000) olabilir ve baskasi gelipte sana benim O(n*10000) algoritmam var seninkisinden daha iyi diyebilir. Fakat gercek hayatta ancak n = 10000000 iken bu iki algoritmanin calisma suresi birbirine esit olur cunku (10000000^2)÷1000 = 10000000*10000. Eger sen elindeki listenin 10 milyon elemandan az oldugunu surekli ispatlarsan o zaman constant degerleri ele alabilirsin, fakat bunu ispatlayamazsan o zaman O(n^2) ile O(n) karsilasitmasi olur, bu yuzdende 2. algoritma daha hizlidir deriz (cunku n sonsuza gider). Kendi yaptigin surelerin karsilastirmasiyla asymptotic complexity nin karsilasitirmak dogru olmaz. Birde o sitedeki kullanilan dil senin kullandigin dilden farkli olabilir, donanimda farkli olabilir. Ornegin dedigin gibi matematiksel islemleri saymayiz, fakat senin islemcin bir matematiksel islemi constant zamanda yapamazken karsi tarafinki yapabiliyor olabilir. Eger mantikli bir karsilastirma yapmak istiyorsan n sayisini al(atiyorum 100) bunun zamanini al (atiyorum 1 saniye) simdi x sayisi al (atiyorum 1000) n*x in zamanini al (atiyorum 10000 saniye) n*x in zamanini n e bol (10000 saniye) o zaman diyebiliriz ki bu yapilan testte karsi tarafin 100. sayiyla 100000. ci sayinin orani a dir. Bu orani kendi sonucunla karsilastir, yakin bir sonucsa algoritmanin runtime complexity si buyuk ihtimalle aynidir, x sayisi ne kadar buyukse bu yakinliktan o kadar emin oluruz. |
Bu işin bir standardı yok mudur? Ne biliyim karekök alma işlemini (öyle bir built-in işlem var mı işlemcilerde bilmiyorum, yoksa da aynı algoritma & aynı kod için diyelim) her işlemci aynı sürede yapamıyorsa, örneğin o sitedeki algoritma süresi yazılırken "normal süre" + "işlemci farkından oluşabilecek farklar" (deneylerdeki error gibi)? |
| blockchain projesinde freelance yazılımcı olarak çalışmak isteyen var mı? |
1. sayfa
****************
#include<stdio.h>
#include<conio.h>
bool controllingprimenumber(long number){
int k=0;
int i=2;
while(i<number)
{
if(number%i==0)
{
k++;
}
i++;
}
if(k==0)
return 1;
if(k>0)
return 0;
}
int main(){
long number=3;
int i=0;
while(i<=10000)
{
if(controllingprimenumber(number)==1)
{
i++;}
number++; }
printf("10.001st prime number is %ld",number);
getch();
return 0;
}
**************************
DH forumlarında vakit geçirmekten keyif alıyor gibisin ancak giriş yapmadığını görüyoruz.
Üye Ol Şimdi DeğilÜye olduğunda özel mesaj gönderebilir, beğendiğin konuları favorilerine ekleyip takibe alabilir ve daha önce gezdiğin konulara hızlıca erişebilirsin.