고양이는 어디로 갈까요? (궤도 역학)


16

거의 질량이없는 고양이가 (x, y, z)속도 지점에서 우주 공간에 떨어집니다 (우주복과 모든 것을 걱정하지 마십시오) (vx, vy, vz). 점에 고정 된 무한 밀도의 행성 (볼륨 0)이 있으며 가속 (0, 0, 0)을 통해 멀리 떨어진 물체를 끌어 당깁니다 . 뉴턴의 중력에 따르면, 물체는 시간이 지나면 어디로 가나 요?r1/r^2t

이 경우 질량이 거의 없음은의 값을 출력한다는 의미입니다 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.

이체 문제는 완벽하게 해결 될 수 있기 때문에 이론적으로 완벽하고 정답을 얻는 것이 가능합니다.

점수 : 모든 테스트 사례에서 오류는 출력과 "true"출력 사이의 거리로 정의됩니다. 실제 출력은 테스트 케이스 스 니펫이 생성하는 출력으로 정의됩니다. 오류가보다 작 으면 10^(-8)오류는 0으로 내림됩니다. 점수는 100 개 이상의 임의 테스트 사례의 평균 오류입니다. 완벽하게 정확한 답을 쓰면 0 점을 얻습니다. 최저 점수가 이기고 코드 길이에 따라 타이가 끊어집니다.

테스트 사례 :

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

이 경우 궤도는주기 2 * pi로 완벽하게 원형이므로 159154943 회 돌고 나면 고양이는 대략 (0.83789, -0.54584)가됩니다. 이것은 코드가 테스트 될 테스트 케이스가 아닙니다. 그러나 완벽하게 정확한 답변을 제출하면 이에 대한 테스트를 원할 수 있습니다.

아래 스 니펫은 임의의 추가 테스트 사례를 생성하며 제출물을 판단하는 데 사용됩니다. 이것에 버그가 있는지 알려주십시오.


시간 t은 초 단위입니까? 그렇다면 속도가 초당 단위 또는 더 작은 것으로 주어 집니까?
R. Kap

@아르 자형. Kap 그것은 중요하지 않습니다. t어떤 것이 든 단위 시간으로 주어지고 속도는 같은 단위를 사용합니다. 몇 초이든 몇 시간이든 대답은 같습니다.
soktinpk

nearly massless cat음, 고양이의 정확한 질량은 얼마입니까? 0이 고양이의 질량 값으로 만 사용해야 합니까?
R. Kap

@아르 자형. 그렇습니다. 그러나 그것은 여전히 ​​중력의 영향을받습니다 (일반적으로 뉴턴은 질량이없는 물체는 중력의 영향을받는 것으로 간주하지 않았습니다). 그래서 우리는 그것을 임의로 작은 질량을 갖는 것으로 간주해야하며, 당신의 대답은 실제로 고양이의 질량이 0이 될 때의 위치입니다. 요점은 행성 자체가 고양이의 영향을 전혀받지 않는다는 것입니다.
soktinpk

2
@soktinpk 중앙 몸체가 고정되어 있다고 명시 적으로 말하기가 더 쉬울 수 있습니다.
Maltysen

답변:


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

이것은 Jesper Gö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를 참조하십시오.
Anders Kaseorg

골프를 타는 것은 좋지만, 이것은 코드 도전입니다. 조금 더 명확하게 만들 수 있습니까, 파이썬에서 약간의 긁힘이 있었으며, 이상, 세타, 편심, 기간 등을 계산할 수는 있지만 결정에 집중하고 있습니다. 쎄 타의 부호와 xy 참조 평면에서 3d 공간으로의 회전을 결정합니다. 아직도, 이것은 정말 대단한 것입니다.
마일

@miles 코드 길이에 따라 연결이 끊어 지므로 골프를 치는 것이 좋습니다.
Mego

테스트 케이스 생성은 타원 궤도를 생성하기 때문에 내가 너무 정확한 솔루션을 일하고으로 즉, 사실
마일

2

자바 스크립트

아무도 답변을 게시하지 않는 것 같습니다. 다음은 크게 개선 될 수있는 매우 순진하고 간단한 방법입니다.

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.