我需要设计一个算法,从python中的列表中找到最优的元素。我有一张持有700mb的CD。并且随机生成300个文件大小的数组,从30 - 90 mb变化。它需要以最佳的方式填充cd,最小的空间被浪费(查看所有可能的方式)我猜它类似于背包问题,只是它只有1个数组和一个限制。 由于我对算法和数据结构场景完全不熟悉,我不知道如何使用python实现它
提前致谢
答案 0 :(得分:4)
@payne在评论中指出,这与背包问题非常相似。因此,该解决方案是一种简单的动态编程算法。
假设文件在列表中以某种顺序一个接一个地排列。首先,您可以选择包含第一个文件或跳过它。如果选择包含它,则可用空间将减少该文件的大小。如果您选择跳过它,则可用空间保持不变。现在,您可以在两个州中到达第二个文件。在一个中,您选择了第一个文件,因此占用的空间较少,而在另一个文件中,您跳过了第一个文件并拥有更多空间。对于这些方案中的每一个,您可以再次选择包含或跳过第二个文件。
请注意,您可以仅根据您当前正在考虑的文件以及您拥有的可用空间来定义您的状态。一旦你移过最后一个文件或空间已用完,你已经走到了那一行选择的末尾。
这会产生一个简单的重复:
min_waste(index,space)={
o if space=0 # no more space available, so 0 wastage
space if index>=size(files) # no more files left, whatever is left is wasted
min_waste(index+1,space) if size(files[index])>space # current file is too large skip ahead
min( min_waste(index+1,space), min_waste(index+1,space-size(files[index])) ) otherwise
# minimum of choosing this one and skipping ahead
}
您可以选择通过向下填充表格(即2D数组)来实现此功能,或者只是将其写为递归函数并进行记忆。
这为您提供了最小的浪费,但没有选择哪个文件来实现它。但是您可以轻松地修改它以保存有关在每个状态中所做选择的信息,并使用它来构建从起始状态开始的一系列选择。
答案 1 :(得分:2)
找到绝对最佳的方式可能效率不高。但是你可以使用一些经验法则,比如首先获取最大的文件,然后用第一个适合的文件填充剩余的空间,直到空间太小而不再适合。见Bin Packing Problem。最优的简单算法是First Fit Decreasing。按大小从最大到最小排序所有文件。然后将每个文件放在第一张CD上,在那里有足够的空间让它适合,直到所有文件都用完为止。
修改强>
很可能所有放在一起的文件并不完全等于某些数量的CD。例如,如果文件的总数是1.6GB,即使它们包装完好,那就是剩下的两张CD。所以如果你已经知道3 cd是最低要求,并且你尝试了几个组合,直到你得到它适合3 cd,为什么它需要进行优化呢?你不能保存比理论最小值更多的光盘。