Skip to content

搞英语 → 看世界

翻译英文优质信息和名人推特

Menu
  • 首页
  • 作者列表
  • 独立博客
  • 专业媒体
  • 名人推特
  • 邮件列表
  • 关于本站
Menu

将数组划分为适当大小的块

Posted on 2025-05-23

假设你有一个包含 N 个元素的数组,你想将其分成 M 个块。例如,当尝试将 N 个工作单元分散到 M 个线程上时,这是一个常见的任务。

您希望所有块的大小相同,上下浮动一个元素(合理大小)。这可能比您想象的要难一些。

按照 Python 的约定,a//b 是整数商,因此 5//2 为 2。令 % 为“余数”:5%2 为 1。

朴素算法使用以下块范围:[0, N//M), [N/M, 2*N//M)… 直到 [N//M*M, N)。因此,所有块的大小均为 N/M,但存在一个大小为 N%M 的额外块。

如果 N 为 5 且 M 为 2,则我们有块 [0,2)、[2,4)、[4,5]。

这可不太好。我们多了一个块!至少当 N//M 至少为 1 时是这样。

相反,我们可以让最后一个块更大一些。我们使用的范围是 [0, N//M), [N/M, 2*N//M)… 直到 [N//M*(M-1), N)。如果 N 为 5,M 为 2,那么块数就是 [0,2), [2,5)。至少我们有正确数量的块。

但是如果 N 是 20,M 是 6 呢?我们会得到 [0,3), [3,6), [6,9), [9,12), [12,15), [15,20] 这很糟糕,因为最后一个块要大得多。

相反,您可以尝试以下方法:让块大小为 ceil(N/M)。也就是说,块大小是 N/M 向上舍入。因此,如果 N 为 5 且 M 为 2,则块大小为 ceil(5/3) 或 3。我们使用块范围:[0, ceil(N/M)), [N/M, 2*ceil(N/M))…[(M-1)*ceil(N/M), N)。如果 N 为 5 且 M 为 2,则块为 [0,3), [3,5)。这样要好得多。这次,我们有正确数量的块。一个大小为 3,另一个大小为 2。但如果 N 为 12 且 M 为 5,则失败。我们得到块大小为 3,因此范围为 [0,3), [3,6), [6,9), [9, 12)。所以我们缺少一个块!

那么你应该怎么做呢?更好的方法是让前 N%M 个块的大小为 ceil(N/M),让剩余的 NN%M 个块的大小为 floor(N/M)。

让我用 Python 实现它。get_chunk_range_simple 函数将总共 N 个元素分成 M 个块,并返回第 i 个块(从 0 开始索引)的起始和结束索引。它通过将余数分配到各个块来处理不均匀的划分:第一个余数块(其中余数 = N % M)的大小商为 + 1(其中商 = N // M),而其余块的大小商为。对于给定的块索引 i,该函数将起始值计算为商 * i + min(i, remainder),其中考虑了前面块中的额外元素,并将结束值计算为商 * (i + 1) + min(i + 1, remainder),以确保范围反映先前块大小的累积效应。这种方法确保覆盖所有元素,并且前面的块吸收余数以实现均衡分布。

 def get_chunk_range_simple ( N , M , i ) : 商,余数= divmod ( N , M ) 返回(商* i + min ( i ,余数) , 商* ( i + 1 ) + min ( i + 1 ,余数) )

结果大小适中。我们来举例说明一下 N 为 20、M 为 6 的情况。

我们也可以用 C++ 来实现它。为了方便修改,我返回给定块的索引和长度。

 // N 是元素总数 // M 是块的数量 // i 是块的索引(从 0 开始) std :: pair < size_t , size_t > get_chunk_range_simple ( size_t N , size_t M , size_t i ) { // 计算商和余数 size_t商= N / M ; size_t余数= N % M ; size_t start =商* i + ( i <余数? i :余数) ; size_t长度=商+ ( i <余数? 1 : 0 ) ; 返回{开始,长度} ; }

来源:该问题由罗伯特·克劳塞克 (Robert Clausecker) 在 X 上发布。

原文: https://lemire.me/blog/2025/05/22/dividing-an-array-into-fair-sized-chunks/

本站文章系自动翻译,站长会周期检查,如果有不当内容,请点此留言,非常感谢。
  • Abhinav
  • Abigail Pain
  • Adam Fortuna
  • Alberto Gallego
  • Alex Wlchan
  • Answer.AI
  • Arne Bahlo
  • Ben Carlson
  • Ben Kuhn
  • Bert Hubert
  • Bits about Money
  • Brian Krebs
  • ByteByteGo
  • Chip Huyen
  • Chips and Cheese
  • Christopher Butler
  • Colin Percival
  • Cool Infographics
  • Dan Sinker
  • David Walsh
  • Dmitry Dolzhenko
  • Dustin Curtis
  • Elad Gil
  • Ellie Huxtable
  • Ethan Marcotte
  • Exponential View
  • FAIL Blog
  • Founder Weekly
  • Geoffrey Huntley
  • Geoffrey Litt
  • Greg Mankiw
  • Henrique Dias
  • Hypercritical
  • IEEE Spectrum
  • Investment Talk
  • Jaz
  • Jeff Geerling
  • Jonas Hietala
  • Josh Comeau
  • Lenny Rachitsky
  • Liz Danzico
  • Lou Plummer
  • Luke Wroblewski
  • Matt Baer
  • Matt Stoller
  • Matthias Endler
  • Mert Bulan
  • Mostly metrics
  • News Letter
  • NextDraft
  • Non_Interactive
  • Not Boring
  • One Useful Thing
  • Phil Eaton
  • Product Market Fit
  • Readwise
  • ReedyBear
  • Robert Heaton
  • Ruben Schade
  • Sage Economics
  • Sam Altman
  • Sam Rose
  • selfh.st
  • Shtetl-Optimized
  • Simon schreibt
  • Slashdot
  • Small Good Things
  • Taylor Troesh
  • Telegram Blog
  • The Macro Compass
  • The Pomp Letter
  • thesephist
  • Thinking Deep & Wide
  • Tim Kellogg
  • Understanding AI
  • 英文媒体
  • 英文推特
  • 英文独立博客
©2025 搞英语 → 看世界 | Design: Newspaperly WordPress Theme