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

Java使用動態(tài)規(guī)劃算法思想解決背包問題

 更新時間:2022年04月29日 10:05:46   作者:LNORA  
背包問題(Knapsack problem)是一種組合優(yōu)化的NP完全問題。問題可以描述為:給定一組物品,每種物品都有自己的重量和價格,在限定的總重量內,我們如何選擇,才能使得物品的總價格最高

動態(tài)規(guī)劃算法

動態(tài)規(guī)劃算法的思想

動態(tài)規(guī)劃算法處理的對象是多階段復雜決策問題,動態(tài)規(guī)劃算法和分治算法類似,其基本思想也是將待求解問題分解成若干個子問題(階段),然后分別求解各個子問題(階段),最后將子問題的解組合起來得到原問題的解,但是與分治算法不同的是,子問題往往不是相互獨立的,而是相互聯(lián)系又相互區(qū)別的

動態(tài)規(guī)劃算法問題求解的目標是獲取導致問題最優(yōu)解的最優(yōu)決策序列(最優(yōu)策略)。對于一個決策序列,可以用一個數(shù)值函數(shù)(目標函數(shù))衡量這個決策的優(yōu)劣。

最優(yōu)性原理

動態(tài)規(guī)劃算法的最優(yōu)性原理:一個最優(yōu)決策序列具有這樣的性質,不論初始狀態(tài)和第一步?jīng)Q策如何,對前面的決策所形成的狀態(tài)而言,其余的決策必須按照前一次決策所產生的新狀態(tài)構成一個最優(yōu)決策序列。

最優(yōu)性原理體現(xiàn)為問題的最優(yōu)子結構特性,對于一個問題,如果能從較小規(guī)模的子問題的最優(yōu)解求得較大規(guī)模同類子問題的最優(yōu)解,最終得到給定問題的最優(yōu)解,也就是問題的最優(yōu)解中所包含的子問題的最優(yōu)解,這種性質被稱為最優(yōu)子結構性質。最優(yōu)子結構特性使得在從較小問題的解構造較大問題的解時,只需考慮子問題的最優(yōu)解,然后以自底向上的方式遞歸地從子問題的最優(yōu)解逐步構造出整個問題的最優(yōu)解,它保證了原問題的最優(yōu)解可以通過求解子問題的最優(yōu)解來獲得,最優(yōu)子結構的特性是動態(tài)規(guī)劃算法求解問題的必要條件。

動態(tài)規(guī)劃算法的三大特點

  • 如果求解的問題滿足最優(yōu)性原理,則說明用動態(tài)規(guī)劃算法有可能解決該問題,在分析問題的最優(yōu)子結構時,所使用的方法具有普遍性。要注意一個問題可以有多種方式刻畫它的最優(yōu)子結構,有些表示方法的求解速度更快(空間占用少,問題的維度低)。
  • 遞歸定義最優(yōu)解決方案。動態(tài)規(guī)劃的每一步?jīng)Q策都依賴于子問題的解,動態(tài)規(guī)劃算法求解最優(yōu)化問題的步驟為:找出最優(yōu)解的結構,具體來說就是看這個問題是否滿足最優(yōu)子結構特性;其次遞歸定義一個最優(yōu)解的值,即構造原問題和子問題之間的遞歸方程,原問題的最優(yōu)解可以通過子問題的最優(yōu)解獲得。
  • 以自底向上的方式計算出最優(yōu)解的值(最優(yōu)解的目標函數(shù)的值)。對子問題的分解是基于原問題的分解的基礎之上進行的,而且這些子問題的分解過程是相互獨立的。在對原問題分解的過程中,會出現(xiàn)大量的共享重疊子問題,為了避免對大量重疊子問題的重復計算,一般動態(tài)規(guī)劃算法從自底向上開始計算,對每一個問題只解一次,并且保存求解子問題的最優(yōu)值,當再需要求解這個子問題的時候,可以用常數(shù)時間查看一下結果,而不是再遞歸的去求解每一個問題的解,因此提高了動態(tài)規(guī)劃算法的效率。

動態(tài)規(guī)劃算法中的0/1背包問題

0/1背包問題的規(guī)則是不允許該物品進行拆分,即只有把物品放入和不放入兩個基本狀態(tài),要使用動態(tài)規(guī)劃算法求解決如何放物品才可以是背包中的物品的總價值達到最高。

示例

有一個載重為10的背包,現(xiàn)有4類物品,每類物品的重量分別為(w0,w1,w2,w3)=(2,3,4,7),它們的價值分別為(p0,p1,p2,p3)=(1,3,5,9)。試問如何裝載能夠使背包容納物品的價值最大。

