需要算法帮助(N个袋子和物品随机分配)

6

我遇到了一个算法问题,但是除了暴力方法之外我无法找到更好的解决方案,也无法将其转化为更好的已知问题。有什么提示吗?

有N个大小不同的袋子和N种物品。每种物品归属于一个袋子。每种物品都有许多个,并且每个物品的大小可能不同。最初,这些物品随机分布在所有袋子中。我们必须将物品放入它们所属的袋子。但是,我们只能通过交换物品对来一次操作两个袋子 (尽可能多的) 并继续进行下一步操作。目标是减少总对数。编辑:目标是找到一系列传输的顺序,以使涉及的袋子对的总数最小化

澄清

袋子不是任意大的(如果有助于您,可以假设袋子和物品大小为0到1000之间的整数)。您经常会遇到两个袋子之间的所有物品由于其中一个袋子的有限容量而无法交换的情况。这就是算法需要进行优化的地方。也许,如果另一组袋子先交换,当前的交换可以一次完成。为了说明这一点,让我们考虑袋子A,B和C及其物品1,2,3,分别表示物品大小(括号中的数字)。

A(10):3(8)

B(10):1(2),1(3)

C(10):1(4)

交换顺序可以是AB、AC、AB或AC、AB。后者是最优的,因为交换次数较少。


答案需要精确到小数点后吗? - Richard
1
@rhino2rhonda:袋子和物品的大小有限制吗?我假设所有的大小都是正数。但也许有最大尺寸?也许最小尺寸大于零?也许尺寸必须是整数?(请使用“@Richard”回复,这样我会收到通知。) - Richard
1
@Richard,我理解你的担忧。我已经添加了假设和一个例子来澄清。请查看我的最后一次编辑。 - rohit-biswas
@גלעדברקן,是的,例子中没有第二个物品。所有物品通常都会出现在所有袋子中,但我只是想说明交换顺序的相关性。如果我们首先交换A和B袋子,我们只能移动一个物品(大小为2的物品1)从B到A。然后我们必须执行AC交换以在A袋子中腾出空间,然后再次交换AB以将第二个物品从B转移到A。因此,总共需要3次交换。如果我们选择首先交换A和B袋子,则A袋子中将有足够的空间完成AB交换,因此总共只需要2次交换。希望这样解释清楚了。 - rohit-biswas
1
几个问题:a)一个类的所有物品是否保证能够放入它们的袋子中?b)是否可以假设有一个无限的“外部”袋子用于临时存储?c)是否保证总有解决方案?(我认为如果a)和b)的答案是“是”,那么这也将自动成立,尽管我不确定b)是否必要)。 - jdehesa
显示剩余10条评论
1个回答

2

由于我无法想出一种总能找到最优解的算法,对于解的适应度(交换数量)的近似也是可接受的,因此我建议使用一种带剪枝的随机局部搜索算法。

给定一个随机的起始配置,该算法考虑所有可能的交换,并根据机会做出加权决策:交换越好,选择的可能性就越大。

一个交换的价值是物品交易的价值之和,如果物品没有放入其所属的袋子内,则交易的价值为零,否则为正值。随着物品尺寸的增加,价值会增加(这个想法是更大的块相对于较小的块来说,移动多次更加困难)。此适应度函数可以替换为任何其他适应度函数,在实际展示效率之前,这是未知的。

由于任何配置都可能是许多先前交换的结果,因此我们跟踪我们之前看过的配置,以及适应度(基于多少项在正确的袋子中 - 此适应度与一个交换的价值无关)和前面的交换列表。如果一个配置的适应度函数是在它们所属袋子中的物品数量之和,则问题中物品的数量是最高适应度(因此标记配置为解决方案)。

如果:

  • 任何受影响的袋子在潜在交换后都超过了其容量。
  • 新交换将您带回到之前进行的最后一次交换之前的最后一个配置(即反向交换)。

我们无法进行交换。当我们确定潜在的交换时,我们查看以前看过的配置列表(使用哈希函数进行O(1)查找)。然后我们将其先前的交换设置为我们的先前交换(如果我们的列表比它的列表短),或者将我们的先前交换设置为其列表(如果它的列表比我们的列表要短)。我们可以这样做,因为重要的是我们所做的交换数量尽可能少,而不是我们所做的是哪些交换。

如果在某个配置中没有更多可能的交换,那么这意味着您被卡住了。本地搜索会告诉您“重置”,您可以用各种方式来实现,例如:

  • 重置到以前看到的状态(也许是迄今为止最好的状态?)
  • 重置为一个新的有效随机解决方案

注意

  • 由于该算法只允许您进行有效的交换,因此每个配置都将满足所有约束条件。
  • 该算法不能保证立即“停止”,您可以实现最大迭代次数(交换次数)。
  • 该算法不能保证找到正确的解决方案,因为它会尽力在每次迭代中找到更好的配置。然而,由于完美解决方案(一组交换)应该与几乎完美的解决方案非常接近,所以人类可能能够完成本地搜索算法未能完成的工作,特别是当它导致无效配置时(其中不是每个项目都在其正确的包中)。
  • 使用的适应度函数和策略很可能不是最有效的。您可以四处寻找更好的策略。更高效的适应度函数/策略应该会更快地得出良好的解决方案(较少的迭代次数)。

谢谢,我需要一些时间来消化所有的内容,但我一定会尝试它。 - rohit-biswas
如果你需要更多的帮助/解释,你可以在这里问,我通常会查看stackoverflow。 - Glubus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接