2010-01-28 11 views
6

yöntemleri multiply, divide ve halen BigInteger yılında pow Ne karmaşıklığı vardır? Dokümantasyondaki hesaplama karmaşıklığından (ya da başka herhangi bir yerden) bahsedilmemektedir. Eğer (JDK ile sağlanır) BigInteger için koduna baktığımızdaJava 7'nin BigInteger'sinde hangi karmaşıklık işlemleri var?

+0

Aslında daha önce denedim. Ancak çok fazla bilgi olmadan analiz etmek oldukça zor görünüyor. StackOverflow'u okuyan birinin bu bilgiye sahip olmasını umuyorum. Belki bu çok iyimser oluyor? –

+0

Java 7'den bahsetmenin belirli bir nedeni var mı? BigInteger, Java 1.1'den beri var. –

cevap

3

, multiply(..) (aslında yöntem multiplyToLen(..) olan) O (n^2) olduğunu bana görünür. Diğer yöntemlerin kodu biraz daha karmaşık, ama kendini görebiliyorsun.

Not: Bu onu ölçün o

+3

şunlardır: http://en.wikipedia.org/wiki/Computational_complexity_of_mathematical_operations ... Eğer O'dan O (n^2) ayırt edebilirsiniz (n^1,585) ya da O (n^1,465)? – Joey

+1

Java 7. değişiklikler ben aramaya bulunan bilgileri hatırlayamıyorum olmuştur inanıyoruz, ama onlar kıt. –

+0

Rössel: çoğalması için diğer algoritmalar var _exist_ ancak Java 6 bunları kullanmaz. Büyük sayılar çarpılırken, kesinlikle ders kitabı algoritması ve Karatsuba çarpımı arasındaki farkı fark edeceksiniz. Diğerleri, sayılarla birincil belleği doldurmadıkça daha az zıplıyorlar. – Charles

2

Java 7. farklılık olmayacak varsayalım Java 6. içindir. Doğrusal olarak artan işlenenlerle işlemler yapın ve zamanları bir diyagram üzerinde çizin. Geçerli değerlendirme sonuçları almak için JVM'yi (birkaç çalışma) ısıtmayı unutmayın.

işlemleri polinom veya açık olmalıdır üstel doğrusal O (n), ikinci dereceden O (n^2), ise.

DÜZENLEME: Eğer algoritmalar teorik sınırları vermek mümkün olmakla birlikte, pratikte yararlı böyle olmayabilir. Her şeyden önce, karmaşıklık faktörü vermez. Onlar sorun ise (örneğin Coppersmith-Winograd matris çarpım) için yeterli değildir çok fazla zaman ve kaynak yeme için bazı doğrusal ya da subquadratic algoritmalar basitçe yararlı değildir. Ardından, hesaplamanız yalnızca deneme yoluyla algılayabileceğiniz tüm klupler içerebilir. Sorunu çözmek için hiçbir şey yapmayan ama gerçek çözücüyü (matris koşullandırma) hızlandıran algoritmalar hazırlanıyor. Suboptimal uygulamaları vardır. Daha uzun uzunluklarda, hızınız önemli ölçüde düşebilir (önbellek eksik, hafıza taşıma vb.). Yani pratik amaçlar için, deney yapmayı tavsiye ederim.

iyi şey kez her seferinde giriş uzunluğu iki katına ve karşılaştırmaktır. Ve evet, bir algoritma n^1.5 veya n^1.8 karmaşıklığı varsa öğrenmek yapmak . Basitçe giriş uzunluğu dörde ve size uzunluğu 256 defa çarpın eğer tekrar 1.8 için yaklaşık yarım zaman olsun 1.5 yerine 2. için sadece yarım zamana ihtiyaç duyarlar.

+0

Bu işe yarayabilir. N'nin büyük değerlerini test etmem gerekecek. İki n bit BigIntegers (t_0) ve sonra iki 2n bit BigIntegers (t_1) çarpma süresini ölçtüyse. Sonra karmaşıklığın O (n^(log2 (t_1/t_0))) olmasını bekleyebilirim. Genelde ampirik yöntemlerle ilgili şüphelerim var (muhtemelen haksız). –

+0

Bu, almak için zor bir yaklaşımdır. _A priori_, algoritmaların bir kombinasyonu yerine tek bir algoritmanın kullanıldığını düşünmek için bir neden yoktur. Böylece 10 haneden 1000 haneye kadar ölçeklendirme, 1000 haneden 3000 haneye kadar ölçeklemeden farklı olabilir. – Charles

1

conservateism ve kullanışlı regresyon testlerinin eksikliği (büyük veri setleri) için güneş jdk tarafından kullanılmayan yeni bir "iyi" BigInteger sınıfı yoktur. Daha iyi algoritmalar yapan adam eski BigInteger'i yorumlarda tartışmış olabilir.

Burada Sen kaynak kodunu kontrol edebilir

İlgili konular