就算法而言,我有一点普遍的头脑。我使用ruby但这可能是一个普通的编程问题。以下是业务要求:
让我们说我们有5个销售代表,每个销售代表都有一定比例的积压工作(工作要做)。让我们说积压是价值50万美元的工作。每个销售代表都有一定比例。这是一个任意的例子:
现在假设我们想要分配一定数量的工作人员,这些销售代表可以分配这些工作来完成这项工作。例如,假设有50名工人可以根据这些百分比来分配。
我如何确保根据百分比均匀分配,但确保只使用/全部50名工人? (如果我只是对数字进行四舍五入,你最终会得到51或49)?
答案 0 :(得分:1)
始终使用较低的结果,在这种情况下为49,然后使用第二个例程来优先考虑余数的分布情况,例如:按最高百分比或最佳销售人员等。将清单称为剩余分配清单。
现在因为剩余部分总是小于除数,从剩余分布列表中的顶部项开始,将一个分配到列表顶部,然后分配到列表中的下一个,等等。当你离开时单位你完成。在您的情况下,您只有一个单位要分发,所以您只分发一个。
我在从仓库分发包时遇到了类似的问题。适用于模数运算。
答案 1 :(得分:0)
" ...确保它们均匀分配......"很模糊如果将其视为优化问题,我们需要对要最小化的偏差进行数值测量。例如,如果其中一个销售代表根据销售百分比分配了15
个工作人员但应该{{1}},那么偏差可以被视为14.3
。如果我们希望最小化所有销售代表的最大偏差,可以使用整数编程获得最佳解决方案。
显然需要更简单的东西。根据销售百分比,我倾向于按销售顺序将工人分配给销售代表,从最低到最高,分离浮动。
<强>代码强>
(15-14.3).abs #=> 0.7
示例强>
def allocate_workers(sales, workers)
tot_sales = sales.values.sum.to_f
sales.sort_by(&:last).each_with_object({}) do |(rep, amt),h|
h[rep] = (workers * amt/tot_sales).round
tot_sales -= amt
workers -= h[rep]
end
end
<强>解释强>
对于上面的例子,步骤如下。
sales = { A: 53_230, B: 102_202, C: 72_694, D: 129_230, E: 142_644 }
workers = 50
allocate_workers(sales, workers)
#=> {:A=>5, :C=>7, :B=>10, :D=>13, :E=>15}
生成枚举器a = sales.values
#=> [53230, 102202, 72694, 129230, 142644]
b = a.sum
#=> 500000
tot_sales = b.to_f
#=> 500000.0
c = sales.sort_by(&:last)
#=> [[:A, 53230], [:C, 72694], [:B, 102202], [:D, 129230], [:E, 142644]]
e = c.each_with_object({})
#=> #<Enumerator: [[:A, 53230], [:C, 72694], [:B, 102202], [:D, 129230],
# [:E, 142644]]:each_with_object({})>
的第一个元素并将其传递给块,为块变量赋值。
e
所以代表(rep, amt),h = e.next
#=> [[:A, 53230], {}]
rep
#=> :A
amt
#=> 53230
h
#=> {}
f = amt/tot_sales
#=> 0.10646
m = workers * f
#=> 5.323
h[rep] = m.round
#=> 5
tot_sales -= amt
#=> 446770.0
workers -= h[rep]
#=> 45
已分配:A
名工作人员(从5
四舍五入),剩下的5.323
代表将剩下45名工作人员,其总销售额为{{ 1}}。
生成枚举器4
的下一个元素并将其传递给块,从而导致块变量具有以下值。
500000.0 - 53230 #=> 446770.0
请注意,e
(将返回)已更新。其余的计算遵循传递给块的(rep, amt),h = e.next
#=> [[:C, 72694], {:A=>5}]
rep
#=> :C
amt
#=> 72694
h
#=> {:A=>5}
的第一个元素。
当处理具有最大销售额(h
)的销售代表时,块变量将为
e
我们将
:E
所以代表rep
#=> :E
amt
#=> 142644
h
#=> {:A=>5, :C=>7, :B=>10, :D=>13}
将全部给出
tot_sales
#=> 142644.0 (approx.)
workers
#=> 15
剩下的工人。