Algorithm 动态编程-复杂性

Algorithm 动态编程-复杂性,algorithm,complexity-theory,dynamic-programming,Algorithm,Complexity Theory,Dynamic Programming,我有一个家庭作业的问题,我一直在努力解决一段时间了,但我无法解决我的生活 我有一张X*Y尺寸的纸,还有一组较小尺寸的图案,上面有与之相关的价格值。我可以水平或垂直切割板材,我必须找到优化的切割模式,以从板材中获得最大的利润 据我所知,应该有(X*Y)(X+Y+#of patterns)递归操作。复杂性应该是指数级的。有人能解释一下原因吗 我提出的伪代码如下所示: Optimize( w, h ) { best_price = 0 for(Pattern p : all patterns

我有一个家庭作业的问题,我一直在努力解决一段时间了,但我无法解决我的生活

我有一张X*Y尺寸的纸,还有一组较小尺寸的图案,上面有与之相关的价格值。我可以水平或垂直切割板材,我必须找到优化的切割模式,以从板材中获得最大的利润

据我所知,应该有(X*Y)(X+Y+#of patterns)递归操作。复杂性应该是指数级的。有人能解释一下原因吗

我提出的伪代码如下所示:

Optimize( w, h ) {
best_price = 0
    for(Pattern p :  all patterns) {
        if ( p fits into this piece of cloth && p’s price > best price) {best_price = p’s price}
    }
    for (i = 1…n){
       L= Optimize( i, h );
       R= Optimize( w-i, h);
       if (L_price + R_price > best_price) { update best_price}
    }
    for (i = 1…n){
        T= Optimize( w, i );
        B= Optimize( w, h-i);
        if (T_price + B_price > best_price) { update best_price}
    }
return best_price;
}

递归情况是指数型的,因为您可以在开始时选择将纸张剪切为0到最大宽度英寸或0到最大高度英寸,然后选择剪切其余部分(递归)

这个问题听起来更有趣,因为它涉及两个维度

他是个好向导。阅读这篇文章可以让你在不公然回答作业的情况下走上正确的道路

递归时为何为指数的相关部分:

This recursive algorithm uses the formula above and is slow
Code
    -- price array p, length n
    Cut-Rod(p, n)
        if n = 0 then
            return 0
        end if
        q := MinInt
        for i in 1 .. n loop
            q = max(q, p(i) + Cut-Rod(p, n-i)
        end loop
        return q

Recursion tree (shows subproblems): 4/[3,2,1,0]//[2,1,0],[1,0],0//[1,0],0,0//0
Performance: Let T(n) = number of calls to Cut-Rod(x, n), for any x
T(0)=0
T(n)=1+∑i=1nT(n−i)=1+∑j=0n−1T(j)
Solution: T(n)=2n

在计算动态规划算法的复杂度时,我们可以将其分解为两个子问题:一个是计算子状态数;另一个是计算解决特定子问题的时间复杂度

但当你不使用记忆方法时,实际上具有多项式时间复杂度的算法会增加到指数时间复杂度,因为你没有使用以前计算过的信息。(我很确定您在动态编程课程中理解了这一部分)

无论您是使用记忆方法还是自底向上方法来解决动态规划问题,时间复杂度都保持不变。我认为您遇到的问题是,您试图在脑海中绘制函数调用图。相反,让我们尝试以这种方式估计函数调用的数量

您是说存在(X*Y)(X+Y+#of模式)递归调用

嗯,是和否。

确实,当您使用memoization方法时,递归调用的数量只有这么多。因为如果您已经调用并计算了某个优化(w0,h0),该值将被存储,下次另一个函数优化(w1,h1)调用优化(w0,h0)时,它将不再执行这些冗余工作。这就是时间复杂度多项式的由来


但在您当前的实现中,一个子问题Optimize(w0,h0)会得到许多冗余函数调用,这意味着算法中的递归调用数根本不是多项式(举个简单的例子,尝试绘制递归斐波那契数算法的调用图)。

我想这取决于哪个循环。对于水平切口环n=h-1,对于垂直切口,其为w-1。或者这是一个应该把我推向正确方向的问题吗?:)不,这不是暗示!我开始写答案,然后意识到我不能,因为我不知道循环迭代了多少次。我也用内存表实现了它。对于动态规划,解应该是多项式。由于表的大小为WxH,因此只需要W*H解决方案。再次阅读后,我现在明白了…根据您的代码,它可能是n^2logn。您可以尝试用内存表重写它,这样更容易获得complexity@ReezaCoriza如果你重写了内存中的表,你的循环有多深;e、 因为{for}}是n^2。在大多数情况下,它可以被认为是nlogn,在最坏的情况下是n^2。最后,最终的答案是基于您使用哪种复杂度函数(例如O,O)。我理解它与棒切割问题有关。基本上,如果我找到一个n长度杆的最佳切割,在位置I,我仍然必须找到其余杆的最佳切割,n-I。我想我的头在二维空间里绕不过去了。无论如何,谢谢你的帮助。我对分析复杂性很在行。我只需要一直这样做直到我得到它。