动态编程:如何设计算法何时需要考虑两个因素?

时间:2015-06-22 06:51:29

标签: algorithm optimization dynamic-programming frequency

我有以下问题,我对此只有一点看法:

考虑磁带存储问题。给定长度为n的{​​{1}}个文件以及访问它们的频率l1,...,ln,其中所有频率的总和为1且f1,...,fn。 &#34;最优&#34;意味着最小化这些文件的平均检索时间。例如,如果您有两个长度为0<fi<1和频率为10, 4的文件,如果先存储文件1,则平均检索时间为0.8, 0.2

设计算法以找到最佳顺序并证明其有效。

我的想法: 更大的频率和订单前面的长度越大,但哪个因素应该被赋予更高的优先级?

3 个答案:

答案 0 :(得分:3)

此问题无需动态编程。这是一个简单的排序问题,略有不同。

查找每个文件的frequency / length。这样就可以了解文件的每个单元长度访问频率。按降序对这些进行排序,因为每个文件都是&#34;惩罚&#34;按前一个文件的长度。

<强>证明:

假设订单以某种方式修复。然后,交换任何两个相邻文件不会影响交换位置以外的任何其他li * fi。在交换x和另一个y == x+1中调用左边的一个。然后,平均检索时间的变化是ly*fx - lx*fy。如果fx/lx < fy/ly,则ly*fx < lx*fy表示ly*fx - lx*fy < 0,这意味着平均检索时间减少。这意味着我们有利于进行此交换。我们会在fx/lx < fy/ly时继续进行此类交换,并且当不再可能时,我们将达到这一点。这一定是最佳答案。

每当left < right交换邻近的东西,就像按降序排列气泡一样,所以我们通常只能使用任何排序。

答案 1 :(得分:0)

只需将长度为升序(l1<l2<l3<l4<...<ln)的文件和频率作为降序。 因为

average retrieval time =
ART1 = 
(l1)*f1 +
(l1+l2)*f2 +
(l1+l2+l3)*f3 +
...

假设我们交换l1和l2 。所以我们打破了长度的升序。

ART2 =
(l2)*f1 + 
(l2+l1)*f2 + 
(l1+l2+l3)*f3 + 
...

如果它(ART1 < ART2),它会使情况变得更糟。 看这个。 我们应该检查ART1-ART2 < 0

ART1-ART2 = 
{ (l1)*f1 + (l1+l2)*f2 }
- 
{ (l2)*f1 + (l2+l1)*f2 }

= l1*f1-l2*f1
= (l1-l2)*f1.

来自假设l1<l2,我们得出结论ART1-ART2<0

所以长度应该是升序。

同样,如果你交换f1和f2,你可以探测频率应该是降序。

答案 2 :(得分:0)

DP可以工作但不是这个问题的一个很好的解决方案,因为虽然检查所有选项的暴力方法需要O(n!)时间,但DP方法需要的时间与不同子问题的数量成比例。比方说,首先我们做出所有可能的n个选择,然后我们将留下n个大小(n-1)的子问题。为了使DP工作,主要问题的最佳解决方案应该来自子问题的最优解决方案。现在,对于大小(n-1)问题,我们可以说我们知道解决方案,所以

total average retreival time = (length of first chosen file * 1) + (retrieval time for (n-1) size problem)

由于上述等式,将出现重叠的子问题,但不同子问题的总数将是

nC1 + nC2 + ... nCn = 2^n

仍然呈指数级。

因此,DP将降低复杂性,但问题的本质仍然是指数级的。