也许是一个微不足道的问题,但我正在寻找能够以平衡方式将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
作为启发式算法的贪婪算法可以做得很好,但不确定是否存在一些极端情况。
谢谢,
答案 0 :(得分:2)
这个问题实际上是不 NP-hard,因为不可能重新组合这些部分。这里是用于确定切割以最小化所得片段的长度的平方和的问题的O(m log n)时间算法。将每个段的拆分计数初始化为一个并将它们放入优先级队列(我将很快指定优先级)。重复以下操作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。
这个"贪婪的原因"算法是最优的是因为将一个分段分成更多个部分的回报是独立的,并且在精确的技术意义上(超模块)逐渐减少。