算法最优填充

时间:2017-02-08 12:28:11

标签: algorithm math knapsack-problem

澄清 我们有一个对象列表。 每个对象都有一个属性Size和一个属性Value。 然后我们的空间有限。

我想知道如何获得最佳的对象混合(或没有混合),以便占据空间的对象的值具有最高的潜在价值。

所以尺寸和价值一样重要。并且每个对象的大小和值都是固定的,所以我不能有半个对象。

实施例 所以我们有 对象A,大小为2,值为5 对象B,大小为3,值为8

我们的空间有限,大小为10.

将对象放置在空间中我们可以看到我们可以有两个对象A的实例和两个对象B的实例,从而得到总值为26.

我想有一个方法/函数,它接受一个Objects和一个Size数组,并返回一个具有最高潜在价值的对象数组。

很抱歉没有从一开始就明白这个问题,很有反馈意见。 希望上面更新的问题能够澄清我想要做的事情。

2 个答案:

答案 0 :(得分:1)

我看到的第一点是解决方案不依赖于值的数量。仅考虑这些值就足够了。

给定一组(例如{5,8,10,15})和所需的目标值,您可以使用动态编程:

def solve(values, target):
    # Try big values first to get smaller results.
    # Does not work in all cases.
    # values.sort(reverse=True)

    # Init an array with 0, -1, -1, ...
    added_to_reach = [None] * (target + 1)
    added_to_reach[0] = 0

    # Dynamically calculate if it is possible to
    # reach each value i up to target and store the
    # last added value in added_to_reach[i].
    for i in range(1, target + 1):
        for v in values:
            if i - v >= 0 and added_to_reach[i-v] is not None:
                added_to_reach[i] = v

    # Calculate the solution by going back.
    while added_to_reach[target] is None:
        target -= 1

    result = []
    while target > 0:
        result.append(added_to_reach[target])
        target -= added_to_reach[target]

    return result

print(solve([5, 10, 13, 14], 39))

在最坏的情况下,复杂度在target(其表示大小的指数)中是线性的。当我们贪婪地选择一个值来接下来尝试时,首先尝试大值可能会很好,但实际上并非如此(参见示例)。

答案 1 :(得分:1)

n:0 1 2 3
 空间:2 2 4 5
 值:3 7 2 9
s = 10

然后你可以达到的最大收益是19,包括项目0,1和3,它们的总重量为9。

 /* *   
 s = given limited space  
 n = current element  
 val = value array for each element  
 space = space occupied by each element  
 * */


 public int findMaximumBenefit(int s, int n, int [] val, int [] space)
{
    if (s == 0 || n == weight.length)
    {
        return 0;
    }

    // if this item's size is greater than space available
    // then this item cannot be included in the knapsack
    if (space[n] > s)
        return findMaximumBenefit(s, n+1, val, space);

    // Case1: maximum benefit possible by including current item in the knapsack
    int includeCaseBenefit = val[n] + findMaximumBenefit(s-space[n], n+1, val, space);

    // Case2: maximum benefit possible by excluding current item from the knapsack
    int excludeCaseBenefit = findMaximumBenefit(s, n+1, val, space);

    // return maximum of case1 and case2 values 
    return max(includeCaseBenefit, excludeCaseBenefit);
}

此功能可在给定的空间限制下为您提供最大可能的好处。 现在,如果您还想了解所有项目的贡献以找到最大收益,那么您可以使用以下链接http://www.ideserve.co.in/learn/dynamic-programming-0-1-knapsack-problem