将任务分配给两台打印机的算法?

时间:2016-03-08 13:04:06

标签: python algorithm time-complexity distribution

我正在网上进行编程练习,我发现了这个问题:

  

两台打印机以不同的速度工作。第一台打印机在x分钟内生成一张纸,而第二台打印机在y分钟内生成一张纸。要总共打印N份论文,如何将任务分配给这些打印机,以便打印时间最短?

练习为我提供了三个输入xyN,并要求输出最短时间。

  

输入数据:

     

1 1 5

     

3 5 4

     

答案:

     

3 9

我尝试将第一台打印机的任务设置为a,将第二台打印机的任务设置为N-a。最有效的打印方式是让它们具有相同的时间,因此最小时间为((n * b)/(a + b))+ 1。但是这个公式是错误的。

然后我尝试用蛮力的方式来解决这个问题。我首先在ab中区分哪一个更小(更快)。然后我继续向更快的打印机添加一张纸。当打印机所需的时间比打印另一台打印机的一张纸的时间长时,我将一张纸送到较慢的打印机,然后减去更快打印机的时间。

代码如下:

def fastest_time (a, b, n):
""" Return the smalles time when keep two machine working at the same time.
    The parameter a and b each should be a float/integer referring to the two
    productivities of two machines. n should be an int, refering to the total 
    number of tasks. Return an int standing for the minimal time needed."""

    # Assign the one-paper-time in terms of the magnitude of it, the reason 
    # for doing that is my algorithm is counting along the faster printer.
    if a > b:
        slower_time_each = a
        faster_time_each = b

    elif a < b :
        slower_time_each = b
        faster_time_each = a

    # If a and b are the same, then we just run the formula as one printer
    else :
        return (a * n) / 2 + 1

    faster_paper = 0
    faster_time = 0
    slower_paper = 0

    # Loop until the total papers satisfy the total task
    while faster_paper + slower_paper < n:

        # We keep adding one task to the faster printer
        faster_time += 1 * faster_time_each
        faster_paper += 1

        # If the time is exceeding the time needed for the slower machine,
        # we then assign one task to it
        if faster_time >= slower_time_each:
            slower_paper += 1
            faster_time -= 1 * slower_time_each

    # Return the total time needed
    return faster_paper * faster_time_each

N较小或xy较大时,它可以正常工作,但需要花费大量时间(我猜超过10分钟)来计算{{1} }和x非常小,即输入为y

我相信有一个更好的算法来解决这个问题,有人可以给我一些建议或提示吗?

1 个答案:

答案 0 :(得分:1)

给出表格中的输入

x, y, n = 1, 2, 159958878

这应该有效

import math
math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y))

这适用于所有样本输入。

In [61]: x, y, n = 1,1,5

In [62]: math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y))
Out[62]: 3.0

In [63]: x, y, n = 3,5,4

In [64]: math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y))
Out[64]: 9.0

In [65]: x, y, n = 1,2,159958878

In [66]: math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y))
Out[66]: 106639252.0

修改

这不适用于@Antti提到的情况,即x, y, n = 4,7,2

原因是我们首先考虑的是较短的时间。因此,解决方案是找到两个值,即考虑更短的时间和考虑更长的时间,然后选择结果值中较小的一个。

因此,这适用于包括@ Antii的所有案例

min((math.ceil((max((x,y)) / float(x+y)) * n) * min((x,y)),
     math.ceil((min((x,y)) / float(x+y)) * n) * max((x,y))))

虽然可能会出现一些极端情况,您可能需要稍微更改一下。