C、315 302バイト
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;}
これは見事なものとはほど遠いものであり、短いものでもありません。長さコンテストに勝つつもりはないので、(理論上の)精度コンテストに勝とうとすることができます!このコードは、おそらくブルートフォースソリューションよりも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
すぐに悲惨なものになります。何らかの近似が必要な場合でも、より堅牢な方法が必要です。
テイラー多項式を入力します。
のD(k0)
すべてD
の微分と同様にの値がわかっている場合、テイラー級数としてk0
書き直すことができますD
。
さて、この式にはたくさんのものがあり、その導関数はかなり扱いにくいものになりますが、今では多項式近似ができました D
!
少しの計算を行うと、前と同じようにのD
導関数を評価することにより、次の2つの導関数を見つけますDi
。
切り捨てと導関数の評価によりD
、次の形式の3次多項式として近似することができます。
A, B, C, D
単なる実数はどこにありますか。
今、この私たちは、最小限に抑えることができます。導関数を取り、それを0に設定すると、次の形式の方程式になります。
計算と置換を行って、次の式を考えますa, b, and c
:
ここで、問題は2次式で与えられる2つの解を与えます。
全体の式はk
書き出すのに大きな負担になるので、こことコードで分割して行います。
高いほどk
常に近似値の最小距離が得られることがわかっているためD
(これについては本当に素晴らしい証拠がありますが、この論文のマージンでは不十分です...)、小さい方を考慮する必要さえありませんソリューション。
最後の問題が残っています。正確を期すために、k0
少なくとも答えが期待される場所の球場にあるから始める必要があります。この目的のために、私のコードは、すべての家のy値の幾何平均を選択します。
フェイルセーフとして、我々は交換し、再び9回全体の問題を繰り返しk0
てk
精度を確保するために、すべての反復で。
繰り返しの回数と実際に必要な微分の数についてはまだ計算していませんが、正確性が確認できるまで慎重に判断することを選択しました。
私と一緒にそれを成し遂げたなら、どうもありがとう!あなたが理解したことを願っています、そして、もしあなたが何かの間違いを見つけたら(その多くはおそらくありますが、私は非常に疲れています)、私に知らせてください!
D
か?ユークリッド?