Kemana kucing itu pergi? (mekanika orbital)

16

Seekor kucing yang hampir tanpa massa dijatuhkan di ruang angkasa (jangan khawatir, dengan baju ruang angkasa dan segalanya) pada titik (x, y, z)dengan kecepatan (vx, vy, vz). Ada planet yang tetap, padat tak terhingga (dengan volume 0) di titik (0, 0, 0)dan menarik objek di kejauhan rdengan percepatan 1/r^2. Menurut gravitasi Newton, ke mana objek pergi setelah waktu t?

Hampir tanpa massa dalam hal ini berarti Anda mengeluarkan nilai lim (mass --> 0) <position of cat>. Massa dipengaruhi oleh gravitasi planet, tetapi planet ini tidak terpengaruh oleh gravitasi kucing. Dengan kata lain, tubuh pusat tetap.

Ini agak mirip dengan Code Golf: Apa nasib pesawat ruang angkasa itu? [versi floating point] , tapi ini berbeda karena mengukur akurasi.

Anda dapat mengimplementasikan solusi berdasarkan simulasi, yang harus berjalan dalam waktu kurang dari 3 detik, ATAU Anda dapat mengimplementasikan program yang memberikan nilai tepat (juga harus berjalan dalam waktu kurang dari 3 detik). Lihat detail penilaian di bawah ini. Jika Anda menerapkan simulasi, itu tidak harus tepat, tetapi skor Anda akan lebih rendah karena ketidaktepatan tersebut.

Masukan : x y z vx vy vz t, belum tentu bilangan bulat yang mewakili x, y, z koordinat, kecepatan dalam x, y, dan arah z dan waktu masing-masing. Dijamin bahwa kecepatan kucing benar-benar kurang dari kecepatan lepas di ketinggian itu. Input dapat diambil dari mana saja, termasuk parameter ke suatu fungsi. Program harus berjalan dalam waktu kurang dari tiga detik pada laptop saya untuk t < 2^30, yang berarti, jika Anda menjalankan simulasi, Anda harus menyesuaikan catatan waktu Anda sesuai. Jika Anda berencana untuk mencapai batas 3 detik untuk setiap test case, pastikan ada parameter yang dapat diubah yang dapat membuatnya lebih akurat / kurang akurat untuk peningkatan kecepatan, sehingga saya dapat membuatnya berjalan dalam tiga detik di komputer saya.

Output : x y z, posisi setelah waktu t.

Karena masalah dua tubuh dapat diselesaikan dengan sempurna, secara teori dimungkinkan untuk mendapatkan jawaban yang sempurna dan benar.

Penilaian : Untuk kasus uji apa pun, kesalahan didefinisikan sebagai jarak antara output Anda dan output "true". Output sebenarnya didefinisikan sebagai output yang dihasilkan oleh snipet kasus uji. Jika kesalahan kurang dari 10^(-8), kesalahan dibulatkan ke nol. Skor Anda adalah kesalahan rata-rata pada 100 (atau lebih) kasus uji acak. Jika Anda menulis jawaban yang sangat akurat, Anda harus mendapatkan skor 0; kemenangan skor terendah, dan ikatan akan diputus berdasarkan panjang kode.

Kasus uji :

1 0 0 0 -1 0 1000000000 --> 0.83789 -0.54584 0

Dalam kasus ini, orbitnya melingkar sempurna dengan periode 2 * pi, jadi setelah berputar 159154943 kali, kucing berakhir pada sekitar (0,83789, -0,54584). Ini bukan ujian, kode Anda akan diuji; Namun, jika Anda mengirimkan jawaban yang sangat akurat, Anda mungkin ingin mengujinya.

Cuplikan di bawah ini menghasilkan kasus uji tambahan acak dan akan digunakan untuk menilai pengiriman; beri tahu saya jika ada bug dengan ini:

soktinpk
sumber
Apakah waktu tdiberikan dalam detik? Jika demikian, apakah kecepatan akan diberikan dalam satuan per detik, atau sesuatu yang lebih kecil?
R. Kap
@R. Kap Tidak masalah. tdiberikan dalam satuan waktu, apa pun itu, dan kecepatan akan menggunakan satuan yang sama. Apakah dalam hitungan detik atau jam, jawabannya akan sama.
soktinpk
nearly massless catNah, seperti apa massa kucing itu? Haruskah kita menggunakan 0nilai untuk massa kucing ini?
R. Kap
@R. Kap Ya. Tetapi masih dipengaruhi oleh gravitasi (biasanya, Newton tidak menganggap benda tanpa massa dipengaruhi oleh gravitasi). Jadi kita harus menganggapnya memiliki massa kecil yang sewenang-wenang, dan jawaban Anda sebenarnya adalah posisi ketika massa kucing menjadi nol. Poin utamanya adalah bahwa planet itu sendiri tidak terpengaruh sama sekali oleh kucing.
soktinpk
2
@ sittinpk mungkin lebih mudah untuk secara eksplisit mengatakan bahwa tubuh pusat sudah diperbaiki.
Maltysen

