RodCutting:杆大于阵列长度

时间:2016-11-13 17:49:10

标签: java dynamic-programming

如何修改cutRod和bottomUpCutRod方法以保存大于数组长度的长度。例如,当前p的长度为11,如何切割具有相同阵列的长度为15,20的杆等。例如

p = {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30};

如果我调用cutRod(p,10),我得到30,但它当然在cutRod(p,15)或者崩溃 cutRod(P,20)。 (同样适用于bottomUpCutRod)。任何想法如何做到这一点?这是动态编程问题,我实现bottomUpCutRod方法的想法是遍历p,并且每个元素计算自身及其邻居的每个排列,并在必要时更新结果数组r。

 public class Main {    
    private static final double MINUS_INFINITY = Double.NEGATIVE_INFINITY;    

    public static void main(String[] args) {

        // price array
        double[] p = {0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30};

        // test cutRod
        cutRod(p,10);

        // test bottomUpCutRod
       bottomUpCutRod(p,10);

    }//end of main

    // an optimal cut for a rod of length n
    // p is the price array
    // use recursion
    private static double cutRod(double[] p, int value) {
        double[] r = new double[value+1];
        double out = 0;

          // initialize r to NEGATIVE_INFINITY;
        for (int i = 1; i < r.length; i++)
            r[i] = MINUS_INFINITY;

        // call the helper method
        out = helpCutRod(p,r.length-1,r);

        // print r
        System.out.println("Result ");
        System.out.println("r[" + (r.length-1) + "] = " + r[r.length-1]);

        return out;
    }//end of method             

    // helpCutRod computes an optimal cut for a rod 
    // p is the price array and r[i] is the optimal cut for a rod of length i
    // n is the length of the rod that is currently being computed

    private static double helpCutRod(double[] p, int n, double[] r) {
        double q = MINUS_INFINITY;
        if (r[n] >= 0)  // the whole r was computed
            return r[n];
        if (n == 0)
           q = 0;
        else {
            for (int i = 1; i <= n; i++) {                
                 q = RodCutting.max(q, p[i] + helpCutRod(p,n-i,r));
            }    
            r[n] = q;
        }           
        return q;
    }                

    // use the bottom-up approach
    // do NOT use recursion

    private static double bottomUpCutRod(double[] p, int len) {
        // r[i] is the optimal cut for a rod of length i
        double[] r = new double[len+1];
        r[0] = 0;
        for (int j = 1; j < p.length; j++) {

            // compute r[j]
            double q = MINUS_INFINITY;

            // r[j] is the maximum over i of p[i] + r[j-i]
            // where 1<= i <= j

            for (int i = 1; i <= j; i++)                
                q = max(q, p[i] + r[j-i]);

            // update value of r[j]
            r[j] = q;
        }//end of for outer    

        // print r 
        System.out.println("The r array from the bottomUpCutRod:");
            System.out.println("r[" + len + "] = " + r[len]);
        return r[len] ;       
    }//end of method
    public static double max(double a, double b){

        if(a<=b){
            return b;
        }else{
            return a;
        }   
    }//end of max
}//end of class

1 个答案:

答案 0 :(得分:0)

如果我正确理解了杆切割问题,那么您的价格数组p会告诉您可以通过p.length - 1销售长度为0的杆件的价格。因此,如果阵列长度为11,即使您有一个长度为15,20或30的初始杆,您也知道长度为10的碎片价格。由于您不知道11号及以上长度的价格,我假设您可以安全地将它们设置为0.我会期望算法将你的杆切成碎片,你知道它是正价格。

如果所有这些都是正确的,那么解决方案很简单。比如,cutRod(p, 15)计算,首先要做

    p = Arrays.copyOf(p, 15 + 1);

这会将p复制到索引为0到15的新数组中,并用zeores填充。现在运行你的方法。当然,与其他初始长度类似。

通过此修改,您的程序将打印杆长度为15:

Result 
r[15] = 43.0
The r array from the bottomUpCutRod:
r[15] = 43.0

我认为它在10,3和2处被发现产生价格30 + 8 + 5 = 43,但我没有检查过。

编辑:如果杆比价格数组长得多,那么计算结果时切割的时间长于价格数组的最大值可能是浪费。因此,实际上可以修改您的方法以接受更短的价格数组和更长的初始棒。而不是上面的快速修复。

在递归helpCutRod()中,将for循环更改为:

        for (int i = 1; i <= Math.min(n, p.length - 1); i++) {                

这将确保只考虑我们有价格的作品。

对于bottomUpCutRod(),需要进行两项更改:

第一个for循环需要运行,直到j等于len

    for (int j = 1; j < r.length; j++) {

同样,内部for循环不应该通过p

的边界
        for (int i = 1; i <= Math.min(j, p.length - 1); i++)                

使用这三个修改而不是p数组的扩展,程序将打印与上面相同的结果。