algorithm - 有什么算法可以平衡地将N条线段分割成M条线(N <= M)?

标签 algorithm

也许是一个微不足道的问题,但我正在寻找一种算法,可以以平衡的方式将 N 线段分割成 M 段(M >= N)(例如,R^2 r 平方最大化)。有人有好的引用吗?

编辑(根据评论者的要求添加示例):

例如,让 N = 5长度段:{1, 10, 7, 15, 1}我们想把它分成 M = 7零件。

  • 一个好的解决方案是:{1, 1, 5, 5, 7, 7, 8} (分为 15 和 10)
  • 一个糟糕的解决方案是:{1, 1, 5, 5, 5, 7, 10} (将 15 分成 3)

我猜,是一个贪婪算法 distance from avg作为一种启发式方法可以做得很好,但不确定是否存在一些极端情况。

谢谢

最佳答案

这个问题实际上不是 NP-hard,因为不可能重新组合各个部分。这是一个 O(m log n) 时间算法,用于解决确定切割以最小化所得碎片长度平方和的问题。将每个段的分割计数初始化为 1,并将它们放入优先级队列中(我将很快指定优先级)。重复以下操作 m - n 次:拉出最上面的段(最高优先级),增加其拆分计数,然后将其放回队列中。

每个段的优先级是其当前划分的平方和减去其假设划分为另一段的平方和。例如,如果 15 当前被分割为两部分,7 和 8,我们可以将其分割为三部分,即 5、5 和 5,则优先级为 7^2 + 8^2 - 5^2 - 5^2 - 5^2 = 38。为了运行您的示例,初始优先级队列是

15 (1 cut), priority 15^2 - 7^2 - 8^2 = 112
10 (1 cut), priority 10^2 - 5^2 - 5^2 =  50
 7 (1 cut), priority  7^2 - 3^2 - 4^2 =  24
 1 (1 cut), priority  1^2 - 0^2 - 1^2 =   0
 1 (1 cut), priority  1^2 - 0^2 - 1^2 =   0.

我们又分了15次。

10 (1 cut ), priority 10^2       - 5^2 - 5^2       = 50
15 (2 cuts), priority  7^2 + 8^2 - 5^2 - 5^2 - 5^2 = 38
 7 (1 cut ), priority  7^2       - 3^2 - 4^2       = 24
 1 (1 cut ), priority  1^2       - 0^2 - 1^2       =  0
 1 (1 cut ), priority  1^2       - 0^2 - 1^2       =  0.

我们又分了10次。

15 (2 cuts), priority 7^2 + 8^2 - 5^2 - 5^2 - 5^2 = 38
10 (2 cuts), priority 5^2 + 5^2 - 3^2 - 3^2 - 4^2 = 16
 7 (1 cut ), priority 7^2       - 3^2 - 4^2       = 24
 1 (1 cut ), priority 1^2       - 0^2 - 1^2       =  0
 1 (1 cut ), priority 1^2       - 0^2 - 1^2       =  0.

我们就到此为止;接下来是 15,即 1, 1, 5, 5, 5, 5, 5, 7。

这种“贪婪”算法是最优的,因为将一个片段分割成更多片段的返回是独立的,并且在精确的技术意义上是递减的(超模块化)。

关于algorithm - 有什么算法可以平衡地将N条线段分割成M条线(N <= M)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23268085/

相关文章:

algorithm - A* 算法示例 - 是否正确

algorithm - 为什么对本地列表求和比用 `GHC -O2` 对教堂编码列表求和慢?

algorithm - DPLL算法和访问节点数

algorithm - 棘手的算法题

找到多个方程的评估顺序的算法

algorithm - 如何解决带间隙条件的LCS(最长公共(public)子序列)

algorithm - 验证无向树中最长路径的不同方法

java - Karger MinCut Java Large Input Error 的 Minimum Cut

java - 生成一个偏离两极的随机纬度

c++ - 如何使用动态编程自顶向下方法解决这个问题?