欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)黃金分割法的示例代碼

 更新時(shí)間:2022年03月15日 10:07:31   作者:別團(tuán)等shy哥發(fā)育  
黃金分割法是一種區(qū)間收縮方法。所謂區(qū)間收縮方法,指的是將含有最優(yōu)解的區(qū)間逐步縮小,直至區(qū)間長(zhǎng)度為零的方法。本文將用Java實(shí)現(xiàn)這一算法,需要的可以參考一下

1、概述

黃金分割法是一種區(qū)間收縮方法。

所謂區(qū)間收縮方法,指的是將含有最優(yōu)解的區(qū)間逐步縮小,直至區(qū)間長(zhǎng)度為零的方法。比如,為求函數(shù)f(x)在區(qū)間[a,b]上的最小值點(diǎn),可在該區(qū)間中任取兩點(diǎn)x1、x2,通過比較函數(shù)f(x)在這兩點(diǎn)的函數(shù)值或者導(dǎo)數(shù)值等,來(lái)決定去掉一部分區(qū)間[a,x1?]或者[x2?,b],從而使搜索區(qū)間長(zhǎng)度變小,如此迭代,直至區(qū)間收縮為一點(diǎn)為止,或區(qū)間長(zhǎng)度小于某給定的精度為止。

對(duì)于區(qū)間[a,b]上的單峰函數(shù)f(x),可以在其中任意選取兩點(diǎn)x1?、x2?,通過比較這兩點(diǎn)的函數(shù)值,就可以將搜索區(qū)間縮小。比如說(shuō),如果f(x1?)<f(x2?),則選取[a1?,b1?]=[a,x2?],如果f(x1?)> f(x2?),則選取[a1?,b1?]=[x1?,b],如果f(x1?)=f(x2),則選取[a1?,b1?]=[x1?,x2?],這樣就得到f(x)的更小的搜索區(qū)間[a1?,b1?],然后根據(jù)這一方法再進(jìn)行劃分,得到一系列搜索區(qū)間滿足

于是對(duì)事先給定的某個(gè)精度ε,當(dāng)

時(shí),可以將f(x)的最小值點(diǎn)近似地取為

單峰函數(shù)與搜索區(qū)間的定義如下:

如何選取x1和x2才能使得算法的效率更高?

這里推導(dǎo)過程不在詳細(xì)討論,直接給出滿足對(duì)稱取點(diǎn)、等比收縮和單點(diǎn)計(jì)算三個(gè)原則的分點(diǎn)。

或者

2、黃金分割法

算法描述如下:

這個(gè)算法非常理想,整個(gè)迭代過程中。除最初計(jì)算分點(diǎn)時(shí)使用過一次乘法外,后邊的分點(diǎn)全部都由加減法完成,并且每次迭代只需計(jì)算一個(gè)分點(diǎn)的函數(shù)值。但是,在實(shí)際應(yīng)用中,該方法存在一定的缺陷。這種缺陷主要來(lái)源于無(wú)理數(shù)(-1+√5)/2的取值。這里我們只取了小數(shù)點(diǎn)后三位數(shù)。因而有一定誤差,所以在迭代過程中,經(jīng)過多次累計(jì),誤差就會(huì)很大,從而導(dǎo)致最終選取的兩點(diǎn)并不一定是我們所期望的那兩點(diǎn),事實(shí)上,常常發(fā)生x2小于x1的情形。

為避免這種情況的出現(xiàn),我們也可以通過將無(wú)理數(shù)(-1+√5)/2小數(shù)點(diǎn)后面的位數(shù)提高來(lái)避免算法的這一缺陷。不過這樣做的效果未必很好。因?yàn)槲覀儾恢涝谒惴ㄖ械降滓?jīng)過多少次迭代,當(dāng)?shù)螖?shù)很大時(shí),這種做法依然是不能奏效的。因此,我們?cè)诔绦蛑忻看斡?jì)算分點(diǎn)時(shí)不得不根據(jù)算法原理,使用一次乘法,即第二個(gè)分點(diǎn)不用加減法產(chǎn)生,而直接用乘法計(jì)算得出。由此即可避免累計(jì)誤差所帶來(lái)的缺陷。我們?nèi)约僭O(shè)f(x)是區(qū)間[a,b]上的單峰函數(shù)。修改后的黃金分割法的計(jì)算框圖如下圖所示。

3、修改后的黃金分割算法

修改后的黃金分割算法如下:

4、編程實(shí)現(xiàn)修改后的黃金分割算法

用黃金分割法求函數(shù) f(x)=x³-12x-11在區(qū)間[0,10]上的最小值點(diǎn),取ε=0.01。

import java.math.BigDecimal;

/**
 * 黃金分割法測(cè)試
 */
