【问题标题】:Split array into sub-arrays of similar weight将数组拆分为权重相似的子数组
【发布时间】:2018-10-24 01:54:39
【问题描述】:

我有一个n 正数数组。我需要将其拆分为N 连续子数组; n > N.

我需要最小化[max S(j) over j] - [min S(j) over j], 其中S(j) 表示j-th 子数组(j = 1,...,N) 中元素的总和。

即,所有子数组都应具有“相同”的元素总和。

我确定这个问题是已知的。有人可以指出我的算法、实现或出版物吗?

【问题讨论】:

  • 快速(线性算法)逼近:stackoverflow.com/questions/52094356
  • @MBo 谢谢。我想知道,准确地解决我的问题是否是 NP-hard...
  • 范忠的方法似乎合理
  • @MBo 不,它不起作用:查看我对他的帖子的评论

标签: algorithm optimization load-balancing mathematical-optimization


【解决方案1】:

这个问题相当于求max S(j) over all j的最小值。

直觉:

  • 假设所有可能的max S(j) over all j 中的最小值为xmax,因此结果将为xmax - xmin

  • 假设,另一个 ymax > xmax 可以为我们提供更好的结果,这意味着 ymax - ymin xmax - xmin -> ymin > xmin -> min S(j) - ymax > min S(j) - xmax,这不应该发生。

所以,问题归结为找到max S(j) over all j 的最小值

这可以通过使用二分查找来解决。 假设整个数组的总和是X,所以我们有我们的算法:

int start = 0;
int end = X;
int result = 0;
while(start <= end){
    int mid = (start + end)/2;
    for(int i = 0; i < n; i++){
       if sum of current segment > mid
           split

    }
    if total segment > N
       start = mid + 1;
    else 
       update result;
       end = mid - 1;
}

【讨论】:

  • 我不同意。考虑将[10 7 3 4] 拆分为 3 个子数组。寻找max 中的min 给出了2 个等效答案:10 | 7 3 | 410 | 7 | 3 4。寻找max - min 中的min 只能给出一个最佳答案:10 | 7 | 3 4
【解决方案2】:

找到整个数组的总和并调用它T,然后执行k = T / N 来确定第一个子数组元素的理想总和。然后线性创建第一个子数组(从数组的开头开始),同时在决定子数组是否应该/不应该包含下一个元素时尝试最小化ksum of all values in the sub-array so far + potential next element 之间的差异。

然后使用递归将数组的剩余部分拆分为N-1 块,当N == 1 时停止(数组的剩余部分是最后一个子数组)。

注意:这并不是在所有情况下都提供最佳解决方案,但它相对较快,并且出于(动态)负载平衡的目的,负载会经常变化,以至于任何更昂贵的东西(即总能找到最优解)是没有意义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    相关资源
    最近更新 更多