Fractional Knapsack Problem in Java

2025年5月3日 | 阅读4分钟

分数背包问题是一个优化问题,广泛应用于计算机科学和运筹学的解决问题中。然而,与 0/1 背包问题不同的是,物品不必是完整的,因为这种情况允许分割它们,以在给定容量的单个背包中获得最大的总价值。这一特性使其成为所谓的贪心算法的理想选择。

问题定义

在这个问题中,我们面临着一组物品,所有这些物品都有特定的重量和价值。这里定义的情况是一个优化任务——精确地说,是确定可以装入重量容量有限的背包中的最大数量的物品。

与 0/1 背包问题的重大区别在于,一个 对象 不必完全放入背包,而是可以是其一部分。

例如,考虑以下物品

物品 1:重量 = 10,价值 = 60

物品 2:重量 = 20,价值 = 100

物品 3:重量 = 30,价值 = 120

如果背包的容量是 50,可以装入物品 1 和物品 2,以及物品 3 的一半,以获得最大的利润。

问题解决方案

贪心法

为了有效地解决这个问题,我们采用贪心算法。该算法遵循以下步骤:

计算价值-重量比:对于每件物品,计算其价值与重量之比。这个比率将帮助我们根据每单位重量的价值来决定顺序和要携带的物品。

对物品进行排序:将物品按价值-重量比从高到低排序。这样,我们将更有可能首先满足客户对最重要物品的需求。

遍历已排序的物品:开始将物品添加到背包中

  • 如果背包中仍有足够的空间完全装下该物品,则必须将其全部添加。
  • 如果某个物品根本无法装入背包,则应尽可能多地装入,以填满背包。

返回总价值:如果处理的物品数量等于可用物品的总数,或者背包已满,则输出获得的总体价值。

文件名:FractionalKnapsack.java

输出

 
Maximum value in knapsack: 240.00   

解释

分数 背包问题 创建了一个 Item 类来存储每件物品的重量、价值和价值密度。getMaxValue 方法 将这些物品按价值/重量的降序分开。

然后,它遍历已排序的物品,将可以放入背包的独立可执行物品的最大价值添加进去。当一个物品不合适时,它会取能装下的部分(一个分数)并将其添加到总价值中。

最后,上面给出的方法返回要装入背包的总价值。在 main() 方法 中,创建了一些预定义的物品及其容量和价值。

指定背包的最大容量,并调用 getMaxValue() 方法返回最大可能的利润,然后打印消息。此实现展示了如何确切地使用贪心方法来解决分数背包问题。

结论

分数背包问题展示了 贪心算法 在资源分配方面的良好应用。与 0/1 问题相比,这个问题允许部分物品被占用,这使得该问题更加灵活。

读者可以轻松地看到它在 Java 中的实现方式,从而获得一个关于如何以高效率和可读性解决此问题以用于实际工作的示例。


下一个主题Java 回调函数