您的位置:首页 > 其它

动态规划之钢条切割

2015-03-23 12:42 162 查看
先附上代码:

package dynamicprogramming;

public class Case01 {

// 切管子

public static void main(String args[]) {

// 管子长度以及对应成本

int[] len = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int[] price = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };

// 前驱结点设为空

int[] pre = new int[11];

// 定义最优解数组

int[] result = new int[11];

for (int i = 0; i < pre.length; i++) {

pre[i] = -1;

result[i] = -1;

}

result[1] = 1;

for (int i = 2; i < len.length; i++) {

result[i] = price[i];

for (int j = 1; j < i; j++) {

if (result[i] < result[i - j] + price[j]) {

result[i] = result[i - j] + price[j];

pre[i] = j;

}

}

}

// 已经有了最优解

System.out.println("打印结果");

for (int i : result) {

System.out.print(i + " ");

}

System.out.println();

/*System.out.println("前驱结点:");

for (int i : pre) {

System.out.print(i + " ");

}*/

System.out.println("打印分割方案:");

for(int i=1;i<len.length;i++){

if(pre[i]!=-1){

//有后继结点,那么先输出与对应节点之间的长度,然后再继续输出后继节点对应的方案

System.out.print((i-pre[i])+" ");

//调用方法

int temp= getPre(pre,i);

while(temp!=-1){

//System.out.print((i-pre[i])+" ");

if(pre[temp]!=-1){

System.out.print((temp-pre[temp])+" ");

//调用方法

temp=pre[temp];

}else

{ System.out.print(temp+" ");break;}

}

}

else

System.out.print(i);

System.out.println();

}

}

public static int getPre(int[] pre, int n) {

if(pre
!=-1){



return pre
;

}

else return -1;

}

}

打印结果

-1 1 5 8 10 13 17 18 22 25 30

打印分割方案:

1

2

3

2 2

3 2

6

6 1

6 2

6 3

10

---------------------------------------------------------------------------------------------

采用子底向上的方式,依次计算切割钢管所能获得的最大收益,然后是对应的分割方案。

// 管子长度以及对应成本

int[] len = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int[] cost = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };

一开始先要初始化两个数组,pre, result 分别存放对应长度的前驱以及对应的最优解。

前驱可以理解为当前管子的最优分割法中出去最后一段长度后的管子长。由于是满足最优子结构的性质,自底向上地方法去计算,我们可以通过循环调用来找到更小规模下的最优解,从而求得大问题的最优解。

我们先将每段长度的花费初始化result 数组,然后对这个结果是否是最优进行判断,如果存在一种组合总价值大于它,则把大的价值赋给它,同时保留前驱结点的信息(用于输出分割方案)。

分割方案的输出的思路是判断该结点处是否存在前驱,不存在的话对应长度的价格就是最优价格。否则,输出与其前驱之间的长度差,然后再用相同额方法去判断它的前驱,直至前驱不存在。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: