我需要设计一个算法来进行简单的碎片整理,但需要进行最少量的更改"特征。让我们说我有3个容量为10的容器及其中的以下项目:
Container 1: 2 3 3
Container 2: 4 4
Container 3: 1 5 1 1
所有容器都装满了8/10。现在我想放置下一个大小为3的项目 - 整体可用容量为6,但是没有一个容器具有3的可用容量。虽然有多种可能的解决方案进行碎片整理,但我需要算法,它将找到解决方案,其中来自第一个容器的2号物品将被放置在其他地方,因此新物品可以放入容器1中,因为这个解决方案只需要一次更换(而不是从容器3中更换两个物品)。因此,所需的结果应该是:
Container 1: 3 3 3(new item)
Container 2: 4 4 2(moved from Container 1)
Container 3: 1 5 1 1
我已经做了一些研究,我能找到的只是背包问题或Buddy算法,但我不确定,这些是否真的是我想要的。
你们中的任何人都可以帮我设计这个算法尽可能简单吗?我正在解决一种情况,即我将拥有少量大容器和大量物品,因此列举所有可能性并不是最佳选择。
非常感谢!
更新只是为了弄清楚我在问什么 - 确定是否可以通过仅进行一次更改来解决问题是没有问题的。问题是,如何在单次移动时找到最少量的替换物。是不可能的。
答案 0 :(得分:1)
这不是问题的答案,但是评论太长了。这里陈述的问题是NP完全的(一旦我们适当地将其改为决策问题),可以从the PARTITION problem减少。
设x 1 ,x 2 ,...,x n 是PARTITION问题的一个实例。为了表示法,让我们将x 1 作为x的最小值的大小,让W为所有x的总和。此外,为简单起见,我们假设W是偶数。
我们构造一个给定问题的实例来编码我们的PARTITION实例,如下所示。我们有三个尺寸为W,W / 2-x 1 和x 1 的容器。最初,第一个容器包含大小为x 1 ,x 2 ,...,x n 的项目,其他两个为空。要插入的新项目的大小为W / 2。我们观察到,当且仅当原始PARTITION问题有解决方案时,才能将这个新项目插入到这些容器中。
编辑添加(更多证明细节)
首先,我们假设我们有一个原始PARTITION问题的解决方案,即:将x分成两个子集S 1 和S 2 ,这样每个子集中的x的总和等于W / 2。假设S 1 包含最小元素x 1 。然后,我们可以将x 1 移动到第三个容器中,将S 1 的所有其他元素移动到第二个容器中,从而在第一个容器中留下W / 2的空间对于新项目。
接下来,假设我们有一些方法可以将新的W / 2大小的元素插入到这些容器中。通过检查,这可能发生的唯一方法是在第一个容器中为它腾出空间; 可能发生的唯一方法是将第一个容器中准确的W / 2物品移出(并因此,准确地留下W / 2值的物品)。显然,这定义了将原始项集合拆分为两个子集,使每个子集的大小为W / 2.
现在,仅仅因为这个问题是NP完全并不意味着所有的都丢失了。它只是意味着如果你认为你已经提出了一个解决多项式时间内所有实例的解决方案,那么你应该检查你的工作。您将看到的实例类型的结构(例如:“大量容器和其中的大量项目”)可能有助于指导搜索有用的启发式方法。
答案 1 :(得分:0)
如果这些容器是从头开始构建的,你可以添加状态来说明哪个容器填充最少,并且总是将下一个项目放在那里。
如果您可以从容器中移除容器的大小到容器外部,这可能会变得更简单。
只需2美分。