用浮点数除以整数,得到比例整数

时间:2015-02-09 01:33:36

标签: algorithm integer division integer-division

最近我在做项目时遇到了一个难以解决的问题。我想问你们一个解决它的解决方案/算法,因为我真的很难想到这样做的聪明主意。

我有任意数量的花车:

  • f1,f2,...,fn 其中 f1 + f2 + ... + fn = 1

和一个整数:

  • 其中 I> 0

我需要将整数 I 划分为浮点数,就像我分发不可分割的东西一样。所以基本上这个比例在某种意义上必须保持,因为最大的浮动必须得到最大的整数。一个好的比喻就好像我在分割那些无法分割的股票。

如果第一个投资者拥有0.6%的股票而第二个投资者拥有0.4个股票,那么给定1个股票进行拆分,我会将其交给第一个(100%0%)。如果有2只股票,我会给第一只和第一种(50%50%)。请注意,我总是希望拆分尽可能成比例(接近60%40%)。

问题本身并没有非常明确的定义,但是应该知道应该发生什么,不应该发生什么。一些容易出现在我脑海中的例子是:

  1. 如果: f1 = 0.4,f2 = 0.3,f3 = 0.3,I = 1 那么我需要 f1-result = 1,f2-result = 0,f3-结果= 0

  2. 如果: f1 = 0.4,f2 = 0.4,f3 = 0.2,I = 1 那么我需要 f1-result = 1,f2-result = 0,f3- result = 0 f1-result = 0,f2-result = 1,f3-result = 0

  3. 如果: f1 = 0.6,f2 = 0.25,f3 = 0.15,I = 5 那么我需要 f1-result = 3,f2-result = 2,f3-结果= 1

3 个答案:

答案 0 :(得分:2)

至少在最初阶段我是如何接近它的。

每个桶都有所需的量。这是基于它们的浮点值,并且所有浮点值总和为1。

所以,仔细阅读"对象"一个接一个地分发。要确定哪个桶获得它,您需要找到低于所需数量的存储桶的最大差异(如果在所需级别下有多个等于它们,则选择第一个)。这是"最不快乐的"桶。

然后将该对象分发到该存储桶,调整数字并移至下一个对象。这意味着一个物体总是以这样的方式分布,使不幸的水桶的生活更好一点(好悲伤,这听起来像我是一个社会工作者)。

举例来说,让我们开始根据上述算法将对象分配给三个桶(分别需要50%,30%和20%)。

括号中的第二个数字是每个桶与其所需百分比的偏差,因此,在每个阶段,我们选择最低于所需水平的桶,最不快(由*表示):

BucketA (50%)  BucketB (30%)  BucketC (20%)
-------------  -------------  -------------
 0 (0%,-50*)    0 (0%,-30)     0 (0%,-20)
 1 (100%,+50)   0 (0%,-30*)    0 (0%,-20)
 1 (50%,+0)     1 (50%,+20)    0 (0%,-20*)
 1 (33%,-17*)   1 (33%,+3)     1 (33%,+13)
 2 (50%,+0)     1 (25%,-5*)    1 (25%,+5)
 2 (40%,-10*)   2 (40%,+10)    1 (20%,+0)
 3 (50%,+0)     2 (33%,+3)     1 (17%,-3*)
 3 (43%,-7*)    2 (29%,-1)     2 (29%,+9)
 4 (50%,+0)     2 (25%,-5*)    2 (25%,+5)
 4 (44%,-6*)    3 (33%,+3)     2 (22%,+2)
 5 (50%,+0)     3 (30%,+0)     2 (20%,+0)

