【问题标题】:Design an algorithm that minimises the load on the most heavily loaded server设计一种算法,使负载最重的服务器上的负载最小化
【发布时间】:2021-11-05 22:21:38
【问题描述】:

阅读 Aziz & Prakash 2021 的书我有点卡在问题 3.7 以及我正在尝试实施的相关解决方案上。

问题说:

您有 n 个具有唯一哈希值 h1 到 hn 的用户,并且 m 个服务器,编号为 1 到 m。用户 i 有 Bi 字节要存储。你需要 找到数字 K1 到 Km 使得所有用户之间的哈希值 Kj 和 Kj+1 被分配给服务器 j。设计一个算法来找到 数字 K 1 到 Km,将最重的负载降至最低 加载的服务器。

解决方案说:

令 L(a,b) 为服务器上的最大负载,当 具有哈希 h1 到 ha 的用户被分配到服务器 S1 到 Sb 一种最佳方式,使最大负载最小化。我们观察到 以下重复:

换句话说,我们找到正确的 x 值,这样如果我们打包 b - 1 个服务器中的前 x 个用户,最后一个服务器中的剩余用户最大 给定服务器上的负载最小化。 使用这种关系,我们可以将 L 的值制成表格,直到我们得到 L(n,m)。在将 L 的值制成表格时计算 L(a,b) 对于 a 和 b 的所有较低值,我们需要找到 x 的正确值 最小化负载。当我们增加 x 时,上式中的 L(x,b-1) 增加,总和项减少。我们可以对 x 进行二分搜索以找到使它们的最大值最小的 x。

我知道我们可能可以使用某种动态编程,但是我们怎么可能将这个想法实现到代码中呢?

【问题讨论】:

  • 约束看起来很重,你可以使用贪心算法。不需要任何花哨的东西。

标签: recursion dynamic-programming


【解决方案1】:

动态规划算法的定义相当好,给出了这个公式:实现一个自上而下的 DP 算法只需要你从 x = 1 to a 循环并记录哪个最小化 max(L(x,b-1), sum(B_i)) 表达式。

但是,对于这个问题,您应该考虑一种更简单(更快)的贪婪/二分搜索算法,如下所示:

  1. 计算 B 的前缀总和

  2. 找到L的最小值,这样我们就可以将B划分为m个最大和等于L的连续子数组。

    • 我们知道 1 canSplit(v) 测试我们是否可以将 B 拆分为 sum v 的子数组。
    • canSplit(v) 贪婪地工作:从 B 的开头删除尽可能多的元素,这样我们的总和就不会超过 v。重复此操作共 m 次;如果我们使用了所有的 B,则返回 True。
    • 您可以使用前缀 sum 在 O(m log n) 时间内运行 canSplit,并进行额外的内部二分搜索。
  3. 给定L,使用与canSplit函数相同的策略来确定m-1个分割点;从那里找到 m 个分区边界。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多