C, 315302 바이트
t,i;double o,w,h,x,y,k,a,b,c;double g(N,S)double N,S[][2];{for(t=0;t<N;t++)k+=S[t][1];k/=N;for(i=0;i<9;i++){o=w=h=0;for(t=0;t<N;t++)x=S[t][0],y=S[t][1],a=y-k,c=k*k-2*k*y+x*x+y*y,o+=-a/sqrt(x*x+a*a),w+=x*x/pow(c,1.5),h+=3*x*x*a/pow(c,2.5);a=h/2;b=w-h*k;c=o-w*k+a*k*k;k=(-b+sqrt(b*b-4*a*c))/h;}return k;}
이것은 꽤 멀지 않으며 짧지도 않습니다. 나는 길이 콘테스트에서 이기지 못할 것이라고 생각하면서 (이론적) 정확성 콘테스트에서 이길 수 있습니다! 이 코드는 아마도 bruteforce 솔루션보다 1 ~ 2 배 빠르며 약간의 수학적 토모 일에 의존합니다.
g(N,S)
주택 수와 주택 N
배열을 입력으로 받는 함수 를 정의합니다 S[][2]
.
다음은 테스트 사례와 함께 해결되었습니다.
t,i;
double o,w,h,x,y,k,a,b,c;
double g(N,S)double N,S[][2];{
/* Initially, let k hold the geometric mean of given y-values */
for(t=0;t<N;t++)
k+=S[t][1];
k/=N;
/* We approximate 9 times to ensure accuracy */
for(i=0;i<9;i++){
o=w=h=0;
for(t=0;t<N;t++)
/* Here, we are making running totals of partial derivatives */
/* o is the first, w the second, and h the third*/
x=S[t][0],
y=S[t][1],
a=y-k,
c=k*k-2*k*y+x*x+y*y,
o+=-a/sqrt(x*x+a*a),
w+=x*x/pow(c,1.5),
h+=3*x*x*a/pow(c,2.5);
/* We now use these derivatives to find a (hopefully) closer k */
a=h/2;
b=w-h*k;
c=o-w*k+a*k*k;
k=(-b+sqrt(b*b-4*a*c))/h;
}
return k;
}
/* Our testing code */
int main(int argc, char** argv) {
double test[2][2] = {
{5.7, 3.2},
{8.9, 8.1}
};
printf("%.20lf\n", g(2, test));
return 0;
}
어떤 출력 :
5.11301369863013732697
경고 : 완전히 이해하려면 일부 미적분학 지식이 필요할 수 있습니다!
수학에 대해 이야기 해 봅시다.
우리는 원하는 지점 (0, k)
과 집과 의 거리를 알고 있습니다 i
.
그리고 이렇게 총 거리 D
에서 n
다음과 같이 집은 정의 할 수 있습니다 :
우리가하고 싶은 것은에 대해 미분을 취하고 k
동일하게 설정 함으로써이 기능을 최소화 하는 것 0
입니다. 해 봅시다. 우리는 파생 상품이 D
다음과 같이 설명 될 수 있음을 알고 있습니다.
그러나 각각의 첫 부분 미분 Di
은 꽤 나쁩니다 ...
불행히도으로도 n == 2
이러한 파생 상품을 설정 0
하고 해결하는 k
것은 매우 재앙이됩니다. 근사치가 필요하더라도보다 강력한 방법이 필요합니다.
Taylor Polynomials를 입력하십시오.
D(k0)
에서 모든 D
파생 상품 의 가치와 가치를 알고 있다면 Taylor 시리즈로 k0
다시 쓸 수 있습니다 D
.
이제이 공식에는 많은 것들이 들어 있고 그 파생물은 다루기 어려울 수 있지만 이제 다항식 근사값이 D
!
약간의 미적분학을 수행함으로써, 우리 는 이전과 같이 D
의 파생 상품을 평가하여 다음 두 파생 상품을 찾습니다 Di
.
파생 상품을 자르고 평가함으로써, 이제 D
다음과 같은 형태의 3 차 다항식으로 근사 할 수 있습니다 .
A, B, C, D
실수는 어디에 있습니까 ?
지금 이 우리가 최소화 할 수 있습니다. 미분을 취하여 0으로 설정하면 다음과 같은 형식의 방정식으로 끝납니다.
미적분과 대입을 수행하면 다음과 같은 공식이 나옵니다 a, b, and c
.
이제 우리의 문제는 2 차 공식으로 주어진 두 가지 솔루션을 제공합니다.
에 대한 전체 공식은 k
작성하는 데 큰 부담이 될 것이므로 여기와 코드로 조각을 작성합니다.
우리가 높을수록 k
항상 근사 거리가 최소가 된다는 것을 알기 때문에 D
(이 논문의 여백이 포함하기에 충분하지 않다는 사실에 대한 놀라운 증거가 있습니다 ...) 솔루션.
하나의 마지막 문제가 남아 있습니다. 정확한 목적을 위해, k0
적어도 우리가 답을 기대하는 곳의 야구장에서 시작 해야합니다. 이를 위해 내 코드는 모든 집의 y 값에 대한 기하학적 평균을 선택합니다.
A는 페일 세이프 (fail-safe), 우리는 대체, 다시 9 번 전체 문제를 반복 k0
하여 k
정확성을 보장하기 위해, 모든 반복에.
나는 얼마나 많은 반복과 얼마나 많은 파생물이 필요한지에 대한 수학을 수행하지는 않았지만 정확성을 확인할 수있을 때까지주의 측면에서 잘못 선택했습니다.
당신이 나와 함께 그것을 통해 너무 감사합니다! 이해하기를 바랍니다. 실수가 많을 경우 (아마도 많이 피곤합니다) 알려주세요!
D
됩니까? 유클리드?