Dove andrà il gatto? (meccanica orbitale)


16

Un gatto quasi senza massa viene lasciato cadere nello spazio (non preoccuparti, con una tuta spaziale e tutto il resto) nel punto (x, y, z)con velocità (vx, vy, vz). C'è un pianeta fisso, infinitamente denso (con volume di 0) nel punto (0, 0, 0)e attira oggetti a distanza rcon accelerazione 1/r^2. Secondo la gravità newtoniana, dove va l'oggetto dopo il tempo t?

Quasi senza massa in questo caso significa che stai fornendo il valore di lim (mass --> 0) <position of cat>. La massa è influenzata dalla gravità del pianeta, ma il pianeta non è influenzato dalla gravità del gatto. In altre parole, il corpo centrale è fisso.

Questo è in qualche modo simile a Code Golf: qual è il destino dell'astronave? [versione a virgola mobile] , ma questo è diverso perché misura l'accuratezza.

È possibile implementare una soluzione basata su una simulazione, che deve essere eseguita in meno di 3 secondi, oppure è possibile implementare un programma che fornisce un valore esatto (deve essere eseguito anche in meno di 3 secondi). Vedi i dettagli del punteggio di seguito. Se si implementa una simulazione, non deve essere esatto, ma il punteggio sarà inferiore a causa dell'imprecisione.

Ingresso : x y z vx vy vz t, non necessariamente interi che rappresentano rispettivamente x, y, z coordinate, velocità nelle direzioni x, y, z e indicazioni e tempo. È garantito che la velocità del gatto è strettamente inferiore alla velocità di fuga a quell'altitudine. L'input può essere preso da qualsiasi luogo, inclusi i parametri di una funzione. Il programma deve essere eseguito in meno di tre secondi sul mio laptop t < 2^30, il che significa che, se si esegue una simulazione, è necessario regolare di conseguenza il proprio timestep. Se stai pensando di superare il limite di 3 secondi per ogni caso di test, assicurati che ci sia un parametro sintonizzabile che possa renderlo più accurato / meno accurato per i guadagni di velocità, in modo che io possa farlo funzionare in tre secondi sul mio computer.

Uscita : x y zla posizione dopo il tempo t.

Poiché il problema dei due corpi può essere risolto perfettamente, in teoria è possibile ottenere una risposta perfetta e corretta.

Punteggio : per ogni caso di test, l'errore è definito come la distanza tra l'output e l'output "vero". L'output vero è definito come quello generato dallo snippet del test case. Se l'errore è inferiore a 10^(-8), l'errore viene arrotondato per difetto a zero. Il tuo punteggio è l'errore medio su 100 (o più) casi di test casuali. Se scrivi una risposta perfettamente accurata, dovresti ottenere un punteggio di 0; il punteggio più basso vince e i legami verranno interrotti dalla lunghezza del codice.

Casi di prova :

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

In questo caso, l'orbita è perfettamente circolare con periodo 2 * pi, quindi dopo aver girato 159154943 volte, il gatto finisce a circa (0,83789, -0,54584). Questo non è un caso di test su cui verrà testato il codice; se invii una risposta perfettamente accurata, tuttavia, potresti voler testarla su questo.

Lo snippet di seguito genera casi di test aggiuntivi casuali e verrà utilizzato per giudicare i contributi; fammi sapere se c'è un bug con questo:


Il tempo è tespresso in secondi? In tal caso, la velocità sarebbe data in unità al secondo o qualcosa di più piccolo?
R. Kap

@R. Kap Non importa. tviene dato in unità di tempo, qualunque cosa sia, e la velocità utilizzerà la stessa unità. Che si tratti di secondi o ore, la risposta sarà la stessa.
soktinpk,

nearly massless catBene, quale sarebbe la massa esatta del gatto? Dovremmo usare solo 0come valore per la massa di questo gatto?
R. Kap

@R. Kap Sì. Ma è ancora influenzato dalla gravità (di solito, Newton non ha considerato gli oggetti senza massa essere influenzati dalla gravità). Quindi dovremmo considerare che ha una massa arbitrariamente piccola e la tua risposta è in realtà la posizione mentre la massa del gatto va a zero. Il punto principale è che il pianeta stesso non è influenzato dal gatto.
soktinpk,

2
@soktinpk potrebbe essere più semplice dire esplicitamente che il corpo centrale è fisso.
Maltysen,

Risposte:


6

Python 3.5 + NumPy, esatto, 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

Questa è una soluzione esatta, usando una formula che ho progettato sulla base di Jesper Göranssonhis, "Simmetrie del problema di Keplero", 2015 . Usa una ricerca binaria per risolvere l'equazione trascendentale Ax + B cos x + C sin x = D, che non ha una soluzione a forma chiusa.

La funzione prevede che la posizione e la velocità vengano trasmesse come 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])

Che cosa @fa?
R. Kap,

1
È un nuovo operatore in Python 3.5 che NumPy sovraccarica per numpy.dot(moltiplicazione del prodotto / matrice del punto). Vedi PEP 465.
Anders Kaseorg,

È fantastico che sia golfato, ma questa è una sfida al codice, potresti renderlo un po 'più chiaro, ho fatto qualche graffio in Python e posso calcolare l'anomalia, il theta, l'eccentricità, il periodo, ecc., Ma sono bloccato nel determinare il segno di theta e determinare la rotazione dal piano di riferimento xy allo spazio 3d. Tuttavia, questa è davvero roba fantastica
miglia

@miles Poiché i legami sono interrotti dalla lunghezza del codice, ha senso che questo sia golfato.
Mego

È vero, dato che stavo lavorando anche su una soluzione esatta, poiché il generatore di test case crea solo orbite ellittiche
miglia

2

Javascript

Questo è solo per far rotolare la palla, dal momento che nessuno sembra pubblicare le risposte. Ecco un modo molto ingenuo e semplice che può essere migliorato molto:

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:

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

Ehi, va abbastanza bene. Ha un errore di circa 3.333 * 10 ^ (- 6) che non è sufficiente per essere arrotondato per difetto ... è vicino.

Solo per divertimento:

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

Oh bene; quindi non è il migliore.

E su un caso di test casuale dal generatore:

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]

Con un errore di solo circa 0,32305!

Questo può essere migliorato molto usando qualcosa come l'integrazione di Verlet o qualche algoritmo elaborato. In effetti, quegli algoritmi possono persino ottenere punteggi perfetti, nonostante siano simulazioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.