public class GoldenCut {
    public static final BigDecimal C=new BigDecimal("0.01");

    public static  BigDecimal end=null;

    /**
     *x^3-12x-11
     * @param x 輸入?yún)?shù)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;
    }
    //輸出最優(yōu)解
    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("迭代區(qū)間如下:");
        int count=0;    //迭代次數(shù)
        while(!OK(a,b)){//只要不滿足精度就一直迭代
            System.out.println("["+a+"\t,\t"+b+"]");
            count++;    //迭代次數(shù)+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("迭代結(jié)束,迭代次數(shù)"+count);
    }
    public static void main(String[] args) {
        BigDecimal a=new BigDecimal("0");
        BigDecimal b=new BigDecimal("10");

        goldenTest1(a,b);
        System.out.println("最優(yōu)解為x*="+end);
        System.out.println("f(x*)="+ComputeFx(end));
    }
}

由運(yùn)行結(jié)果可以看到,迭代次數(shù)15次,最優(yōu)解為x*=2.0009942948,f(x*)=-26.9999940673。迭代區(qū)間如下:

可以證明,黃金分割法是線性收斂的。

到此這篇關(guān)于Java實(shí)現(xiàn)黃金分割法的示例代碼的文章就介紹到這了,更多相關(guān)Java黃金分割法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)駝峰下劃線互轉(zhuǎn)的使用示例

    Java實(shí)現(xiàn)駝峰下劃線互轉(zhuǎn)的使用示例

    駝峰和下劃線互轉(zhuǎn)場(chǎng)景是在不同命名規(guī)范的情況下,需要進(jìn)行字段名稱的轉(zhuǎn)換,本文就來(lái)介紹一下Java實(shí)現(xiàn)駝峰下劃線互轉(zhuǎn)的使用示例,感興趣的可以了解一下
    2023-12-12
  • Mybatis-plus使用注解 @TableField(exist = false)

    Mybatis-plus使用注解 @TableField(exist = false)

    這篇文章主要介紹了Mybatis-plus使用注解 @TableField(exist = false),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • SpringBoot中使用?POI的示例代碼

    SpringBoot中使用?POI的示例代碼

    這篇文章主要介紹了SpringBoot中使用POI的實(shí)例詳解,包括引入poi的jar包和創(chuàng)建excel的實(shí)例代碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • springboot-dubbo cannot be cast to問題及解決

    springboot-dubbo cannot be cast to問題及解決

    這篇文章主要介紹了springboot-dubbo cannot be cast to問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 編碼實(shí)現(xiàn)從無(wú)序鏈表中移除重復(fù)項(xiàng)(C和JAVA實(shí)例)

    編碼實(shí)現(xiàn)從無(wú)序鏈表中移除重復(fù)項(xiàng)(C和JAVA實(shí)例)

    如果不能使用臨時(shí)緩存,你怎么實(shí)現(xiàn)無(wú)序鏈表中移除重復(fù)項(xiàng)(?C和JAVA實(shí)例無(wú)序鏈表中移除重復(fù)項(xiàng)。
    2013-10-10
  • java實(shí)現(xiàn)會(huì)反彈的小球示例

    java實(shí)現(xiàn)會(huì)反彈的小球示例

    這篇文章主要介紹了java實(shí)現(xiàn)會(huì)反彈的小球示例,需要的朋友可以參考下
    2014-04-04
  • java線程之join方法的使用介紹

    java線程之join方法的使用介紹

    本篇文章介紹了,java線程之join方法的使用分析,需要的朋友參考下
    2013-05-05
  • Java tomcat中的類加載器和安全機(jī)制你了解嗎

    Java tomcat中的類加載器和安全機(jī)制你了解嗎

    這篇文章主要介紹了Tomcat 類加載器的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下,希望能夠給你帶來(lái)幫助
    2021-09-09
  • javaDSL簡(jiǎn)單實(shí)現(xiàn)示例分享

    javaDSL簡(jiǎn)單實(shí)現(xiàn)示例分享

    DSL領(lǐng)域定義語(yǔ)言,用來(lái)描述特定領(lǐng)域的特定表達(dá)。比如畫圖從起點(diǎn)到終點(diǎn);路由中的從A到B。這是關(guān)于畫圖的一個(gè)簡(jiǎn)單實(shí)現(xiàn)
    2014-03-03
  • BigDecimal的toString()、toPlainString()和toEngineeringString()區(qū)別及用法詳解

    BigDecimal的toString()、toPlainString()和toEngineeringString()區(qū)

    使用BigDecimal進(jìn)行打印的時(shí)候,經(jīng)常會(huì)對(duì)BigDecimal提供的三個(gè)toString方法感到好奇,以下整理3個(gè)toString方法的區(qū)別及用法,需要的朋友可以參考下
    2023-08-08

最新評(píng)論