我将使用 Python 语法和对象来表示问题,但实际上它是用于 SQL 数据库中的模型,带有 Python API 和 ORM。
我有一个这样的数字列表:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
有时,会删除一些数字并保留空空格:
[0, 1, 2, None, None, 5, 6, None, None, None, 10]
我需要做的是在定期执行的维护步骤中有效地打包这组数字,以有序和无序的方式,这样数字之间就没有空空格:
因此,以有序的方式,我需要该列表变为:
[0, 1, 2, 5, 6, 10, None, None, None, None, None]
当无序时,每个数字的去向并不重要,只要它们之间没有空格即可。
数字可以在连续的块中移动,将它们向左或向右移动任意数量的成本相同,但是存在设置和拆卸成本,这使得移动更大的块并在尽可能少的更新中实现它变得更加有效.
现在我正在使用最简单的解决方案,查找连续数字块并将它们一次移动一个块到最近的左侧,直到它被打包。因此,在示例中,5、6 在一次更新中向左移动了 2 个块,然后在另一个更新中将 10 向左移动了 5 个块。
[0, 1, 2, None, None, 5, 6, None, None, None, 10]
[0, 1, 2, 5, 6, None, None, None, None, None, 10]
[0, 1, 2, 5, 6, 10, None, None, None, None, None]
当订单很重要时,这种简单的方法似乎是最有效的,但实际上我的大部分操作都是无序的,我认为应该有更好的方法。例如,在这种情况下,可以通过在 6 和 10 之间移动 0、1、2 块来将列表打包到单个更新中:
[None, None, None, None, None, 5, 6, 0, 1, 2, 10]
实际上会有数千个块,但我事先知道每个块的大小和每个间隙。与它们的大小和间隙之间的组合计算所需的计算相比,移动块也非常昂贵,因此找到最佳解决方案是理想的。
这似乎是一种装箱问题,但我真的不知道如何接近它以找到最佳解决方案。有任何想法吗?