Saya seorang peneliti sains planet dan satu proyek yang sedang saya kerjakan adalah N- semua simulasi cincin Saturnus. Tujuan dari penelitian khusus ini adalah untuk menyaksikan partikel-partikel menggumpal di bawah gravitasi diri mereka sendiri dan mengukur massa agregat rumpun versus kecepatan rata-rata semua partikel dalam sel. Kami sedang mencoba mencari tahu apakah ini dapat menjelaskan beberapa pengamatan yang dilakukan oleh pesawat ruang angkasa Cassini selama titik balik matahari musim panas Saturnus ketika struktur besar terlihat melemparkan bayangan pada cincin hampir ujung-ke-atas. Di bawah ini adalah tangkapan layar seperti apa bentuk waktu yang diberikan. (Setiap partikel berdiameter 2 m dan sel simulasi itu sendiri sekitar 700 m.)
Kode yang saya gunakan sudah memuntahkan kecepatan rata-rata di setiap timestep. Yang perlu saya lakukan adalah mencari cara untuk menentukan massa partikel dalam rumpun dan BUKAN partikel liar di antara mereka. Saya tahu posisi setiap partikel, massa, ukuran, dll., Tetapi saya tidak tahu dengan mudah bahwa, katakanlah, partikel 30.000-40.000 bersama dengan 102.000-105.000 membentuk satu untaian yang bagi mata manusia jelas.
Jadi, algoritma yang perlu saya tulis harus berupa kode dengan sesedikit mungkin parameter yang dimasukkan pengguna (untuk replikasi dan objektivitas) yang akan melewati semua posisi partikel, mencari tahu partikel apa yang termasuk rumpun, dan kemudian menghitung massa. Akan lebih bagus jika bisa melakukannya untuk "masing-masing" rumpun / untai yang bertentangan dengan segala sesuatu di atas sel, tetapi saya tidak berpikir saya benar - benar membutuhkannya untuk memisahkan mereka.
Satu-satunya hal yang saya pikirkan adalah melakukan semacam perhitungan jarak N 2 di mana saya akan menghitung jarak antara setiap partikel dan jika, katakanlah, 100 partikel terdekat berada dalam jarak tertentu, maka partikel itu akan dianggap sebagai bagian dari suatu gugus. Tapi itu tampak sangat ceroboh dan saya berharap Anda, orang-orang dan programmer CS mungkin tahu solusi yang lebih elegan?
Diedit dengan saya Solusi: Apa yang saya lakukan adalah untuk mengambil semacam pendekatan tetangga terdekat-/ cluster dan melakukan cepat-n-kotor N 2 implementasi pertama. Jadi, ambil setiap partikel, hitung jarak ke semua partikel lain, dan ambang untuk dalam sebuah cluster atau tidak adalah apakah ada partikel N dalam jarak d ( sayangnya, dua parameter yang harus ditetapkan apriori , tetapi seperti yang dikatakan oleh beberapa tanggapan / komentar, saya tidak akan lolos dengan tidak memiliki beberapa dari mereka).
Saya kemudian mempercepatnya dengan tidak menyortir jarak tetapi hanya melakukan pencarian urutan N dan menambah counter untuk partikel dalam d , dan mempercepat hal-hal dengan faktor 6. Kemudian saya menambahkan "pohon programmer bodoh" (karena saya tahu hampir tidak ada tentang kode pohon). Saya membagi sel simulasi menjadi sejumlah set kisi (hasil terbaik ketika ukuran kisi ≈7 d ) di mana kisi-kisi utama berbaris dengan sel, satu kisi diimbangi dengan setengah di x dan y , dan dua lainnya diimbangi dengan 1/4 in ± x dan ± y . Kode kemudian membagi partikel ke dalam kisi-kisi, maka setiap partikel N hanya harus memiliki jarak yang dihitung dengan partikel lain dalam sel itu.
Secara teoritis, jika ini adalah pohon asli, saya harus memesan N * log ( N ) sebagai lawan dari kecepatan N 2 . Saya berada di antara keduanya, di mana untuk sub-set 50.000-partikel, saya mendapat peningkatan 17x dalam kecepatan, dan untuk 150.000-partikel sel, saya mendapat peningkatan 38x dalam kecepatan. 12 detik untuk yang pertama, 53 detik untuk yang kedua, 460 detik untuk sel 500.000 partikel. Itu adalah kecepatan yang sebanding dengan berapa lama kode yang diperlukan untuk menjalankan simulasi 1 timestep maju, jadi itu masuk akal pada saat ini. Oh - dan itu sepenuhnya berulir, jadi itu akan membutuhkan prosesor sebanyak yang saya bisa lakukan.