Kedi nereye gidecek? (yörünge mekaniği)


16

Neredeyse kütlesiz bir kedi, (x, y, z)hızda bir noktada uzaya düşüyor (bir uzay giysisi ve her şeyle endişelenmeyin) (vx, vy, vz). Noktada sabit, sonsuz yoğun bir gezegen (0 hacmi ile) vardır (0, 0, 0)ve nesneleri rivmeli olarak uzaktan çeker 1/r^2. Newton yer çekimine göre, nesne zaman sonra nereye gidiyor t?

Bu durumda neredeyse kütlesiz değeri çıktısını aldığınız anlamına gelir lim (mass --> 0) <position of cat>. Kütle gezegenin yer çekiminden etkilenir, ancak gezegen kedinin yerçekiminden etkilenmez. Başka bir deyişle, merkezi beden sabittir.

Bu Code Golf'e biraz benziyor : Uzay gemisinin kaderi nedir? [kayan noktalı sürüm] , ancak doğruluk ölçtüğü için bu farklı.

3 saniyeden daha kısa sürede çalışması gereken bir simülasyona dayalı bir çözüm uygulayabilirsiniz, VEYA tam bir değer veren bir program da uygulayabilirsiniz (ayrıca 3 saniyeden daha kısa sürede çalıştırılmalıdır). Aşağıdaki puanlama ayrıntılarına bakın. Bir simülasyon uygularsanız, kesin olması gerekmez, ancak yanlışlık nedeniyle puanınız daha düşük olacaktır.

Girdi : x y z vx vy vz tmutlaka x, y, z koordinatlarını, x, y ve z yönlerindeki hızı ve zamanı temsil eden tam sayılar olmak zorunda değildir. Kedinin hızının, o irtifadaki kaçış hızından kesinlikle daha düşük olduğu garanti edilir. Bir işleve parametreler dahil olmak üzere giriş her yerden alınabilir. Program dizüstü bilgisayarımda üç saniyeden daha kısa sürede çalışmalı t < 2^30, yani bir simülasyon çalıştırıyorsanız, zaman testinizi buna göre ayarlamanız gerekir. Her test durumu için 3 saniyelik sınıra ulaşmayı planlıyorsanız, bilgisayarımda üç saniye içinde çalışmasını sağlamak için hız kazançları için daha doğru / daha az doğru hale getirebilecek ayarlanabilir bir parametre olduğundan emin olun.

Çıktı :, x y zsüre sonra konum t.

İki cisim problemi mükemmel bir şekilde çözülebildiğinden teorik olarak mükemmel ve doğru bir cevap almak mümkündür.

Puanlama : Herhangi bir test durumunda, hata, çıktınız ile "doğru" çıktı arasındaki mesafe olarak tanımlanır. Gerçek çıktı, test senaryosu snippet'inin ürettiği çıktı olarak tanımlanır. Hata daha küçükse 10^(-8), hata sıfıra yuvarlanır. Puanınız 100 (veya daha fazla) rastgele test vakasındaki ortalama hatadır. Kusursuz bir cevap yazarsanız, 0 puan almalısınız; en düşük puan kazanır ve bağlar kod uzunluğuna göre kesilir.

Test senaryoları :

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

Bu durumda, yörünge periyot 2 * pi ile mükemmel daireseldir, bu nedenle 159154943 kez daire çizdikten sonra kedi yaklaşık olarak (0.83789, -0.54584) biter. Bu, kodunuzun test edileceği bir test durumu değildir; bununla birlikte, kusursuz bir cevap gönderirseniz, bu konuda test etmek isteyebilirsiniz.

Aşağıdaki pasaj rastgele ek test senaryoları oluşturur ve gönderimleri yargılamak için kullanılacaktır; bununla ilgili bir hata varsa bana bildirin:


Zaman tsaniye cinsinden mi verilir? Eğer öyleyse, hız saniyede birim olarak mı yoksa daha küçük bir şey olarak mı verilir?
R. Kap

@R. Kap Önemli değil. tbirim zamanda, ne olursa olsun verilir ve hız aynı birimi kullanır. İster saniye ister saat olsun, cevap aynı olacaktır.
soktinpk

nearly massless catPeki, kedinin tam kütlesi ne olurdu? 0Bu kedinin kütlesi için bir değer olarak mı kullanmalıyız ?
R. Kap

@R. Kap Evet. Ama yine de yerçekiminden etkileniyor (genellikle Newton kütlesi olmayan cisimlerin yerçekiminden etkileneceğini düşünmüyordu). Bu yüzden keyfi olarak küçük bir kütleye sahip olduğunu düşünmeliyiz ve cevabınız aslında kedinin kütlesi sıfıra giderken konumdur. Ana nokta, gezegenin kendisinin kedi tarafından hiç etkilenmediğidir.
soktinpk

2
@soktinpk merkezi gövdenin sabit olduğunu açıkça söylemek daha kolay olabilir.
Maltysen

Yanıtlar:


6

Python 3.5 + NumPy, tam, 186 bayt

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

Bu, Jesper Göranssonhis, “Kepler probleminin simetrileri”, 2015'e dayanan bir formül kullanarak kesin bir çözüm . Kapalı form çözümü olmayan Trans + B cos x + C sin x = D aşkın denklemini çözmek için ikili bir arama kullanır.

İşlev, NumPy dizileri olarak iletilecek konum ve hızın beklemesini bekler:

>>> 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])

Ne yapar @?
R. Kap

1
Python 3.5'te NumPy'nin aşırı yüklediği yeni bir operatör numpy.dot(nokta ürün / matris çarpımı). Bkz. PEP 465.
Anders Kaseorg

Golf oynamak harika, ama bu kod zorluğu, biraz daha açık hale getirebilir misiniz, Python'da bazı çizikler yaptım ve anomali, teta, eksantriklik, dönem vb. teta işareti ve xy referans düzleminden 3d uzaya dönüşün belirlenmesi. Yine de, bu gerçekten harika şeyler
mil

miles Bağlar kod uzunluğuna göre parçalandığından, bunun golf oynaması mantıklıdır.
Mego

Test kasası jeneratörü sadece eliptik yörüngeler oluşturduğundan, ben de tam bir çözüm üzerinde çalıştığım için bu doğru
mil

2

JavaScript

Bu sadece topun yuvarlanması içindir, çünkü kimse cevap göndermiyor gibi görünüyor. İşte çok geliştirilebilecek çok saf ve basit bir yol:

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];
}

Test yapmak:

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

Hey, bu oldukça iyi. Yuvarlanması için yeterli olmayan yaklaşık 3.333 * 10 ^ (- 6) hatası var ... yakın.

Sadece eğlence için:

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

Oh iyi; bu yüzden en iyisi değil.

Ve jeneratörden rastgele bir test durumunda:

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]

Sadece yaklaşık 0.32305 hata ile!

Verlet entegrasyonu veya süslü algoritma gibi bir şey kullanarak bu çok geliştirilebilir. Aslında, bu algoritmalar simülasyonlara rağmen mükemmel puanlar bile alabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.