问题是装箱与订购的一面。单独装箱是 NP 难的,所以我要建议的确切算法的运行时间不是多项式的。希望它无论如何都会有用。
第一步是生成所有可能的组。这是一些 Python 来演示我的意思。
def allgroups(terminals, fibrecount=12, groupsofar=[]):
if terminals: # is nonempty
terminal = terminals.pop() # last element
if terminal.portsize <= fibrecount:
groupsofar.append(terminal)
yield from allgroups(terminals, fibrecount - terminal.portsize, groupsofar)
groupsofar.pop() # terminal
yield from allgroups(terminals, fibrecount, groupsofar)
terminals.append(terminal)
elif groupsofar:
yield groupsofar
第二步是使用算法 X生成所有可能的分组,第三步是通过动态规划评估每个分组。你没有说“尽可能按终端的顺序”是什么意思,所以我会尽量减少inversions。实际上,只要它具有最佳子结构,确切的目标并不重要,即,给定相同组的两个排序,无论其他组如何排列,一个总是优于另一个。
在运行动态程序之前,计算每对组的反转次数(如果第一个出现在第二个之前)。这意味着迭代第一组的外循环和迭代第二组的内循环,计算第一组中的终端应该出现在第二组中的终端之后的次数。现在,对于非递减顺序的每个组子集,确定该子集的最佳顺序。由于最优子结构,最优顺序从子集中的某个组开始,并以我们已经为剩余部分计算的最优解结束。尽量减少哪个组首先出现的所有选择。