algorithm - 均匀划分连续的数字序列

标签 algorithm parallel-processing partitioning

K workers 之间连续并行化 N 令人尴尬的并行工作 block 的一项常见任务是使用以下算法在伪代码中进行分区:

acc = 0
for _ in range(K):
    end = acc + ceil(N/K)
    emit acc:end
    acc = end

这将发出 K 个连续分区,通常大小为 N/K,并且适用于大的 N。但是,如果 K 大约为 N,这可能会导致不平衡,因为最后一个 worker 将获得很少的项目。如果我们将不平衡定义为分区大小之间的最大绝对差异,则迭代算法从任何随机分区开始并减少潜力,直到最大差异为 1(如果 KN) 将是最优的。

在我看来,通过执行在线“重新规划”,以下可能是获得相同答案的更有效方法。这个算法有名字和最优性证明吗?

acc = 0
workers = K
while workers > 0:
    rem = N - acc
    end = acc + ceil(rem/workers)
    emit acc:end
    acc = end
    workers -= 1

编辑。鉴于我们可以递归地定义上面的循环,我可以看到归纳最优性证明可能有效。无论如何,我们将不胜感激 :)

最佳答案

划分范围的一种简单方法是:

for i in range(K):
  emit (i*N // K):((i+1)*N // K)

这具有本身可并行化的优势,因为迭代不需要按顺序执行。

很容易证明每个分区都有 floor(N/K)ceil(N/K) 元素,而且很明显每个元素都会恰好在一个分区中。由于下限和上限最多相差 1,因此该算法必须是最优的。

您建议的算法也是最优的(并且结果相似)。不过我不知道它的名字。

另一种可以并行完成的划分范围的方法是使用范围 start(N, K, i):start(N, K, i+1) 其中 start(N, K, i)(N//K)*i + min(i, N%K)。 (注意 N//KN%K 只需要计算一次。)这个算法也是最优的,但是分配了不平衡,所以第一个分区是较大的。这可能有用也可能没用。

关于algorithm - 均匀划分连续的数字序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48052419/

相关文章:

algorithm - 将曲线图案与图像的边缘相匹配

hive - 指定分区时,Spark SQL saveAsTable 与 Hive 不兼容

postgresql - Postgres 10.3 严重分区表,无法删除任何记录

windows - 更改 Windows 中打开文件的最大数量

java - 数组写入竞争条件

sql - sql中的表分布和表分区有什么区别?

algorithm - 不规则函数的优化

algorithm - 用遗传算法逼近函数

algorithm - 你如何有效地解决这个对数不等式?

c++ - 应用程序缓冲区和系统缓冲区有什么区别