import java.util.*;
public class Goldstein {
public static void main(String[]args) {
//f(x)=1*x^3-2*x^1+1*x^0
double[][]f=new double[][] {{1,3},{-2,1},{1,0}};//矩阵f最后映射为函数,每个f[i][0]表示系数,f[i][1]表示次方数
int a=0,b=2;//初始范围
GsMain gm=new GsMain(f,a,b);//根据函数,初始范围创建
gm.t=0.618;//可以修改分割比例
gm.e=0.2;//可以修改精度
double ans=gm.main();//计算,并返回最终结果
gm.visit();//展示计算过程
System.out.println("最终结果:"+ans);
}
}
class GsMain {
double[][]f;//是个n*2矩阵,每列第一个元素是系数,第二个元素是次方
final double T=(-1+Math.pow(5,1.0/2))/2;//默认分割比例
double t;//可以设置比例,例如0.618
double a,b,a0,b0;//a0,b0记录第i次起始结果,a,b记录变化后的结果
double fa,fb;//f(a),f(b)
double e;//精度
final double E=0.2;//默认精度
List<String> list=new ArrayList<>();//存储每次运行结果
public GsMain(double[][]f,double a,double b) {
this.f=f;
this.t=T;
this.a=a;
this.b=b;
a0=a;
b0=b;
e=E;
}
public double main() {
int count=0;
String s=String.format("%4s"+"%6s%6s%6s%6s%14s%6s","次数","a","b","f(a)","f(b)","[a,b]","|b-a|");
list.add(s);
while(true) {
if(++count>20) {
break;
}
a=a0+(1-t)*(b0-a0);
b=a0+t*(b0-a0);
setFab();//设置f(a),f(b)
if(fa<=fb) {
//删除右区间
//以下两行用于记录每轮数据,可忽略
s=String.format("%4d"+"%6.3f%6.3f%6.3f%6.3f[%6.3f,%6.3f]%6.3f",count,a,b,fa,fb,a0,b,b-a0);
list.add(s);
a=a0;//左边界重置
b0=b;//右边界修改
} else {
//删除左区间
//以下两行用于记录每轮数据,可忽略
s=String.format("%4d"+"%6.3f%6.3f%6.3f%6.3f[%6.3f,%6.3f]%6.3f",count,a,b,fa,fb,a,b0,b0-a);
list.add(s);
b=b0;
a0=a;
}
if(Math.abs(b-a)<e) {
break ;
}
}
return (a+b)/2;
}
//根据a,b的值设置fa,fb
void setFab() {
//系数
fa=0;
fb=0;
for(double[]fi:f) {
//次方
fa+=fi[0]*Math.pow(a,fi[1]);
fb+=fi[0]*Math.pow(b,fi[1]);
}
}
void visit() {
for(String s:list) {
System.out.println(s);
}
}
}
|