import java.math.BigDecimal;
/**
* 黄金分割法测试
*/
public class GoldenCut {
public static final BigDecimal C=new BigDecimal("0.01");
public static BigDecimal end=null;
/**
*x^3-12x-11
* @param x 输入参数x
* @return x^3-12x-11
*/
public static BigDecimal ComputeFx(BigDecimal x){
return x.pow(3).subtract(new BigDecimal("12").multiply(x)).subtract(new BigDecimal("11"))
.setScale(10,BigDecimal.ROUND_HALF_EVEN);
}
/**
* a+0.382*(b-a)
* @param a
* @param b
* @return a+0.382*(b-a)
*/
public static BigDecimal Compute382(BigDecimal a,BigDecimal b){
return a.add(new BigDecimal("0.382").multiply(b.subtract(a)))
.setScale(10,BigDecimal.ROUND_HALF_EVEN);
}
/**
* a+0.618(b-a)
* @param a
* @param b
* @return
*/
public static BigDecimal Compute618(BigDecimal a,BigDecimal b){
return a.add(new BigDecimal("0.618").multiply(b.subtract(a)))
.setScale(10,BigDecimal.ROUND_HALF_EVEN);
}
/**
* a+b-x1
* @param a
* @param b
* @param x1
* @return
*/
public static BigDecimal Subtractabx1(BigDecimal a,BigDecimal b,BigDecimal x1){
return a.add(b).subtract(x1)
.setScale(10,BigDecimal.ROUND_HALF_EVEN);
}
//判断是否满足精度 b-a<C?
public static boolean OK(BigDecimal a,BigDecimal b){
return b.subtract(a).compareTo(C) < 0;
}
//输出最优解
public static BigDecimal Success(BigDecimal a, BigDecimal b){
return (a.add(b)).divide(new BigDecimal("2"))
.setScale(10,BigDecimal.ROUND_HALF_EVEN);
}
//修改后的黄金分割法
public static void goldenTest1(BigDecimal a,BigDecimal b){
System.out.println("初始化");
BigDecimal x1=Compute382(a,b);
BigDecimal x2=Subtractabx1(a,b,x1);
BigDecimal f1=ComputeFx(x1);
BigDecimal f2=ComputeFx(x2);
System.out.println("x1="+x1);
System.out.println("x2="+x2);
System.out.println("f1="+f1);
System.out.println("f2="+f2);
System.out.println("迭代区间如下:");
int count=0; //迭代次数
while(!OK(a,b)){//只要不满足精度就一直迭代
System.out.println("["+a+"\t,\t"+b+"]");
count++; //迭代次数+1
if(f1.compareTo(f2)==1){//f1>f2
a=x1;
if(OK(a,b)){ //精度判断
end = Success(a, b);
break;
}else{
f1=f2;
x1=x2;
x2=Compute618(a,b);
f2=ComputeFx(x2);
}
}else{
b=x2;
if(OK(a,b)){
end = Success(a, b);
break;
}else{
f2=f1;
x2=x1;
x1=Compute382(a,b);
f1=ComputeFx(x1);
}
}
}
System.out.println("迭代结束,迭代次数"+count);
}
public static void main(String[] args) {
BigDecimal a=new BigDecimal("0");
BigDecimal b=new BigDecimal("10");
goldenTest1(a,b);
System.out.println("最优解为x*="+end);
System.out.println("f(x*)="+ComputeFx(end));
}
}