请注意,初始条件包含0%处的所有存储桶,即使它技术上不正确(它可以很容易地被视为100%甚至{{ {1}}基于计算的未定义的零除零性质。但是,这是确保初始分配到需要最高百分比的存储桶的好方法,之后百分比变得很明确。

从上面的表格中可以看出,物体的分布最终会导致预期的结果。


而且,如果您想要一些代码,您可以使用它来实现这一点(让我们面对它,不会想要那个?),请参阅以下内容Python程序:

3.14159%

输出:

desiredPct = [50, 30, 20]
bucket = [0, 0, 0]
count = 0

# Allocate first item specially so no concern with div-by-zero.

idx = desiredPct.index(max(desiredPct))
happy_min = -desiredPct[idx]
bucket[idx] += 1
count += 1

actualPct = [x * 100 / count for x in bucket]
print "Unhappiest %6.2f @ %d, want %s%%, have %s (%s%%)" % (happy_min, idx, desiredPct, bucket, actualPct)

# Allocate all others in loop.

for i in range(99):
    # Get most disadvantaged bucket.

    idx = 0
    happy_min = bucket[idx] * 100 / sum(bucket) - desiredPct[idx]
    for j in range(1, len(bucket)):
        happy = bucket[j] * 100 / sum(bucket) - desiredPct[j]
        if happy < happy_min:
            idx = j
            happy_min = happy

    bucket[idx] += 1
    count += 1
    actualPct = [x * 100 / count for x in bucket]
    print "Unhappiest %6.2f @ %d, want %s%%, have %s (%s%%)" % (happy_min, idx, desiredPct, bucket, actualPct)

这也表明,一旦你第一次获得所需的结果,对象的分布往往会接近你想要的。

答案 1 :(得分:1)

投资者j应至少获得floor(fj*I)份。要分配超额份额,首先确定其数量(x = I - sum(floor(fj*I) for all j)),然后选择分数数组x中的fj*I - floor(fj*I)最大元素。比这更大一点的每个人都可以获得更多份额;具有这一分数的人可以根据需要获得一个或零,以使总数有效。

运行时间为O(n),其中n为投资者数量。

答案 2 :(得分:0)

您使用 f1 + f2 + .... + fn = 1 启动了问题,但最后只提到了三个浮点数。 解决这个问题的简单方法是将最小的 fi 乘以10(10 ^ p)的幂,以获得整数值。你从整数(10 ^ p)中减去要分配的金额,以计算出从每个浮点数到达分配金额需要多少钱,假设你带来的额外金额最多为(10 ^ p)每个人获得其共享时间(10 ^ p)。 您通过重复计划执行此操作,首先您从每个浮动收回超过分配金额的金额。在下一次迭代中,您从每个浮点数中收集一个单位,按升序排序,但您应该考虑不要为负数。测试你是否在每次扣除后获得全部金额。

所以举例说明 f1 = 0.6,f2 = 0.25,f3 = 015,I = 5。 用f(i,j)声明浮点数矩阵f,其中i = 3且j = 2,它是两列和三行的矩阵。将浮点数存储在第一列中并对矩阵进行升序排序。访问矩阵f(1,1)的第一个元素得到0.15。 将其转换为整数,因为It = f(1,1)*(10 ^(小数位数(f(1,1))),我们得到It = 0.15 *(10 ^ 2)。即它= 15。矩阵第二列,带整数

f(1,2)=15
f(2,2)=25
f(3,2)=60

现在我必须收回10 ^ 2-5 = 95的金额。设置它= 95。第一轮,每个拥有超过5的人都会给予超额回报。所以我得到以下内容(为了简化示例,我正在跳过测试f(i,2)&gt; 5)

10 = f(1,2)-5; f(1,2)=f(1,2)-10
20 = f(2,2)-5; f(2,2)=f(2,2)-20 
55 = f(3,2)-5; f(3,2)=f(3,2)-55

直到知道我声称回复 10 + 20 + 55 = 85 。我必须去另一个。现在每个人有五个。这是三次迭代。循环的第一次第二次和第三次运行将从每个单位获得一个单位。 现在我回到了94 我仍然需要一个单位,这将是从f(2,1)和循环声明的将离开,因为我已达到我的95单位。在三次迭代和第四次迭代的一步之后,我的最终矩阵是

  f(1,2)=1, 
  f(2,2)=2, 
  f(2,3)=2.

其中显而易见的原因总计为5 迭代算法很简单。它迭代f(i,2)。它测试f(i,s)> 0,然后它从f(i,2)中扣除一个单位;将此单位添加到目前为止要求的金额,并测试金额是否等于要返还的总金额。如果是真的话会破坏循环。

相关问题