在给出数百GB不同大小资产的情况下,填充一组蓝光光盘的最佳算法是什么?
我正在尝试整合大量旧CDROM,DVD和小型硬盘,并将所有内容放在由MD5签名索引的数据库中。肯定是一项艰巨的任务。
我目前所做的是按降序对资产大小(通常是目录大小)进行排序,开始在填充列表中插入最大的资产,跳过任何不合适的资产,直到资产耗尽为止。它几乎是瞬间运行但我不介意在必要时一夜之间运行。
它通常会给我95%或更高的利用率,但我确信有一种方法可以使用其他组合来提高效率。对于像磁盘映像这样的大型项目,使用这种原始方法可以获得相当低的利用率。
我的想法是采取所有资产的组合,1然后是2,然后是3,...项目,并保持最高字节数的运行值< 25,025,314,816字节指向与其相加的数组。当我发现我一次拥有如此多的资产时,没有任何组合适合,停止并使用正在运行的最高计数器指向的数组。
这是最好的算法吗?
有两个Perl模块似乎可以完成任务,算法组合和Math-Combinatorics。有什么建议更快,更稳定,更酷?
我的方案是编写一个脚本来计算大量目录的大小,并向我展示要刻录的数十个磁盘的最佳内容。
而且,我不想只是按文件填写文件,因为我想在同一张光盘上放置整个目录。
答案 0 :(得分:4)
这是一个NP完全问题,称为bin packing。没有已知的多项式时间算法可以最佳地解决它。换句话说,如果没有基本上尝试所有解决方案,就无法找到最佳解决方案。
从好的方面来说,一个非常简单的启发式方法,例如“将剩余的最大文件夹放在第一个有空间的磁盘上”将保证您使用的磁盘数量不会超过最佳情况的两倍。 (您可以阅读有关该问题的维基百科文章的更多详细信息)。
答案 1 :(得分:2)
该算法称为1d bin-packing。算法非常快但不是最优的。您也可以使用强力算法,但搜索空间非常大。这是一个带有贪婪算法的程序:http://www.phpclasses.org/package/2027-PHP-Pack-files-without-exceeding-a-given-size-limit.html
答案 2 :(得分:0)
我发现有效填充蓝光光盘的最实用方法。
我列出了要刻录的所有可用文件的完全限定路径。
然后(任意)决定考虑一堆目录级别或为其接受命令行选项。这是为了在一个蓝光上将目录中的所有目录保持在一起。还有一个STUFF选项可以先插入最大的文件,当文件导致溢出时,请查看下一个较小的文件,直到文件或空间用完为止。
将每个目录的哈希作为密钥,并将其包含的文件的总大小作为数据。同时保留一个并行哈希与每个目录的文件数量作为松弛空间和目录开销显然加起来,并且必须考虑。
选择22作为幻数。如果您有< = 22个目录,请尝试查找所有组合 最接近但不超过25.025 GB的那个。如果你有超过22,只需使用22最大。我使用Perl模块Algorithm :: Combinatorics来查找所有组合。通过试验和大多数错误,我确定21项的组合只需几秒钟。 23项需要很长时间,比我的注意力范围更长。 22大约需要35秒。
也接受输出目录并检查现有数据。可以选择移动文件(复制,检查大小和取消链接)。
每次我买一个新硬盘时,它通常都是前一个硬盘的两倍,所以我只想复制一切。随着尼康D800E(至尊!),HDR和全景,我终于耗尽了空间。
我的项目是独特,杂草并整合了15年(主要是垃圾)照片,视频,电影,音乐等等。我列出了大约十几个存储设备,计算了MD5签名并将它们全部放在数据库中。我选择了一个驱动器作为照片的主人,一个用于视频和其他一切的核心。我发现了8份东西!
我现在有大约10 TB的可用磁盘空间!
在任何人感兴趣的情况下完成所有实际工作的功能之下。
=============================================== 哎呀!无法提交您的答案,因为:
Your post appears to contain code that is not properly formatted as code
这个愚蠢的网页破坏了我的原始代码。对不起:( ..
答案 3 :(得分:-2)
使用“背包”优化问题中的算法。
http://en.wikipedia.org/wiki/Knapsack_problem
它可能不是最佳选择(它将最大化下一个磁盘的填充因子,而不是最小化所需的总磁盘数),但它有很好的文档,很容易找到编程语言的示例和工作代码您在网络上的选择(甚至是电子表格)。