package 算法設計與分析;
 import java.util.Arrays;
 import java.util.Scanner;
 //m表示的是背包的容量,a表示有多少種類的物品,數(shù)組w用與存放每類物品的重量,數(shù)組val用于存放每類物品的價值
 public class my {
     public static void main(String[] args) {
         Scanner scanner = new Scanner(System.in);
         System.out.print("請輸入背包的容量:");
         int m = scanner.nextInt();
         Scanner inScanner = new Scanner(System.in);
         System.out.print("請輸入物品的個數(shù):");
         int a = inScanner.nextInt();
         int[] w = new int[a + 1];
         System.out.print("請輸入物品的重量:" + " ");
         for (int i = 1; i <= a; i++) {
             w[i] = inScanner.nextInt();
         }
         int[] val = new int[a+ 1];
         System.out.print("請輸入物品的價值:" + " ");
         for (int i = 1; i <= a; i++) {
             val[i] = inScanner.nextInt();
         }
         int n = val.length;
         int[][] path = new int[n +1][m+1 ];
         //創(chuàng)建二維數(shù)組
         //v[i][j]:表示在前i個物品中能夠裝入容量為j的背包中的最大價值
         int[][] v = new int[n +1][m + 1];
         //初始化第一行和第一列
         for (int i = 0; i < v.length; i++) {//v.length:獲取二維數(shù)組的行數(shù)
             v[i][0] = 0;//將第一列設置為0
         }
         for (int i = 0; i < v[0].length; i++) {//v[0].length:獲取二維數(shù)組的列數(shù)
             v[0][i] = 0;//將第一行設置為0
         }
         for (int i = 1; i < v.length; i++) {//int i = 1 不處理第一行
             for (int j = 1; j < v[0].length; j++) {//int j = 1 不處理第一列
                 if (w[i - 1] > j) {
                     v[i][j] = v[i - 1][j];
                 } else {
                     if (v[i - 1][j] < (val[i - 1] + v[i - 1][j - w[i - 1]])) {
                         v[i][j] = val[i - 1] + v[i - 1][j - w[i - 1]];
                         //把當前情況記錄到path
                         path[i][j] = 1;
                     } else {
                         v[i][j] = v[i - 1][j];
                     }
                 }
             }
         }
         //輸出二維數(shù)組:
         for (int[] ints : v) {
             System.out.println(Arrays.toString(ints));
         }
         //輸出最后我們是放入的那些商品
         int i = path.length - 1;//行的最大下標
         int j = path[0].length - 1;//列的最大下標
         while (i > 0 && j > 0) {//從path的最后開始找
             if (path[i][j] == 1) {
                 System.out.printf("第%d個商品放入背包\n", i-1);
                 j -= w[i - 1];
             }
             i--;
         }
     }
 }

輸入一個背包容量為10,里面有4類物品,物品的重量分別為2,3,4,7,物品的價值分別為1,3,5,9

 結果 

動態(tài)規(guī)劃算法的優(yōu)點

若要解一個給定問題,我們需要解其不同部分(即子問題),再合并子問題的解以得出原問題的解。 通常許多子問題非常相似,為此動態(tài)規(guī)劃法試圖僅僅解決每個子問題一次,從而減少計算量: 一旦某個給定子問題的解已經(jīng)算出,則將其記憶化存儲,以便下次需要同一個子問題解之時直接查表。 這種做法在重復子問題的數(shù)目關于輸入的規(guī)模呈指數(shù)增長時特別有用。

小結

以上就是針對動態(tài)規(guī)劃算法的詳細分析,利用動態(tài)規(guī)劃算法可以避免重復計算多次子問題,提高效率,使計算機的性能更好!

到此這篇關于Java使用動態(tài)規(guī)劃算法思想解決背包問題的文章就介紹到這了,更多相關Java背包問題內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳談Enumeration接口和Iterator接口的區(qū)別

    詳談Enumeration接口和Iterator接口的區(qū)別

    下面小編就為大家?guī)硪黄斦凟numeration接口和Iterator接口的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • mybatis簡單resultMap使用詳解

    mybatis簡單resultMap使用詳解

    resultMap是Mybatis最強大的元素,它可以將查詢到的復雜數(shù)據(jù)(比如查詢到幾個表中數(shù)據(jù))映射到一個結果集當中。這篇文章主要介紹了mybatis簡單resultMap使用詳解的相關資料,需要的朋友可以參考下
    2021-04-04
  • Java基礎知識精通數(shù)組的內存分析

    Java基礎知識精通數(shù)組的內存分析

    數(shù)組對于每一門編程語言來說都是重要的數(shù)據(jù)結構之一,當然不同語言對數(shù)組的實現(xiàn)及處理也不盡相同。Java?語言中提供的數(shù)組是用來存儲固定大小的同類型元素
    2022-04-04
  • java開發(fā)ServiceLoader實現(xiàn)機制及SPI應用

    java開發(fā)ServiceLoader實現(xiàn)機制及SPI應用

    這篇文章主要為大家介紹了java開發(fā)ServiceLoader實現(xiàn)機制及SPI應用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • Kotlin 基礎教程之異常

    Kotlin 基礎教程之異常

    這篇文章主要介紹了Kotlin 基礎教程之異常的相關資料,需要的朋友可以參考下
    2017-06-06
  • 一篇文章帶你搞定 springsecurity基于數(shù)據(jù)庫的認證(springsecurity整合mybatis)

    一篇文章帶你搞定 springsecurity基于數(shù)據(jù)庫的認證(springsecurity整合mybatis)

    這篇文章主要介紹了一篇文章帶你搞定 springsecurity基于數(shù)據(jù)庫的認證(springsecurity整合mybatis),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • Spring中數(shù)據(jù)訪問對象Data Access Object的介紹

    Spring中數(shù)據(jù)訪問對象Data Access Object的介紹

    今天小編就為大家分享一篇關于Spring中數(shù)據(jù)訪問對象Data Access Object的介紹,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Java基本數(shù)據(jù)類型與封裝類型詳解(int和Integer區(qū)別)

    Java基本數(shù)據(jù)類型與封裝類型詳解(int和Integer區(qū)別)

    這篇文章主要介紹了Java基本數(shù)據(jù)類型與封裝類型詳解(int和Integer區(qū)別) ,需要的朋友可以參考下
    2017-02-02
  • Java數(shù)組隊列概念與用法實例分析

    Java數(shù)組隊列概念與用法實例分析

    這篇文章主要介紹了Java數(shù)組隊列概念與用法,結合實例形式分析了Java數(shù)組隊列相關概念、原理、用法及操作注意事項,需要的朋友可以參考下
    2020-03-03
  • SpringMVC上傳圖片代碼實例

    SpringMVC上傳圖片代碼實例

    這篇文章主要介紹了SpringMVC上傳圖片代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08

最新評論