Apa pendekatan terbaik untuk menghitung faktor prima terbesar dari suatu angka?
Saya pikir yang paling efisien adalah sebagai berikut:
- Temukan bilangan prima terendah yang membagi dengan bersih
- Periksa apakah hasil pembagiannya prima
- Jika tidak, cari yang terendah berikutnya
- Pergi ke 2.
Saya mendasarkan asumsi ini pada hal itu menjadi lebih mudah untuk menghitung faktor prima kecil. Apakah ini benar? Pendekatan apa lagi yang harus saya perhatikan?
Sunting: Saya sekarang menyadari bahwa pendekatan saya sia-sia jika ada lebih dari 2 faktor utama dalam permainan, karena langkah 2 gagal ketika hasilnya adalah produk dari dua bilangan prima lainnya, oleh karena itu diperlukan algoritma rekursif.
Sunting lagi: Dan sekarang saya menyadari bahwa ini masih berfungsi, karena bilangan prima yang ditemukan terakhir harus menjadi bilangan tertinggi, oleh karena itu setiap pengujian lebih lanjut terhadap hasil non-prima dari langkah 2 akan menghasilkan bilangan prima yang lebih kecil.
sumber
1.
menemukan angka yang membagi dengan jelas (untuk i = 2 ke int (sqr (num)))2.
dibagi dengan angka itu (num = num / i) dan berulang sampai tidak ditemukan dalam interval 1.3.
num adalah faktor terbesarJawaban:
Sebenarnya ada beberapa cara yang lebih efisien untuk menemukan faktor angka besar (untuk divisi percobaan yang lebih kecil berfungsi dengan baik).
Salah satu metode yang sangat cepat jika nomor input memiliki dua faktor yang sangat dekat dengan akar kuadratnya dikenal sebagai faktorisasi kulit . Itu memanfaatkan identitas N = (a + b) (a - b) = a ^ 2 - b ^ 2 dan mudah dimengerti dan diimplementasikan. Sayangnya itu tidak terlalu cepat secara umum.
Metode yang paling terkenal untuk menghitung angka hingga 100 digit adalah Saringan kuadratik . Sebagai bonus, bagian dari algoritma mudah dilakukan dengan pemrosesan paralel.
Algoritma lain yang pernah saya dengar adalah algoritma Rho Pollard . Ini tidak seefisien Saringan Quadratic secara umum tetapi tampaknya lebih mudah untuk diterapkan.
Setelah Anda memutuskan cara membagi angka menjadi dua faktor, berikut adalah algoritma tercepat yang dapat saya pikirkan untuk menemukan faktor prima terbesar dari sebuah angka:
Buat antrian prioritas yang awalnya menyimpan nomor itu sendiri. Setiap iterasi, Anda menghapus angka tertinggi dari antrian, dan mencoba untuk membaginya menjadi dua faktor (tentu saja 1 tidak menjadi salah satu faktor itu). Jika langkah ini gagal, angkanya prima dan Anda memiliki jawaban! Kalau tidak, Anda menambahkan dua faktor ke dalam antrian dan ulangi.
sumber
Inilah algoritma terbaik yang saya tahu (dengan Python)
Metode di atas berjalan dalam
O(n)
kasus terburuk (ketika input adalah bilangan prima).EDIT:
Di bawah ini adalah
O(sqrt(n))
versi, seperti yang disarankan dalam komentar. Ini kodenya, sekali lagi.sumber
O(sqrt(n))
kasus terburuk" - Tidak, berjalan dalamO(n)
kasus terburuk (mis. kapann
prima.)Jawaban saya didasarkan pada Triptych , tetapi meningkatkan banyak di atasnya. Ini didasarkan pada fakta bahwa di luar 2 dan 3, semua bilangan prima adalah dari bentuk 6n-1 atau 6n +1.
Baru-baru ini saya menulis artikel blog menjelaskan cara kerja algoritma ini.
Saya berani memberanikan diri bahwa suatu metode di mana tidak perlu untuk tes primality (dan tidak ada konstruksi ayakan) akan berjalan lebih cepat daripada yang menggunakan itu. Jika itu masalahnya, ini mungkin merupakan algoritma tercepat di sini.
sumber
while (multOfSix - 1 <= n)
Kode JavaScript:
Contoh Penggunaan:
Berikut ini contoh kode :
sumber
Mirip dengan jawaban @ Triptych tetapi juga berbeda. Dalam contoh ini daftar atau kamus tidak digunakan. Kode ditulis dalam Ruby
sumber
Semua angka dapat dinyatakan sebagai produk bilangan prima, misalnya:
Anda dapat menemukan ini dengan hanya mulai dari 2 dan hanya melanjutkan untuk membagi sampai hasilnya bukan kelipatan dari nomor Anda:
menggunakan metode ini Anda tidak harus benar-benar menghitung bilangan prima: semuanya akan menjadi bilangan prima, berdasarkan fakta bahwa Anda telah memfaktorkan angka sebanyak mungkin dengan semua angka sebelumnya.
sumber
currFactor = 3513642
, kami tahu bahwa 12345678987667 adalah yang utama, dan harus mengembalikannya sebagai jawabannya. Sebagai gantinya, kode ini akan melanjutkan enumerasi hingga 12345678987667 sendiri. Itu 3.513.642x lebih lambat dari yang diperlukan.sumber
while
loop Anda akan melewatii
nilai2,2,2,2,2,2,2,2,2,2,2,2, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5, 2,3,4,5
. Semua dari 60 iterasi. Tetapi untuk (10 ^ 12 + 39) akan ada (10 ^ 12 + 38) iterasii=2,3,4,5,6,...,10^12+39
,. Bahkan jika 10 ^ 10 ops membutuhkan satu detik, 10 ^ 12 akan memakan waktu 100 detik. Tetapi hanya 10 ^ 6 iterasi yang benar-benar diperlukan, dan jika 10 ^ 10 ops membutuhkan waktu satu detik, 10 ^ 6 akan membutuhkan 1 / 10.000 per detik.long n = 2*1000000000039L
? Apakah ini bekerja secepat yang seharusnya? (juga, dapatkah Anda menyederhanakan kode Anda dengan menggunakanreturn;
pernyataan?). (Jika Anda ingin saya berhenti menyenggol Anda, katakan saja;))Solusi paling sederhana adalah sepasang fungsi yang saling rekursif .
Fungsi pertama menghasilkan semua bilangan prima:
Fungsi kedua mengembalikan faktor prima dari angka yang diberikan
n
dalam urutan yang meningkat.n
.Faktor prima terbesar
n
adalah angka terakhir yang diberikan oleh fungsi kedua.Algoritma ini membutuhkan daftar malas atau bahasa (atau struktur data) dengan semantik panggilan-oleh-kebutuhan .
Untuk klarifikasi, berikut adalah salah satu (tidak efisien) implementasi di atas dalam Haskell:
Membuat ini lebih cepat hanya masalah menjadi lebih pintar dalam mendeteksi nomor mana yang prima dan / atau faktor
n
, tetapi algoritma tetap sama.sumber
Ada beberapa tes modulo yang superflous, karena n tidak pernah dapat dibagi dengan 6 jika semua faktor 2 dan 3 telah dihapus. Anda hanya dapat mengizinkan bilangan prima untuk i, yang ditunjukkan dalam beberapa jawaban lain di sini.
Anda dapat benar-benar menjalin saringan Eratosthenes di sini:
Lihat juga pertanyaan ini .
sumber
Saya sadar ini bukan solusi cepat. Posting semoga mudah dipahami sebagai solusi lambat.
sumber
Pendekatan Python Iterative dengan menghapus semua faktor utama dari nomor tersebut
sumber
Saya menggunakan algoritma yang terus membagi angka dengan Prime Factor saat ini.
Solusi saya di python 3:
Input:
10
Keluaran:5
Input:
600851475143
Keluaran:6857
sumber
Ini adalah usaha saya di c #. Hasil cetak terakhir adalah faktor utama nomor tersebut. Saya memeriksa dan berfungsi.
sumber
sumber
Menghitung faktor prima terbesar dari angka menggunakan rekursi dalam C ++. Cara kerja kode dijelaskan di bawah ini:
sumber
Inilah pendekatan saya untuk dengan cepat menghitung faktor prima terbesar. Hal ini didasarkan pada fakta bahwa modifikasi
x
tidak mengandung faktor non-prima. Untuk mencapai itu, kami membagix
segera setelah faktor ditemukan. Kemudian, satu-satunya yang tersisa adalah mengembalikan faktor terbesar. Itu sudah prima.Kode (Haskell):
sumber
Algoritma C ++ berikut ini bukan yang terbaik, tetapi bekerja untuk angka di bawah satu miliar dan cukup cepat
sumber
Menemukan solusi ini di web oleh "James Wang"
sumber
Faktor utama menggunakan saringan:
sumber
Sepertinya saya bahwa langkah # 2 dari algoritma yang diberikan tidak akan menjadi semua pendekatan yang efisien. Anda tidak memiliki harapan yang masuk akal bahwa itu prima.
Juga, jawaban sebelumnya yang menyarankan Saringan Eratosthenes sama sekali salah. Saya baru saja menulis dua program ke faktor 123456789. Satu didasarkan pada Saringan, satu didasarkan pada yang berikut:
Versi ini 90x lebih cepat dari Saringan.
Masalahnya, pada prosesor modern jenis operasi lebih penting daripada jumlah operasi, belum lagi bahwa algoritma di atas dapat berjalan dalam cache, Saringan tidak bisa. Saringan menggunakan banyak operasi yang mencoret semua angka komposit.
Perhatikan juga, bahwa faktor-faktor pemisah saya sebagaimana mereka diidentifikasi mengurangi ruang yang harus diuji.
sumber
Hitunglah daftar yang menyimpan bilangan prima terlebih dahulu, misalnya 2 3 5 7 11 13 ...
Setiap kali Anda memfaktorkan angka, gunakan implementasi oleh Triptych tetapi iterasi daftar bilangan prima ini bukan bilangan bulat alami.
sumber
Dengan Java:
Untuk
int
nilai:Untuk
long
nilai:sumber
Ini mungkin tidak selalu lebih cepat tetapi lebih optimis bahwa Anda menemukan pembagi utama yang besar:
N
adalah nomor kamureturn(N)
Sqrt(N)
N is divisible by Prime
demikianReturn(Prime)
Sunting: Pada langkah 3 Anda dapat menggunakan Saringan Eratosthenes atau Saringan Atkins atau apa pun yang Anda suka, tetapi dengan sendirinya saringan tidak akan menemukan Anda faktor utama terbesar. (Itulah sebabnya saya tidak akan memilih posting SQLMenace sebagai jawaban resmi ...)
sumber
Saya pikir akan lebih baik untuk menyimpan di suatu tempat semua kemungkinan bilangan prima lebih kecil daripada n dan hanya beralih melalui mereka untuk menemukan divisior terbesar. Anda bisa mendapatkan bilangan prima dari prime-numbers.org .
Tentu saja saya berasumsi bahwa nomor Anda tidak terlalu besar :)
sumber
Bukan yang tercepat tetapi berhasil!
sumber
Berikut adalah fungsi yang sama dengan @ Triptych yang disediakan sebagai generator, yang juga sedikit disederhanakan.
max prime kemudian dapat ditemukan menggunakan:
dan daftar faktor yang ditemukan menggunakan:
sumber
sumber