日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构与算法--贪婪算法2

發布時間:2023/12/4 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法--贪婪算法2 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

近似裝箱問題

  • 解決裝箱問題(bin packing problem)的算法。也可以用貪婪算法來完成

  • 給定N項物品,大小為s1,s2,s3…sn,所有的大小滿足0 < si < 1。問題是要把這些物品裝到最小數目的箱子中,已知每一個箱子容量是1個單位。我們用如下案例,有大小如下的物品:0.2, 0.5, 0.4, 0.7, 0.1, 0.3, 0.8的一列物品最優裝修辦法

  • 有兩種結局方案:

    • 一種聯機裝箱問題(online bin packing problem)。在這種問題中,每一件物品必須放入一個箱子之后才能處理下一個物品
    • 第二中脫機裝箱問題(offline bin packing problem)。在一個脫機裝箱算法中,我們做任何事情都需要等所有的輸入數據全被讀取之后才進行
聯機算法
下項合適算法
  • 算法定義:當處理任何一項物品,我們檢查看他是否能裝進去剛才放入物品的箱子中。 如果能,那么放入該箱子,否則,開辟一個新的箱子。

  • 算法實現簡單,而且還是線性時間下運行

  • 算法實現:

/*** 近似裝箱問題 - 聯機算法 - 脫機算法** @author liaojiamin* @Date:Created in 14:12 2021/1/15*/ public class KnapsackProblem {private static final int MAX_WEIGHT = 10;/*** 隨機生成10 以內的物品數據*/public static int[] getSource(int num) {int[] source = new int[num];Random random = new Random();for (int i = 0; i < num; i++) {source[i] = random.nextInt(10);System.out.println(source[i]);}return source;}/*** 下項適合算法:* 當處理任何一項物品適合,我們堅持是否能裝進去剛才裝物品的同一個箱子* 如果能,就放入,如果不能就重新開一個新箱*/public static int[][] multiKnasack(int[] source ) {int num = source.length;//極端情況,所有獲取都是1 ,都在第一個里面int[][] myPackage = new int[num][num];int[] position = new int[num];int[] weight = new int[num];int packagePosition = 0;for (int i = 0; i < source.length; i++) {if (MAX_WEIGHT - weight[packagePosition] < source[i]) {packagePosition++;}myPackage[packagePosition][position[packagePosition]] = source[i];weight[packagePosition] += source[i];position[packagePosition] += 1;}return myPackage;}public static void main(String[] args) {int[] source = getSource(20);int[][] myPackage = multiKnasack(source);for (int i = 0; i < myPackage.length; i++) {System.out.print("第" + i + "個箱子:");for (int i1 = 0; i1 < myPackage[i].length; i1++) {if (myPackage[i][i1] > 0) {System.out.print(myPackage[i][i1] + ", ");}}System.out.println();}} }
  • 下項合適算法有一個合理的性能保證,但是效果在實踐中很差,因為在不需要開普新箱子的時候他卻會開辟一個新的箱子。
首次合適算法
  • 算法定義:有序掃描箱子,并把新的物品放入足夠能放下他的第一個箱子中。因此只有當前面那些放置物品的箱子已經容納不下當前物品的時候才會開辟新的箱子
  • 算法實現:
/*** 近似裝箱問題 - 聯機算法 - 脫機算法** @author liaojiamin* @Date:Created in 14:12 2021/1/15*/ public class KnapsackProblem {private static final int MAX_WEIGHT = 10;/*** 隨機生成10 以內的物品數據*/public static int[] getSource(int num) {int[] source = new int[num];Random random = new Random();for (int i = 0; i < num; i++) {source[i] = random.nextInt(10);System.out.println(source[i]);}return source;}/*** 首次適合算法:* 義序草廟箱子,并把新的一項物品放入能容納的箱子中* */public static int[][] multiKnasackFirst(int[] source ){int num = source.length;int[][] myPackage = new int[num][num];int[] position = new int[num];int[] weight = new int[num];int packagePosition = 0;for (int i = 0; i < source.length; i++) {boolean isInsert = false;for (int j = 0; j < weight.length; j++) {if(MAX_WEIGHT - weight[j] >= source[i]){isInsert = true;myPackage[j][position[j]] = source[i];weight[j] += source[i];position[j] += 1;break;}}if(!isInsert){packagePosition ++;myPackage[packagePosition][position[packagePosition]] = source[i];weight[packagePosition] += source[i];position[packagePosition] += 1;}}return myPackage;}public static void main(String[] args) {int[] source = getSource(20);int[][] myPackage = multiKnasackFirst(source);for (int i = 0; i < myPackage.length; i++) {System.out.print("第" + i + "個箱子:");for (int i1 = 0; i1 < myPackage[i].length; i1++) {if (myPackage[i][i1] > 0) {System.out.print(myPackage[i][i1] + ", ");}}System.out.println();}} }
  • 首次合適算法時間復雜度達到O(N^2),
最佳適合算法
  • 第三種策略最佳適合裝箱法。改算法不是把一項物品放入所發現的第一個能容納他的箱子,而是放到所有箱子中能容納他的最滿的哪一個箱子中。典型的方法。

  • 算法實現:

package com.ljm.resource.math.greedy;import java.util.Random;/*** 近似裝箱問題 - 聯機算法 - 脫機算法** @author liaojiamin* @Date:Created in 14:12 2021/1/15*/ public class KnapsackProblem {private static final int MAX_WEIGHT = 10;/*** 隨機生成10 以內的物品數據*/public static int[] getSource(int num) {int[] source = new int[num];Random random = new Random();for (int i = 0; i < num; i++) {source[i] = random.nextInt(10);System.out.println(source[i]);}return source;}/*** 最佳合適算法* 將物品放入一個能容納他并且最滿的箱子中* */public static int[][] multiKnasackBest(int[] source ){int num = source.length;int[][] myPackage = new int[num][num];int[] position = new int[num];int[] weight = new int[num];int packagePosition = 0;for (int i = 0; i < source.length; i++) {int maxWeight = -1;int maxWeightId = -1;for (int j = 0; j <= packagePosition; j++) {if(MAX_WEIGHT - weight[j] > source[i]){if(weight[j] > maxWeight){maxWeight = weight[j];maxWeightId = j;}}}if(maxWeightId < 0){packagePosition++;myPackage[packagePosition][position[packagePosition]] = source[i];weight[packagePosition] += source[i];position[packagePosition] += 1;}else {myPackage[maxWeightId][position[maxWeightId]] = source[i];weight[maxWeightId] += source[i];position[maxWeightId] += 1;}}return myPackage;}public static void main(String[] args) {int[] source = getSource(20);int[][] myPackage = multiKnasackBest(source);for (int i = 0; i < myPackage.length; i++) {System.out.print("第" + i + "個箱子:");for (int i1 = 0; i1 < myPackage[i].length; i1++) {if (myPackage[i][i1] > 0) {System.out.print(myPackage[i][i1] + ", ");}}System.out.println();}} }
脫機算法
  • 如果我們能夠觀察全部物品在給出答案,那么我們應該會做的更好。實時確實如此,我們通過徹底的搜索總能找到最優的裝箱方法,因此我們對聯機的情況下進行改進

  • 我們聯機算法中,主要問題在于大項物品裝箱困難,特別是當他們輸入的后期出現的時候,總要新建立一個箱子。我們脫機算法中先將物品按照權重排序,這樣大的在前面。次數我們應用首次適合算法,或者最佳適合算法得到解決,他們分別是首次適合遞減算法最佳適合遞減算法

  • 首次適合遞減算法算法實現:

/*** 近似裝箱問題 - 聯機算法 - 脫機算法** @author liaojiamin* @Date:Created in 14:12 2021/1/15*/ public class KnapsackProblem {private static final int MAX_WEIGHT = 10;/*** 隨機生成10 以內的物品數據*/public static int[] getSource(int num) {int[] source = new int[num];Random random = new Random();for (int i = 0; i < num; i++) {source[i] = random.nextInt(10);System.out.println(source[i]);}return source;}public static int[][] multiknasackDecreasing(int[] source){quickSort(source, 0, source.length - 1);return multiKnasackFirst(source);}/*** 快排從大到小* */public static void quickSort(int[] source, int left, int right){if(left > right){int temp = swap(source, left, right);quickSort(source, left, temp - 1);quickSort(source, temp + 1, right);}}public static int swap(int[] source, int left, int right){if (left < right){int position = source[left];while (left < right){while(left < right && position > source[right]){right --;}if(left < right){source[right] = source[left];left ++;}while (left < right && position < source[left]){left ++;}if(left < right){source[left] = source[right];right --;}}source[left] = position;}return left;}/*** 首次適合算法:* 義序草廟箱子,并把新的一項物品放入能容納的箱子中* */public static int[][] multiKnasackFirst(int[] source ){int num = source.length;int[][] myPackage = new int[num][num];int[] position = new int[num];int[] weight = new int[num];int packagePosition = 0;for (int i = 0; i < source.length; i++) {boolean isInsert = false;for (int j = 0; j < weight.length; j++) {if(MAX_WEIGHT - weight[j] >= source[i]){isInsert = true;myPackage[j][position[j]] = source[i];weight[j] += source[i];position[j] += 1;break;}}if(!isInsert){packagePosition ++;myPackage[packagePosition][position[packagePosition]] = source[i];weight[packagePosition] += source[i];position[packagePosition] += 1;}}return myPackage;}public static void main(String[] args) {int[] source = getSource(20);int[][] myPackage = multiknasackDecreasing(source);for (int i = 0; i < myPackage.length; i++) {System.out.print("第" + i + "個箱子:");for (int i1 = 0; i1 < myPackage[i].length; i1++) {if (myPackage[i][i1] > 0) {System.out.print(myPackage[i][i1] + ", ");}}System.out.println();}} }

上一篇:數據結構與算法–貪婪算法
下一篇:數據結構與算法–分治算法

總結

以上是生活随笔為你收集整理的数据结构与算法--贪婪算法2的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。