Jawaban:

6

Python 3.5 + NumPy, tepat, 186 byte

from math import*
def o(r,v,t):
 d=(r@r)**.5;W=2/d-v@v;U=W**1.5;b=[0,t*U+9]
 while 1:
  a=sum(b)/2;x=1-cos(a);y=sin(a)/U;k=r@v*x/W+d*y*W
  if a in b:return k*v-r*x/W/d+r
  b[k+a/U-y>t]=a

Ini adalah solusi yang tepat, menggunakan formula I yang direkayasa berdasarkan Jesper Göranssonhis, "Symmetries of the Kepler problem", 2015 . Ia menggunakan pencarian biner untuk menyelesaikan persamaan transendental Ax + B cos x + C sin x = D, yang tidak memiliki solusi bentuk-tertutup.

Fungsi mengharapkan posisi dan kecepatan untuk dilewatkan sebagai array NumPy:

>>> from numpy import array
>>> o(array([1,0,0]),array([0,-1,0]),1000000000)
array([ 0.83788718, -0.54584345,  0.        ])
>>> o(array([-1.1740058273269156,8.413493259550673,0.41996042044140003]),array([0.150014367067652,-0.09438816345868332,0.37294941703455975]),7999.348650387233)
array([-4.45269544,  6.93224929, -9.27292488])
Anders Kaseorg
sumber
Apa yang @dilakukan?
R. Kap
1
Ini adalah operator baru di Python 3.5 yang NumPy kelebihan untuk numpy.dot(multiplikasi produk / matriks). Lihat PEP 465.
Anders Kaseorg
Sangat bagus karena golf, tetapi ini adalah tantangan kode, dapatkah Anda membuatnya sedikit lebih jelas, saya memiliki beberapa goresan di Python, dan dapat menghitung anomali, theta, eksentrisitas, titik, dll, tapi saya terjebak dalam menentukan tanda theta dan menentukan rotasi dari bidang referensi xy ke ruang 3d. Namun, ini benar-benar hebat
mil
@miles Karena ikatan diputus oleh panjang kode, masuk akal untuk ini akan di-golf.
Mego
Itu benar, karena saya juga sedang mengerjakan solusi yang tepat, karena generator case test hanya menciptakan orbit elips
mil
2

Javascript

Ini hanya untuk membuat bola bergulir, karena sepertinya tidak ada yang memposting jawaban. Ini adalah cara yang sangat naif dan sederhana yang dapat ditingkatkan banyak:

function simulate(x, y, z, vx, vy, vz, t) {
  var loops = 1884955; // tune this parameter
  var timestep = t / loops;
  for (var i = 0; i < t; i += timestep) {
    var distanceSq = x*x + y*y + z*z; // distance squared from origin
    var distance = Math.sqrt(distanceSq);
    var forceMag = 1/distanceSq; // get the force of gravity
    var forceX = -x / distance * forceMag;
    var forceY = -y / distance * forceMag;
    var forceZ = -z / distance * forceMag;
    vx += forceX * timestep;
    vy += forceY * timestep;
    vz += forceZ * timestep;
    x += vx * timestep;
    y += vy * timestep;
    z += vz * timestep;
  }
  return [x, y, z];
}

Pengujian:

simulate(1, 0, 0, 0, -1, 0, Math.PI*2) --> [0.9999999999889703, -0.0000033332840909716455, 0]

Hei, itu cukup bagus. Ini memiliki kesalahan sekitar 3,333 * 10 ^ (- 6) yang tidak cukup untuk dibulatkan ... sudah dekat.

Hanya untuk bersenang-senang:

console.log(simulate(1, 0, 0, 0, -1, 0, 1000000000))
--> [-530516643639.4616, -1000000000.0066016, 0]

Baiklah; jadi itu bukan yang terbaik.

Dan pada test case acak dari generator:

simulate(-1.1740058273269156,8.413493259550673,0.41996042044140003,0.150014367067652,-0.09438816345868332,0.37294941703455975,7999.348650387233)
-->    [-4.528366392498373, 6.780385554803544, -9.547824236472668]
Actual:[-4.452695438880813, 6.932249293597744, -9.272924876103785]

Dengan kesalahan hanya sekitar 0,32305!

Ini dapat ditingkatkan banyak dengan menggunakan sesuatu seperti integrasi Verlet atau beberapa algoritma mewah. Bahkan, algoritma tersebut bahkan bisa mendapatkan skor sempurna, meskipun simulasi.

soktinpk
sumber