在python中从数组中查找最佳元素

在python中从数组中查找最佳元素,python,arrays,algorithm,data-structures,Python,Arrays,Algorithm,Data Structures,我需要设计一种算法,从python中的列表中找到最佳元素。我有一张700mb的cd。以及一个300个随机生成的文件大小从30-90MB不等的数组。它需要以最理想的方式填充cd,最小的空间被浪费(通过所有可能的方式查看)。我想这与背包问题类似,只是它只有一个数组和一个限制。 由于我对算法和数据结构场景完全陌生,我不知道如何使用python实现它 提前感谢找到绝对最佳的方法可能效率不高。但是你可以使用一些经验法则,比如先取最大的文件,然后用第一个合适的文件填充剩余的空间,直到空间太小,无法容纳更多的

我需要设计一种算法,从python中的列表中找到最佳元素。我有一张700mb的cd。以及一个300个随机生成的文件大小从30-90MB不等的数组。它需要以最理想的方式填充cd,最小的空间被浪费(通过所有可能的方式查看)。我想这与背包问题类似,只是它只有一个数组和一个限制。 由于我对算法和数据结构场景完全陌生,我不知道如何使用python实现它


提前感谢

找到绝对最佳的方法可能效率不高。但是你可以使用一些经验法则,比如先取最大的文件,然后用第一个合适的文件填充剩余的空间,直到空间太小,无法容纳更多的文件。看见最优的simple算法是先拟合递减法。按大小从大到小对所有文件进行排序。然后将每个文件放在第一张cd上有足够空间容纳的地方,直到所有文件都用完

编辑


很可能所有文件放在一起并不完全等于某个cd的数量。例如,如果文件的总容量为1.6GB,那就是两张cd,还有一点剩余,即使它们包装得很好。因此,如果您已经知道3张cd是最低要求,并且您尝试了一些组合,直到您将其安装到3张cd上,那么为什么还需要对其进行优化呢?你不能保存比理论最小值更多的cd。

正如@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数组)来实现这一点,或者只是将其作为递归函数编写并记忆


这将使您的损耗最小,但不是选择了哪些文件来实现这一点。但是,您可以轻松地修改它,以保存关于它在每个状态下所做选择的信息,并使用这些信息从开始状态建立一系列选择。

这正是背包问题,只有一个维度。我假设您要使用所有文件?我想这是错的?我想过,但有人告诉我,这必须是最理想的方式。它可以被视为一艘船舶,必须装载最大数量的货物而不超过限额。货物越多,往返运输所需的时间就越少,从而最大限度地降低运营成本。@jorgen:正确。然而,这是一个NP难问题,对于300个随机生成的文件,您将尝试
300大致为
10^1000
的场景。世界上所有的计算机都无法在宇宙的时间长度上测试所有的可能性!哦你说得对。事实上,我不得不承认有一个轻微的打字错误。数字是30而不是300。。很抱歉,在我之前的评论中,还有一些策略可以在相对较短的时间内为您提供95%或更多的最佳解决方案。挤出最后一点最优解决方案需要数年的时间才能达到几个百分点。这真的不值得。@jorgen:即使是30个文件,也就是
30这是
265252859812191058630848000000
尝试的可能组合,但仍然不切实际。使用启发式方法就足够了,尝试每一种可能的组合几乎没有什么好处。