让我们说我们有N个垃圾箱,并且想要在给定时间段P内在每个垃圾箱上触发 目标是计算一个周期,该周期将反复重复(在过程的整个生命周期中)。事件应在此周期的重复过程中平均分配。 作为一个例子,假设我们有3个bin A,B和C,使得 目前尚不清楚这是否是最佳选择,因为B分布不均。 当然,我们无法保证事件的数量是如此精确地分配;实际上,事件的数量可能是同质的。 注意:一个同样好的循环将使Bs的任一列与As的列切换。 数量级: 一个务实的解决方案是依靠随机算法:对于上述情况,将5 As,10 Bs和15 Cs放在一个序列中,然后随机洗牌。它不是最佳的,但是具有良好的复杂性和相对分散的可能性。 我有一个暂定的Python解决方案: 哪个似乎在这个特定示例上起作用,产生: 但是我不相信(1)正确,(2)最佳。 如何将定期事件随时间均匀地分布在各个业务部门中? #[n]
事件(n
P / sum(#[n])
,都会触发一个事件。P / #[n]
。#[A] = 5
,#[B] = 10
和#[C] = 15
,那么一个好的周期可能是:[C, B, C, B, C, A,
C, B, C, B, C, A,
C, B, C, B, C, A,
C, B, C, B, C, A,
C, B, C, B, C, A]
def select_minimum(weights):
n, w = 0, weights[0][1]
for i in range(len(weights)):
if weights[i][1] < w:
n, w = i, weights[i][1]
return n
def spread_bins(bins):
total = sum(bins)
pace = [total * 1.0 / b for b in bins]
c = [(i, pace[i]) for i in range(len(bins))]
result = []
for _ in range(total):
n = select_minimum(c)
bin, w = c[n]
c = c[:n] + c[n+1:] + [(bin, w + pace[bin])]
c = [(i, w - 1) for i, w in c]
result.append(bin)
return result
[2, 1, 2, 0, 1, 2,
2, 1, 2, 0, 1, 2,
2, 1, 2, 0, 1, 2,
2, 1, 2, 0, 1, 2,
2, 1, 2, 0, 1, 2]
答案 0 :(得分:2)
请注意,您的问题在本质上等同于Bresenham line drawing algorithm。
虽然Bresehham算法将两个位移值dx
和dy
尽可能均匀地分布在dx+dy
步骤上,但是您的任务需要“更多尺寸”-N = 3..12
Bresenham算法可能会在3D情况下进行扩展,以此类推(example of 3d and 6d),但是我没有看到简洁的概括(例如,使用优先级队列来累积错误等)-也许确实存在这种概括。 (some words towards common case)
答案 1 :(得分:0)
说我们每个仓库都有一个数据结构,其中包含以下内容:
给定的bin需要(达到的值-当前值)/生长步长(四舍五入为整数)步长作为下一个元素出现。
考虑所有垃圾箱,将使用 M =步骤值的最小值触发下一个元素。
所以我们可以:
这样,我们以离散的方式推进结果,而不会丢失频率。 此外,由于初始列表的顺序,因此仅保留顺序。
在 bad Python中,可能是:
def create_bins( sizes ):
s = sum(sizes)
return [[size, s, 0, size] for size in sizes]
def div_rem( x, y ):
d = (int)(x / y)
r = x % y
if r == 0:
return d
else:
return d+1
def next_bins( bins ):
min_steps = min([div_rem(b[1]-b[2], b[3]) for b in bins])
for b in bins: b[2] = b[2] + min_steps * b[3]
result = [b for b in bins if b[2] >= b[1]]
for b in result: b[2] = b[2] - b[1]
return result
sizes = [15, 10, 5]
bins = create_bins( sizes )
result = next_bins( bins )