猫はどこへ行くの?(軌道力学)


16

ほぼ無質量の猫が(x, y, z)、速度のある点で宇宙船に落とされます(宇宙服とすべてで心配しないでください)(vx, vy, vz)。ポイントには固定された無限に密集した惑星(体積0)があり、加速(0, 0, 0)して距離rを置いてオブジェクトを引き付けます1/r^2。ニュートン重力によると、オブジェクトは時間の経過後にどこに行くのtでしょうか?

この場合、ほとんど質量がないということは、の値を出力していることを意味しますlim (mass --> 0) <position of cat>。質量は惑星の重力の影響を受けますが、惑星は猫の重力の影響を受けません。つまり、中心体は固定されています。

これは、コードゴルフに多少似ています:宇宙船の運命は?[浮動小数点バージョン]ですが、これは精度を測定しているため、異なります。

3秒未満で実行する必要があるシミュレーションに基づいたソリューションを実装することも、正確な値を提供するプログラムを実装することもできます(3秒未満で実行する必要があります)。以下のスコアリングの詳細を参照してください。シミュレーションを実装する場合、正確である必要はありませんが、不正確なためにスコアが低くなります。

入力x y z vx vy vz t、必ずしもx、y、z座標、x、y、およびz方向の速度と時間を表す整数ではありません。猫の速度が厳密にその高度での脱出速度よりも遅いことが保証されています。関数へのパラメーターを含め、どこからでも入力を取得できます。プログラムは、私のラップトップ上で3秒未満で実行する必要がありますt < 2^30。つまり、シミュレーションを実行している場合は、それに応じてタイムステップを調整する必要があります。すべてのテストケースで3秒の制限に達することを計画している場合は、コンピューターで3秒で実行できるように、速度のゲインをより正確に/より正確に調整できる調整可能なパラメーターがあることを確認してください。

出力x y z時間後の位置t

二体問題は完全に解決できるので、理論的には完全で正しい答えを得ることができます。

スコアリング:すべてのテストケースで、エラーは出力と「真の」出力の間の距離として定義されます。真の出力は、テストケーススニペットが生成するものと定義されています。エラーが未満の場合、エラーは10^(-8)ゼロに切り捨てられます。スコアは、100(またはそれ以上)のランダムテストケースの平均誤差です。完全に正確な答えを書いた場合、スコア0を取得する必要があります。最も低いスコアが勝ち、コードの長さによって関係が壊れます。

テストケース

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

この場合、軌道は周期2 * piで完全に円形であるため、159154943回旋回した後、猫はおよそ(0.83789、-0.54584)になります。これは、コードがテストされるテストケースではありません。ただし、完全に正確な回答を提出する場合は、これでテストすることをお勧めします。

以下のスニペットは、ランダムな追加のテストケースを生成し、提出を判断するために使用されます。これにバグがあるかどうか教えてください:


時間tは秒単位で与えられますか?もしそうなら、速度は1秒あたりの単位で与えられますか、それとももっと小さいものですか?
R.カップ

@R。Kap関係ありません。tそれが何であれ、単位時間で与えられ、速度は同じ単位を使用します。秒単位でも時間単位でも、答えは同じです。
soktinpk

nearly massless catさて、猫の正確な質量は何ですか?0この猫の質量の値として使用するだけですか?
R. Kap

@R。はい。しかし、依然として重力の影響を受けます(通常、ニュートンは、質量のないオブジェクトが重力の影響を受けるとは考えていませんでした)。したがって、任意に小さな質量を持つと考える必要があります。実際の答えは、猫の質量がゼロになる位置です。主なポイントは、惑星自体が猫の影響をまったく受けないということです。
soktinpk

2
@soktinpkでは、中心体が固定されていると明示的に言う方が簡単かもしれません。
マルティセン16

回答:


6

Python 3.5 + NumPy、正確、186バイト

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

これは、JesperGöranssonhis、「Symmetries of the Kepler problem」、2015年に基づいて設計された式Iを使用した正確なソリューションです。バイナリ検索を使用して、超越方程式Ax + B cos x + C sin x = Dを解きます。これには閉形式の解はありません。

この関数は、位置と速度が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])

何をし@ますか?
R. Kap

1
NumPyがオーバーロードするのはPython 3.5の新しい演算子ですnumpy.dot(ドット積/行列乗算)。PEP 465を参照してください
アンダースKaseorg

ゴルフをするのは素晴らしいことですが、これはコードチャレンジです。もう少しわかりやすくしてください。Pythonでスクラッチワークをいくつか行い、異常、シータ、離心率、周期などを計算できますが、シータの符号とxy基準面から3d空間への回転を決定します。それでも、これは本当に素晴らしいものです
マイル

@milesタイはコードの長さによって分割されるため、これをゴルフにかけるのは理にかなっています。
メゴ

私はあまりにも厳密解に取り組んでいたように、テストケース・ジェネレータのみ楕円軌道を作成しますので、それは、本当だ
マイル

2

Javascript

誰も答えを投稿していないようですので、これは単にボールを転がすためです。これは非常に素朴で簡単に改善できる方法です。

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

テスト:

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

ねえ、それはかなり良いです。約3.333 * 10 ^(-6)のエラーがあり、切り捨てるには不十分です...近いです。

楽しみのためだけに:

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

しかたがない; それは最高ではありません。

そして、ジェネレーターからのランダムなテストケースで:

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]

わずか0.32305の誤差で!

これは、Verlet統合または何らかの派手なアルゴリズムのようなものを使用することにより、大幅に改善できます。実際、これらのアルゴリズムは、シミュレーションであっても完全なスコアを取得する場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.