首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

关于双肩包算法由递归转迭代实现

2013-02-17 
关于背包算法由递归转迭代实现背包算法应用很广泛,也是经典算法了,最近由于项目需要,使用了此算法。查找到

关于背包算法由递归转迭代实现

背包算法应用很广泛,也是经典算法了,最近由于项目需要,使用了此算法。

查找到以下博客: http://puffsun.iteye.com/blog/1286331

这个写的简单易懂,估计大家一看就明白了,使用了递归算法,开始余量等于总数,容易每次循环,进行操作,直到余量等于0为止,但是还有个小Bug,打印的时候,中间有大于的时候需要跳过的,当然,他只求是否有解,我是需要答案,也不算是Bug吧。

原算法如下:

     * @author Sun Kui       */      public class Knapsack {          public static void main(final String... args) {              int[] arr = new int[5];              arr[0] = 11;              arr[1] = 8;              arr[2] = 7;              arr[3] = 5;              arr[4] = 3;              Knapsack k = new Knapsack();              System.out.println(k.knapsack(arr, 0, 20, 20));          }                /**          *@param arr    all of items in knapsack          *@param start  the start item to be put into the knapsack          *@param left   the remaining capacity of knapsack          *@param sum    capacity of knapsack          */          public boolean knapsack(int[] arr, int start, int left, int sum) {                    if (arr.length == 0) {                  return false;              }                    // start from the next item in original array              if (start == arr.length) {                  int[] tempArr = new int[arr.length - 1];                  for (int i = 0; i < tempArr.length; i++) {                      tempArr[i] = arr[i + 1];                  }                  return knapsack(tempArr, 0, sum, sum);              } else if (arr[start] > left) {                  return knapsack(arr, start + 1, left, sum);              } else if (arr[start] == left) {                  for (int i = 0; i < start + 1; i++) {                      // print the answer out                      System.out.print(arr[i] + "\t");                  }                  System.out.println();                  return true;              } else {                  return knapsack(arr, start + 1, left - arr[start], sum);              }          }      }  

?

?

我修改后如下,?

?

public class Knapsack {public static void main(final String... args) {//int a=5000;//int[] arr = new int[a];//for(int i=0;i<a;i++){//arr[i]=1;//}//Knapsack k = new Knapsack();//k.knapsack(arr, 0, a, a);//System.out.println(k.knapsack(arr, 0, a, a));int[] arr = new int[5];arr[0]=11;arr[1]=5;arr[2]=5;arr[3]=3;arr[4]=1;Knapsack k = new Knapsack();k.knapsack(arr, 0, 20, 20);System.out.println(k.knapsack(arr, 0, 20, 20));}/** * @param arr *            all of items in knapsack * @param start *            the start item to be put into the knapsack * @param left *            the remaining capacity of knapsack * @param sum *            capacity of knapsack */public boolean knapsack(int[] arr, int start, int left, int sum) {if(start%500==0){System.gc();}if (arr.length == 0) {return false;}// start from the next item in original arrayif (start == arr.length) {int[] tempArr = new int[arr.length - 1];for (int i = 0; i < tempArr.length; i++) {tempArr[i] = arr[i + 1];}return knapsack(tempArr, 0, sum, sum);} else if (arr[start] > left) {arr[start]=0;return knapsack(arr, start + 1, left, sum);} else if (arr[start] == left) {for (int i = 0; i < start + 1; i++) {// print the answer outSystem.out.print(arr[i] + "\t");}System.out.println();return true;} else {return knapsack(arr, start + 1, left - arr[start], sum);}}}

?

请查看注释,如果我有超过5千的数据量需要使用此算法,则会抛出异常:StackOverflowError

当然,网上有调用gc的,有调JVM内存大小的,但这都不能解决问题,无意中,我看到一句话:

所有递归都是可以用迭代实现的

?

我就感觉有救了,今天被这个事情折腾的,数据都做不下去了,谢谢这位仁兄,我用迭代实现了如下,不知道有没有Bug,不过没时间测试了,先搞上去吧,2单数据已经无法做了。

?

import java.util.ArrayList;/** * @author  xy792 */public class CopyOfKnapsack {public static void main(final String... args) {//int a = 100000;//int[] arr = new int[a];//for (int i = 0; i < a; i++) {//arr[i] = 1;//}int[] arr = new int[5];arr[0]=12;arr[1]=11;arr[2]=5;arr[3]=2;arr[4]=2;CopyOfKnapsack k = new CopyOfKnapsack(); System.out.println(k.knapsack(arr, 0, 20, 20));}/** * @param arr *            all of items in knapsack * @param start *            the start item to be put into the knapsack * @param left *            the remaining capacity of knapsack * @param sum *            capacity of knapsack */public ArrayList<Integer> knapsack(int[] arr, int start, int left, int sum) {ArrayList<Integer> list = new ArrayList<Integer>();if (arr.length == 0) {return list;}int end = arr.length + 1;while (start < end) {if (start == arr.length) {start = 0;int[] tempArr = new int[arr.length - 1];for (int i = 0; i < tempArr.length; i++) {tempArr[i] = arr[i + 1];}arr = tempArr;end=tempArr.length;left=sum;continue;}if (arr[start] > left) {//arr[start] = 0;start++;} else if (arr[start] == left) {for (int i = 0; i < start + 1; i++) {//System.out.print(arr[i] + "\t");if (arr[i] != 0) {list.add(arr[i]);}}return list;} else {left = left - arr[start];start++;}}return list;}}

?

?

?

如有建议,或者Bug,可以留言。

end

??????

?

热点排行