算法问题:将填料棒连成一排

时间:2010-09-30 06:19:26

标签: javascript algorithm sorting constraints

好吧,这可能是一个棘手的问题。它实际上是与我的实际应用相关的另一个类似问题的类比,但为了清楚起见,我已将其简化为这个假设问题。这是:

  1. 我需要排序一系列的棒。因为它是一条线,所以只需关注一维。
  2. 杆有不同的长度和不同的重量。重量和长度之间没有相关性。小杆可能非常重,而大杆可能非常轻。
  3. 棒需要按重量分类。
  4. 然而,真正的捕获某些棒只能放置不超过距线的起点一定距离,无论如何他们的体重。在此之前的任何地方都没事。
  5. 不保证约束将彼此间隔得足够远,以防止约束杆被挤压成重叠的可能性。在这种(希望是罕见的)情况下,要么需要在某些方面将杆重新排列在其约束内以创建所需的空间,或者可能需要找到理想的折衷解决方案(例如违反最小光杆的约束,例子)。
  6. 可能在未来的某个日期可以添加额外的约束*除了长度约束以指示棒之外的线内的特定(甚至不妥协)边界重叠成。
  7. 我目前的解决方案并不考虑后一种情况,听起来他们会涉及一些复杂的工作来解决它们。

    请注意,这适用于客户端Web应用程序,因此制作解决方案apply to Javascript会有所帮助!

4 个答案:

答案 0 :(得分:2)

如果有可能,我建议将其作为混合整数程序。如果您可以在此编码约束,则可以使用求解器来满足约束。 有关此类方法的更多信息,请参阅此页面:

http://en.wikipedia.org/wiki/Linear_programming

如果你能以某种方式将它与Javascript连接起来,那么它可能被证明是一种优雅的解决方案。

答案 1 :(得分:1)

我不太善于解决算法问题。但这是我的尝试:

将其与Knapsack problem

相关联
  • 而不是退货成本或价值 一个盒子,让他们分配 具有更高价值的人 更远的限制。
  • 有些事你喜欢 把一切都收拾得更近了 起点而不是一个 根据背包问题背包。
  • 至于未来日期&修改 我相信,我使用的是约束条件 类似的将需要修改 框的返回值或成本 仅

答案 2 :(得分:1)

起初,我试图将此视为排序问题。但我认为最好将其视为优化问题。让我试着将问题正式化。给出:

  • w i :杆的重量 i
  • l i :杆的长度 i
  • m i :杆 i 距离原点的最大距离。如果没有约束,则可以将此值设置为sum(i = 1,n,l i

问题是要找到一个 i 的排列,这样成本函数:

J = sum(i = 1,n,w a i * sum(j = 1,i-1,l a j ))

被最小化并且约束:

sum(j = 1,i-1,l a j )< = m i ,1< = i< ñ

满意。

但是,我不确定这是一个正确的表述。没有任何限制,最佳解决方案并不总是按重量分类的棒。例如,设l = {1,4},w = {1,3}。如果a = {1,2},则J是1 * 0 + 3 * 1 = 3,并且如果a = {2,1}(按重量排序),则J是3 * 0 + 1 * 4 = 4。显然,未排序的解决方案可以最大限度地降低成本函数,但我不确定这是否是您想要的。

另外,我还不知道如何解决这个问题。您可以在短期内尝试某种启发式搜索。我正在编写这个重新制定,以便其他人可以提供解决方案,同时我更多地考虑解决方案。如果它是正确的,当然。

需要注意的另一点是,您无需找到完整的解决方案即可查看是否存在解决方案。您可以忽略没有位置限制的杆,并尝试仅使用受约束的杆来解决问题。如果有一个解决方案,那么问题确实有一个解决方案(一个明显的次优解决方案是对无约束杆进行排序,并将它们附加到减少问题的解决方案上)。


说完这一切后,我认为下面的算法可以解决问题。我将在视觉上描述它以使其更容易理解。根据您的问题描述,我们的想法是将杆从左到右放置在线段上(原点是线段的最左侧点)。

  1. 将杆上的位置限制分开。然后,将它们放置在受约束位置的极限位置。
  2. 如果没有重叠杆,请转到步骤4
  3. 对于每对重叠的杆,将原点靠近原点朝向原点移动,使它们不再重叠。该步骤可能需要线上的其他杆朝向原点移动以打开一些空间。您可以通过检查移动的杆现在是否与其左侧的杆重叠来检测到这一点。如果你不能创造足够的空间(将距离原点最近的杆移动到0仍然没有释放足够的空间),那么问题就无法解决。在这里,您有机会通过放松原始重叠对的最右侧杆上的约束来找到解决方案:只需将其从原点移开直到没有重叠(您可能需要向前推动前杆,直到所有重叠都固定为止之前你这样做了。)。
  4. 现在,我们放置了一些杆,周围有一些自由空间。开始用最重的杆(包括在自由空间右侧有限制的杆)填充自由空间。如果找不到合适的杆,只需移动自由空间右侧的下一根杆即可缩小间隙。
  5. 重复步骤4,直到到达最右边的约束杆。剩余的线段是所有可用空间。
  6. 按重量对所有留下的杆进行分类,并将它们放在剩余的空间中。
  7. 关于算法的一些注释:

    • 它没有解决我之前说过的问题。它试图仅根据它们的重量对杆进行分类。

    • 我认为有一些失去的机会可以做得更好,因为我们将一些杆向原点滑动以使它们全部适合(在步骤3中),并且有时从这些“挤入”的地方拾取重杆,并使它们更靠近原点(步骤4)。这释放了一些空间,但我们不会将被推开的杆滑回到受约束位置的极限。有可能这样做,但是当我的大脑工作得更好时,我将不得不修改算法。

    • 这不是一个非常有效的算法。我觉得它可以在O(n ^ 2)中完成,但更好的是需要创造性的数据结构。你需要能够找到比O(n)更快的长度小于给定L的最重的杆来做得更好。

答案 3 :(得分:1)

我99%肯定这可以作为一个整数背包问题加上一个额外的约束,我认为可以通过首先考虑具有起始距离条件的杆来解决这个问题。

以下是背包问题解释的链接:http://www.g12.cs.mu.oz.au/wiki/doku.php?id=simple_knapsack