杆切割的变化(杆的尺寸可以改变)

时间:2016-09-17 20:24:27

标签: python recursion dynamic-programming

[这是一项任务,请不要给我完整的代码。] 我需要编写一个接收两个列表的函数,一个带有棒的库存(它们的大小各不相同),一个带有订单并返回" False,[]" (如果它无法回答订单)或"是的,如何"其中how_to是一个列表,其中每个项目是用于按顺序提供相应项目的杆的索引。

E.g:

stock = [100, 150]
order = [30, 60, 90, 60]
how_to = [0, 0, 1, 1]

接受任何有效的解决方案([0,0,1,1],[0,1,1,0],[1,1,0,1]等)。该函数必须是递归的。

how_to = []
def process(stock, order):

    stock_size = 0  
    order_size = 0

    for i in order:
        order_size += i
    for i in stock:
        stock_size += i

    if order_size > stock_size:
        return False, []

    elif len(order) == 0:
        return True, how_to

    else:

        for i in range(len(stock)):
            if len(stock) > 0:
                if stock[i] >= order[0]:
                    stock[i] -= order[0]
                    how_to.append(i)
                    del order[0]
                    process(stock, order)
            else:
                return True, how_to
        return False, []

这就是我写的。但是,它仅在how_to中的项目增加时才起作用(即,如果解决方案使用按顺序显示的库存)。像过程([60,70,50],[45,5,25,30,55])这样的案例不起作用。我需要帮助解决它。

我知道我的解决方案不是动态的,但它是我能想到的。

有一些要求: (1)我无法对列表进行排序。 (2)我无法在函数中添加另一个参数。

1 个答案:

答案 0 :(得分:0)

首先,让我们解开日常生活中的头脑以便于阅读。 sum 方法对列表的元素求和。因此, elif 之前的所有内容都会崩溃为:

reduce = stock[:]   # copy stock
reduce[i] -= order[0]
process(reduce, order.pop(0))

接下来,修复 for 循环控件的逻辑。编程中的一个重要概念是,一旦进入循环,您应该更改 -loop参数。在这种情况下,从循环内改变股票是个坏主意。相反,当您重复时,传入更改的参数副本,例如

for each rod in stock:
    if I can cut the first rod of the order from this,
        simulate making the cut
        update the stock
        recur on the remainder of the order
        if that recursion works,
            append the simulated cut to this solution,
            return success
# If I get here, I didn't find any solution
return failure

现在,你在递归逻辑中有一个缺陷:你永远不会使用返回结果。不要将 how_to 设为全局变量,而应将其设置为本地变量,保留找到的任何解决方案,并传回结果,添加当前剪切。

这个想法更像是这样:

if len(order) == 0:
    return True, []

...
    found, how_to = process(reduce, order[1:])
    if found:
        how_to.append(i)
    return found, how_to

顺便提一下,请注意,使用空的解决方案列表等效会失败。我不明白为什么作业你也会返回真或假。

为局部变量添加了提示:

由于您只需要一个解决方案, how_to 只是暂时的便利,如果不需要前导布尔值,则根本不存在。解决方案应该在返回值中仅存在

{{1}}

它是:如果您找到了N-1棒的解决方案,那么只需在此迭代中附加您所做的切割,然后将N棒溶液向上移动。