猫会去哪里?(轨道力学)


16

一只几乎没有质量的猫在(x, y, z)速度点上坠落在太空中(不用担心,有了宇航服和所有东西)(vx, vy, vz)。在该点有一个固定的,无限密集的行星(体积为0),(0, 0, 0)r以加速度吸引远处的物体1/r^2。根据牛顿引力,物体在时间之后会流向何处t

在这种情况下,几乎无质量表示您正在输出的值lim (mass --> 0) <position of cat>。质量受行星重力的影响,但行星不受猫重力的影响。换句话说,中央主体是固定的。

这有点类似于Code Golf:太空船的命运是什么?[浮点版本],但这有所不同,因为它测量的是精度。

您可以实施基于仿真的解决方案,该方案必须在3秒以内运行,或者您可以实施提供准确值的程序(也必须在3秒以内运行)。请参阅下面的评分详情。如果您执行模拟,则不一定要精确,但是由于不准确,您的分数会降低。

输入x y z vx vy vz t,不一定是分别表示x,y,z坐标,分别在x,y和z方向上的速度和时间的整数。可以保证猫的速度严格小于该高度下的逃逸速度。输入可以从任何地方进行,包括函数的参数。对于,该程序必须在我的笔记本电脑上运行不到三秒钟t < 2^30,这意味着,如果您正在运行模拟,则必须相应地调整时间步长。如果您打算为每个测试用例都达到3秒的限制,请确保有一个可调整的参数,该参数可使速度提高更为准确/不太准确,以便我可以在计算机上运行三秒钟。

输出x y z,时间后的位置t

由于两体问题可以完美解决,因此从理论上讲有可能获得完美,正确的答案。

计分:对于任何测试用例,错误定义为输出与“ true”输出之间的距离。真正的输出定义为测试用例代码段生成的输出。如果误差小于10^(-8),则将误差四舍五入为零。您的分数是100个(或更多)随机测试用例的平均错误。如果您写出的答案非常准确,您的分数应为0;否则,您的分数为0。得分最低的获胜者,并且按码长打破平局。

测试用例

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

在这种情况下,轨道是周期为2 * pi的完美圆形,因此,在绕转159154943次后,猫的视线约为(0.83789,-0.54584)。这不是测试您的代码的测试用例;但是,如果您提交的答案非常准确,则可能需要对此进行测试。

下面的代码片段会随机生成其他测试用例,并将用于判断提交的内容;让我知道是否存在错误:


时间t以秒为单位吗?如果是这样,速度会以每秒单位或更低的速度给出吗?
R. Kap

@R。Kap没关系。t以单位时间给出,无论是什么,速度将使用相同的单位。无论是几秒钟还是几小时,答案都是一样的。
soktinpk

nearly massless cat那么,猫的确切体重是多少?我们应该只使用0这只猫的体重作为价值吗?
R. Kap

@R。卡普是的。但是它仍然受重力影响(通常,牛顿并不认为无质量的物体会受到重力影响)。因此,我们应该认为它的质量任意小,而您的答案实际上是猫的质量变为零时的位置。要点是,行星本身完全不受猫的影响。
soktinpk

2
@soktinpk可能更容易明确地表明中心主体是固定的。
Maltysen '16

Answers:


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设计的公式“开普勒问题的对称性”,2015年。它使用二进制搜索来求解先验方程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
它是Python 3.5中的一个新运算符,NumPy对其进行了重载numpy.dot(点乘积/矩阵乘法)。见PEP 465
安德斯Kaseorg

它打高尔夫球很棒,但这是代码挑战,您能否使它更清晰一些,我在Python中做过一些草稿,并且可以计算异常,θ,偏心率,周期等,但是我仍然坚持确定theta的符号,并确定从xy参考平面到3d空间的旋转。尽管如此,这确实是很棒的东西
英里

@miles因为领带是用代码长度打断的,所以打起来很有意义。
Mego

是的,因为我也正在尝试一种精确的解决方案,因为测试用例生成器仅创建椭圆形轨道
英里

2

Java脚本

这只是为了使事情顺利进行,因为似乎没有人发布答案。这是一种非常幼稚的简单方法,可以进行很多改进:

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集成或某些奇特的算法,可以大大改善这一点。实际上,尽管是模拟,但这些算法甚至可能获得满分。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.