【问题标题】:Algorithmic help needed (N bags and items distributed randomly)需要算法帮助(N 个袋子和随机分发的物品)
【发布时间】:2017-07-06 06:11:38
【问题描述】:

我遇到了一个算法问题,但我无法找出比蛮力更好的方法,也无法将其简化为一个更清楚的问题。有什么提示吗?

有 N 袋不同尺寸和 N 种物品。每种类型的物品都属于一个袋子。每种类型都有很多物品,每个物品的尺寸可能不同。最初,这些物品随机分布在所有袋子中。我们必须将这些物品放在各自的袋子里。但是,我们一次只能操作一对袋子,方法是交换物品(尽可能多地),然后进行下一对。 目的是减少对的总数。 编辑:目的是找到一个转移序列,使所涉及的袋对总数最小化

澄清

袋子不是任意大的(如果有帮助,您可以假设袋子和物品的大小是 0 到 1000 之间的整数)。您会经常遇到由于其中一个袋子的容量有限而无法交换 2 个袋子之间的所有物品的情况。这是算法需要进行优化的地方。也许,如果先交换另一对包,则可以一次完成当前的交换。为了说明这一点,让我们分别考虑袋子 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。后者是最佳的,因为交换的数量较少。

【问题讨论】:

  • 答案需要准确吗?
  • 这似乎是一个排序问题,根据条件,我认为您可以使用合并排序之类的方法将项目安排在各自的包中。
  • @rhino2rhonda:对包或物品的大小有任何限制吗?我假设所有尺寸都是正数。但也许有最大尺寸?也许最小尺寸大于零?也许大小必须是整数? (请使用@Richard 回复,因此我会收到您已这样做的通知。)
  • @Richard,我明白你的担忧。我添加了假设和一个例子来澄清。请查看我上次的编辑。
  • 几个问题:a) 是否保证某一类的所有物品都可以放入他们的包中? b)是否有可能假设一个无限的“外部”袋子用于临时存储? c) 是否保证总是有解决方案? (我认为如果 a) 和 b) 的答案是“是”,这也将自动成立,尽管我不确定 b) 是否必要)。

标签: algorithm


【解决方案1】:

由于我无法想出一个总能找到最佳答案的算法,并且解决方案的适应度(交换量)的近似值也很好,我建议使用带有修剪的随机局部搜索算法。

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

交换的价值将是物品交易价值的总和,如果物品没有最终进入它的归属袋,则该值为零,如果最终到达那里,则为正数。该值随着项目大小的增加而增加(其背后的想法是,与较小的块相比,较大的块难以移动多次)。这个适应度函数可以被任何其他适应度函数代替,它的效率在经验证明之前是未知的。

由于任何配置都可能是许多先前交换的结果,因此我们会跟踪我们之前看到的配置以及适应度(基于正确包中的物品数量 - 这种适应度与价值无关交换)和先前交换的列表。如果配置的适应度函数是其正确包中的项目的总和,则问题中的项目数量是最高的适应度(因此将配置标记为解决方案)。

如果满足以下条件,则不可能进行交换:

  • 在可能的交换之后,任何一个受影响的袋子的容量都超过了它的容量。
  • 新的交换让您回到上次交换之前的最后一个配置(即反向交换)。

当我们确定潜在的交换时,我们会查看之前看到的配置列表(使用散列函数进行 O(1) 查找)。然后我们要么将它的先行交换设置为我们的先行交换(如果我们的列表比它的短),或者我们将我们的先行交换设置到它的列表(如果它的列表比我们的短)。我们可以这样做,因为我们进行了哪些交换并不重要,只要交换的数量尽可能少。

如果配置中没有更多可能的交换,则意味着您被卡住了。本地搜索告诉您“重置”,您可以通过多种方式执行此操作,例如:

  • 重置为以前看到的状态(可能是您迄今为止看到的最好的状态?)
  • 重置为新的有效随机解

注意

  • 由于该算法仅允许您进行有效交换,因此每个配置都将满足所有约束条件。
  • 算法不保证“停止”开箱即用,您可以实现最大迭代次数(交换)
  • 该算法不能保证找到正确的解决方案,因为它最好在每次迭代时找到更好的配置。然而,由于一个完美的解决方案(一组交换)应该与一个几乎完美的解决方案密切相关,因此在导致无效配置(并非每个项目都正确袋)。
  • 使用的适应度函数和策略很可能不是最有效的。你可以四处寻找更好的。更有效的适应度函数/策略应该会更快(更少迭代)产生良好的解决方案。

【讨论】:

  • 谢谢,我需要一些时间来消化所有这些,但我一定会尝试一下。
  • 如果您需要更多帮助/解释可以在这里提问,我通常检查stackoverflow
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 2021-02-07
  • 2021-11-12
  • 2020-12-31
  • 1970-01-01
相关资源
最近更新 更多