問題を表すためにPython構文とオブジェクトを使用しますが、実際には、PythonAPIとORMを使用したSQLデータベースのモデルを対象としています。
私はこのような番号のリストを持っています:
[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]
そして、順序付けされていない場合、それらの間にヌルスペースがない限り、各番号がどこに行くかは実際には重要ではありません。
数字は連続したブロックで移動でき、任意の数の場所を左右に移動するのに同じコストがかかりますが、セットアップと分解のコストがかかるため、大きなブロックを移動してできるだけ少ない更新でそれを達成するのがはるかに効率的になります。
現在、私は最も単純なソリューションを使用しており、連続する番号のブロックを見つけて、パックされるまで一度に1ブロックずつ最も近い左に移動します。したがって、この例では、1回の更新で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]
この些細なアプローチは、順序が重要な場合に最も効率的であるように見えますが、実際には、私の操作のほとんどは順序付けられていないため、より良いアプローチがあるはずです。たとえば、この場合、0、1、2ブロックを6と10の間で移動することにより、リストを1回の更新でパックできます。
[None, None, None, None, None, 5, 6, 0, 1, 2, 10]
実際には何千ものブロックがありますが、各ブロックのサイズと各ギャップを事前に知っています。ブロックの移動は、サイズとギャップの間の組み合わせ論に必要な計算に比べて非常にコストがかかるため、最適なソリューションを見つけることが理想的です。
これは一種のビンパッキング問題のようですが、最善の解決策を見つけるためにどのようにアプローチするかは本当にわかりません。何か案は?