問題は、混合整数問題でモデル化できます。コレクションが大きすぎない場合 (数百の値など)、ヒューリスティックをプログラムしてパラメーター化するよりも標準の lp ファイルに書き込む方がはるかに簡単なので、このモデルを使用します。
この問題を混合整数問題ソルバーに与えることができます。
- COIN-OR(無料)、
- Cplex (アカデミックでない限り、商業的で拡張的)、
- ぐろび(CM)、
- GLPK (無料だが遅い)...
以下の疑似数学言語で以下の 2 つのモデルを書きました (これは LP 形式ではないことに注意してください)。
ハードバウンド
N をオブジェクトのセット、X_min と Y_min を到達する必要がある下限、ZZ を Z 値の平均下限とします。オブジェクト i が選択されている場合は値が 1 で、選択されていない場合は 0 のバイナリ変数 s_i を使用します。正確な問題は次のように記述できます。
Minimize sum_{i in N} s_i
Subject to:
sum_{i in N} X_i s_i >= X_min
sum_{i in N} Y_i s_i >= Y_min
sum_{i in N} (Z_i - ZZ) s_i >= 0
foreach i in N, s_i in {0, 1}
多目的
アンドレアスの回答で述べられているように、これを行うには他の方法があることに注意してください。これは、(私の意見では)目標に優先順位を付けて問題を「緩和」するためのより簡単な方法であり、上記の線形ソルバーを使用できます。
3 つのスラック変数 dX、dY、dZ、および 3 つの (正の) 重み係数 wX、wY、wZ を追加します。変数 dX、dY、および dZ は制約違反を表し、「重み」は制約違反に与える重要度を表します。
次に、問題を次のように記述できます。
Minimize sum_{i in N} s_i + wX dX + wY dY + wZ dZ
Subject to:
dX >= sum_{i in N} X_i s_i - X_min
dY >= sum_{i in N} Y_i s_i - Y_min
dZ >= sum_{i in N} (Z_i - ZZ) s_i
foreach i in N, s_i in {0, 1}
dX, dY, dZ >= 0
次に、目標に優先順位を付けるために wX、wY、および wZ をパラメータ化できます。たとえば、重みの値が大きい場合、モデルは「ハード バウンド」ソリューションが存在する場合はそれを返します。次に、より高い重みを持つ制約は、他の制約よりも違反される可能性が「低く」なります(もちろん、アイデアを提供するためだけに単純ではありません)。