Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 棒料切割的变化(棒料尺寸可能变化)_Python_Recursion_Dynamic Programming - Fatal编程技术网

Python 棒料切割的变化(棒料尺寸可能变化)

Python 棒料切割的变化(棒料尺寸可能变化),python,recursion,dynamic-programming,Python,Recursion,Dynamic Programming,[这是作业,请不要给我完整的代码。] 我需要编写一个函数来接收两个列表,一个是棒的库存(它们的大小不同),另一个是顺序,并返回“False、[](如果不可能回答顺序)或“True,how_to”,其中how_to是一个列表,其中每个项都是用于按顺序为相应项提供棒的索引 例如: 接受任何有效的解决方案([0,0,1,1]、[0,1,1,0]、[1,1,0,1]等)。函数必须是递归的 how_to = [] def process(stock, order): stock_size = 0

[这是作业,请不要给我完整的代码。] 我需要编写一个函数来接收两个列表,一个是棒的库存(它们的大小不同),另一个是顺序,并返回“False、[](如果不可能回答顺序)或“True,how_to”,其中how_to是一个列表,其中每个项都是用于按顺序为相应项提供棒的索引

例如:

接受任何有效的解决方案([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中的项目增加时才起作用(即,如果解决方案使用出现的订单中的库存)。像process([60,70,50],[45,5,25,30,55])这样的案例不起作用。我需要帮助修理它

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

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

首先,让我们折叠例程的开头以便于阅读。sum方法对列表中的元素求和。因此,您的elif之前的所有内容都会崩溃为:

if sum(order) > sum(stock):
   return False, []
接下来,修复循环控制的逻辑。编程中的一个重要概念是,一旦进入循环,就不应更改-循环参数的。在这种情况下,从循环内部更改股票是个坏主意。相反,当您再次出现时,请传入参数的更改副本,例如

reduce = stock[:]   # copy stock
reduce[i] -= order[0]
process(reduce, order.pop(0))
现在,递归逻辑中有一个缺陷:从不使用返回结果。与其将how_to设置为全局变量,不如将其设置为局部变量,保留找到的任何解决方案,并将结果传回,添加当前切割

这个想法更像这样:

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
顺便说一下,请注意,拥有一个空的解决方案列表相当于失败。我不明白为什么作业让你也返回True或False


为局部变量添加了提示:

由于您只需要一个解决方案,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

就是这样:如果你找到了一个N-1棒的解决方案,那么只需附加你在这个迭代中所做的切割,并将N棒的解决方案向上传递。

这个代码不是递归的。它需要是一个函数
exability(stock,order,how\u to)
,它会调用自己,每次从列表
order
@smci how\u to中取消一个元素的匹配都是一个全局变量,所以我想它做的事情与exability(stock,order,how\u to)做的事情是一样的。它是递归的,因为它有一个基本情况(order是空的),它调用自己,每次它接近基本情况时(通过检查后删除order的一个元素),不是吗?在递归方法中,没有“全局变量”。递归函数只需将
how_传播到
作为其结果进行备份。事实上,您不需要返回元组
True,how\u to
,因为我们可以从
how\u to
为非空的事实推断它是可行的。我会在回答中略述这一点。你说的“新月”是什么意思?增加的?你不能保证会有一个非递减的解决方案。例如,([10,20],[20,10])只有一个解:[1,0],其中的to是递减的。如果您的意思是其他参数之一必须是非递减的,那么只需注意原始顺序,对列表排序,调用函数,然后对解应用逆变换即可。谢谢!我没有使用sum(),因为我们需要手动编写所有内容,从sort()到sum()等等。您的回答非常有用,但我仍然没有弄清楚如何将u转换为局部变量:如果我在进程内编写它,每次调用它(用于递归)时它都会重新启动,结果会丢失。如果我能把它作为一个论点来通过,我会知道怎么做,但既然我不能。。。
if len(order) == 0:
    return True, []

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