アルゴリズム分析
未知と仮定することができる\(D \)の各点を球の中心までの距離を表し、未知の提供(B_1、B_2、\ cdots \を 、B_N \) 球の中心の座標を表します。
私たちは、簡単に取得することができます(N + 1 \)\方程式:
\ [D ^ 2 = \ sum_ {i = 1} ^ {N(a_iを-b_i)^ 2} \]
二次項を発生することが判明し、ここで明らかに変換する方法は、次項を置き換えるために使用することができませんでした。
私たちは、この式を開始しました:
\ [D ^ 2 = \ sum_ {i = 1} ^ nは{a_iを^ 2} + \ sum_ {i = 1} ^ {N b_i ^ 2} +2回\ \ sum_ {i = 1} ^ {N a_ib_i } \]
不明同じ側に書いています:
\ [ - 2 \回\ sum_ {i = 1} ^ nは{a_ib_i} - \ sum_ {i = 1} ^ nは{b_i ^ 2} + D ^ 2 = \ sum_ {i = 1} ^ nは{a_iを^ 2} \]
その後、我々は各方程式、二次係数のためにすべて同じであるので、我々はキャンセル用語はオルト検討し、次のよう求め、ことがわかります\(N- \) :方程式を
\ [ - 2 \回\ sum_ {i = 1} ^ N {(a_iを-A_ {I-1})b_i} = \ sum_ {i = 1} ^ nは{a_iを^ 2-A_ {I-1} ^ 2} \]
これはガウスの消去法の条件に沿ったものである、あなたが直接行うことができます。
コードの実装
#include<bits/stdc++.h>
using namespace std;
#define maxn 105
int n;
double a[maxn][maxn],b[maxn][maxn],x[maxn][maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n+1;i++){
for(int j=1;j<=n;j++){
scanf("%lf",&x[i][j]);
}
}
for(int i=1;i<=n+1;i++){
for(int j=1;j<=n;j++){
b[i][j]=(-2)*x[i][j];
}
for(int j=1;j<=n;j++)b[i][n+1]-=(x[i][j]*x[i][j]);
}
for(int i=1;i<=n+1;i++){
for(int j=2;j<=n+1;j++){
a[i][j]=b[i][j]-b[i-1][j];
}
}
for(int i=1;i<=n;i++){
int p=0;
for(int j=i;j<=n;j++){if(a[j][i]){p=j;break;}}
if(!p)continue;
for(int j=1;j<=n+1;j++)swap(a[i][j],a[p][j]);
double k=a[i][i];
for(int j=1;j<=n+1;j++)a[i][j]/=k;
for(int j=1;j<=n;j++){
if(i==j)continue;
double kk=a[j][i];
for(int l=1;l<=n+1;l++)a[j][l]-=kk*a[i][l];
}
}
for(int i=1;i<=n;i++)printf("%.3lf ",a[i][n+1]);
return 0;
}