如何根据百分比将整数除以整数?

时间:2017-03-10 13:31:13

标签: ruby algorithm math

就算法而言,我有一点普遍的头脑。我使用ruby但这可能是一个普通的编程问题。以下是业务要求:

让我们说我们有5个销售代表,每个销售代表都有一定比例的积压工作(工作要做)。让我们说积压是价值50万美元的工作。每个销售代表都有一定比例。这是一个任意的例子:

  • 销售代表A:53,230美元(预算的10.646%)
  • 销售代表B:102,202美元(预算的20.4404%)
  • 销售代表C:72,694美元(预算的14.5388%)
  • 销售代表D:129,230美元(预算的25.846%)
  • 销售代表E:142,644美元(预算的28.5292%)

现在假设我们想要分配一定数量的工作人员,这些销售代表可以分配这些工作来完成这项工作。例如,假设有50名工人可以根据这些百分比来分配。

我如何确保根据百分比均匀分配,但确保只使用/全部50名工人? (如果我只是对数字进行四舍五入,你最终会得到51或49)?

2 个答案:

答案 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
剩下的工人。