购买策略的动态规划

时间:2018-02-12 21:39:29

标签: algorithm dynamic-programming

假设有s_1,s_2,...,s_n个苹果卖家,根据我们购买的金额,价格会有所不同,而卖家j购买i苹果的价格是p(i,j)。找到一种以最低成本准确购买苹果(0 <= A <= kn)的方法是什么?我认为需要构建一个M * n表来开发动态编程算法,但我不确定如何设计它。而且,我认为时间复杂度应该是O(n ^ 2 k ^ 2),我是否正确?

后续问题:如果我们从卖家j购买u个苹果,我们不允许从其邻居(u+2s_j-1购买s_j+1个或更多苹果),在这种情况下我们应该如何设计算法?

由于

2 个答案:

答案 0 :(得分:2)

问题1所需的数据结构,对于j中的1..nk中的0..A,您可以花费的最低金额{ {1}}来自第一批k供应商的苹果,以及您从最后一批供应商购买的数量。计算单个供应商的数据,假设您拥有最后一个,j n O(A) O(A ^ 2 * n)O(A) counts. Do that for每个vendors and you need操作需要time. With some cleverness, you can also make it次操作O(A ^ 2)`记忆。

对于问题2,它变得更加棘手。而不是通过供应商j购买的每个苹果数量的数据结构,它必须是每(j, k)个数据结构,因为它对您购买的苹果数量很重要。这使得它O(A^3*n)时间。 (实际上比这更好,因为你从不从任何一个供应商那里买太多苹果。)

答案 1 :(得分:2)

这个问题可以很好地转换为常见的背包问题,除了您为每个“项目”设置了许多不同的“价格”和“权重”,即您的p(i,j)功能。

the Wikipedia page无耻地复制的标准DP算法如下所示:

// Input:
// Values (stored in array v)     -> represented by p function
// Weights (stored in array w)    -> determined by parameter to p
// Number of distinct items (n)   -> different apple suppliers
// Knapsack capacity (W)          -> desired number of apples A

for j from 0 to W do:
    m[0, j] := 0

for i from 1 to n do:
    for j from 0 to W do:
        if w[i] > j then:
            m[i, j] := m[i-1, j]
        else:
            m[i, j] := max(m[i-1, j], m[i-1, j-w[i]] + v[i])

但是有一些不同之处:

  • 您不是在寻找max值,而是在寻找min价格
  • 你无法购买最多 W苹果,但完全 W苹果(否则,最好的策略是不买任何苹果苹果)
  • 因此,没有零行;相反,您的第一行包含以相应的批量价格从供应商1购买的所有苹果
  • 您必须考虑p(i, j)
  • 的不同值

因此,您可以将算法调整为这样的(使用类似Python的列表理解符号)

for j from 0 to W do:      // apples to buy from seller 1
    m[1, j] := p(1, j)

for i from 2 to n do:      // loop sellers 2 to n
    for j from 0 to W do:  // loop total number of apples to buy
        m[i, j] := min(m[i-1, j-k] + p(k, i) 
                       for k from 0 to j)  // apples bought from seller i

这意味着你有三个嵌套循环,这使得复杂度为O(nA²)。

第二部分有点棘手,我不确定我是否真的理解它。基本上,这意味着对于每个卖家(第一个除外),您只能再购买一个,相同数量,或者比前一个卖家少一个。为此,您必须扩展DP矩阵以具有第三个维度,即从该卖家购买的苹果数量,并将min表达式替换为实际循环,分配给该表的不同单元格。