我遇到了一个需要解决的问题,乍一看似乎是某种广义分配问题(组合优化问题的一个子集:http://en.wikipedia.org/wiki/Generalized_assignment_problem)。
问题的描述很不清楚,不是用英文写的;请耐心等待,因为我尽力解释它:
我获得了一系列特定尺寸的大理石块上的“切割”(任务)。目标是完成给定列表中的每项任务,同时最大限度地减少大理石丢失的数量。例如,如果我有一个20号的起始块,那么我可以用不同的方式切割它以完成一定数量的任务,同时确保我不会在此过程中“丢失”大理石。如果我需要3,5,6和6的子块,那么初始大小为20的块就可以了,因为我没有丢失的大理石(3 + 5 + 6 + 6 = 20)。
因此,目标是完成每项任务,同时尽可能减少大理石。我可以使用任意数量的起始块,只要任务全部完成即可。一个附加约束是指定长度为L的子块的每个任务也具有分配给它的“类”,其表示执行该特定切割所需的特定机器。给定一个起始块,我无法使用超过 3 不同的类来削减我的块。我可以在一台机器上进行尽可能多的切割,只要我不改变两次以上的类。
以下是可以提供给我的数据示例:
2 20 38
7
20
4 1
7 1
3 1
25 1
22 2
22 1
20 2
17 1
10 1
22 2
27 2
26 2
15 3
13 4
12 5
15 6
27 4
27 5
27 7
27 2
第一行给出了可用于执行所有给定任务的不同块的数量,以及每个起始块的大小。
第二行给出了不同“切割类”的总数,它表示可以执行所需切割的不同机器的数量。
第三行给出完成操作所需的削减(任务)总量。在这种情况下,需要执行正好20个任务才能完成问题。
其余的行提供了所需的剪切以及与此任务相关的类。
总结一下,我需要用任意数量的给定起始块执行某个任务列表,同时尽量减少丢失/不需要的大理石的数量。
所以我的问题是:这个问题的好方法是什么?我认为贪婪的近似算法可能是一种直接而简单的方法来找到合理的解决方案,但我老实说不确定
如果问题不明确,我提前道歉,如果您需要附加信息,请随时提出更明确的指示请求。
谢谢!
PS:算法将用Java编写,如果有帮助的话。
答案 0 :(得分:1)
如果我理解正确,那么(忽略"类"约束)这就是Cutting Stock problem。这是一个NP难的优化问题,通常通过将其公式化为ILP然后应用一种称为列生成的特殊ILP求解器技术来解决。简而言之,ILP具有每个可能的模式的变量,或者将大理石块切割成最大子块集的方式,其记录应该在该特定模式中切割的块的数量。但是可能存在大量可能的模式,其中大多数模式在最佳解决方案中根本不会被使用;列生成允许ILP求解器使用一组较小的变量,这些变量保证包含所有非零变量(即实际使用的所有模式)。
维基百科页面上有很多很好的信息。特别感兴趣的是,如果只有一个初始块大小,那么最小化浪费与最小化所使用的主块的数量相同,然后问题等同于Bin Packing 。这个问题仍然是NP难题,但它是" nice"其中:有简单的启发式方法(可证明)非常接近最优解决方案。您可以将其调整为您的问题的启发式方法。
将问题表述为ILP的一个很好的特性是,在对应于类约束的更多约束中添加它不应该是困难的。