最近 sci.op-research に投稿された質問は、私が考えたくない、あなたが聞いたくない退屈な仕事からの歓迎の休息を提供してくれました。貪欲なヒューリスティックは、連続ナップザック問題 maximumc′xs.ta′x≤bx≤ux∈ℜ+n(1) を最適に解くことがわかっています。(双対性理論を使用した証明は非常に簡単です。) 最大化c′xs.ta′x≤be′x=b˜x≤ux∈ℜ+n(2 ) ここで e=(1,…,1) . 貪欲ヒューリスティックの変種など、シンプレックス法以外で解決できますか?
答えはイエスですが、私が思いついたものがシンプレックス法よりもプログラムが簡単で効率的であるかどうかはまったくわかりません。個人的には、線形計画法のソルバーでライブラリにリンクして、シンプレックスを使用しますが、代替案がシンプレックスの改善ではない場合でも、代替案を見つけるのは面白かったです。
私が提示する方法は、双対性に依存しています。具体的には、線形プログラムの実行可能解とその双対の実行可能解が相補的な緩み条件を満たしている場合、両方がそれぞれの問題で最適であるというよく知られた結果に依存しています。ナップザックとカウント制約の双対変数をそれぞれ λ と μ とします。λ≥0 であるが、μ の符号は無制限であることに注意してください。基本的に、以下で説明する同じ方法は、不等式のカウント制約 (e'x≤b~ ) を使用して機能し、μ (非負) の符号がアプリオリにわかっているため、実際には少し簡単です。元の質問の投稿者は等価カウント制約を指定していたので、それを使用します。上限には双対変数 (ρ≥0 ) もあります。双対問題は最小化されますbλ+b˜μ+u′ρs.t.λa+μe+ρ≥cλ,ρ≥0.(3)
これは論文ではなくブログ投稿であるため、(2) が実現可能であり、すべてのパラメーターが厳密に正であり、最適解が一意で縮退していないと仮定します。一意性と縮退によってアルゴリズムが無効になることはありませんが、プレゼンテーションが複雑になります。(2) の最適な基本実行可能解では、1 つまたは 2 つの基本変数 (ナップザック制約が非拘束の場合は 1 つ、拘束の場合は 2 つ) が存在し、他のすべての変数はその下限または上限のいずれかで非基本的です。(λ,μ,ρ) が (2) の双対の最適解であるとします。任意の変数 xi の削減コストは ri=ci−λai−μ です。ナップザック制約が束縛されていない場合、λ=0 であり、最適解は xi=uiri>0b~-∑rj>0ujri=00ri<0.(4) ナップザック制約が束縛されている場合、2 つの項目 (j , k ) 変数が基本で、 rj=rk=0 。(縮退を想定することで、knapsack 制約の slack 変数が値 0 の基本的である可能性を想定しました)。xi=uiri>00ri<0(5) と設定し、b'=b−∑i∉{j,k}aixi および b~'=b~−∑i∉{j,k}xi とする。2 つの基本変数は、xj=b'−akb˜'aj−akxk=b'−ajb˜'ak−aj で与えられます。(6)
アルゴリズムは 2 段階で処理されます。まず、ナップザックの非バインド (1 つの基本的な x 変数) を使用して解を探し、次にナップザックのバインド (2 つの基本的な x 変数) を使用して解を探します。相補的な緩みに従う実行可能な主解と双対解を初めて見つけたとき、両方が最適でなければならないことに注意してください。また、任意の μ と任意の λ≥0 が与えられた場合、ρi=ci−λai−μ+ を設定することにより、(3) の実行可能な解を得ることができます。したがって、実行可能な双対解を常に扱い、アルゴリズムは相補的な緩みを満たす主解を構築します。したがって、停止基準は、構築された主解が実行可能であるということになります。
最初のフェーズでは、 c1≥⋯≥cn となるように変数を並べ替えます。λ=0 で、単一の基本変数 (xh ) があり、その削減コストはゼロでなければならないため、明らかに μ=ch です。これは、 xi の削減コスト ri=ci−λai−μ=ci−ch が ih に対して非負であることを意味します。(3) で与えられる解が実行可能である場合、つまり ∑ih である場合。したがって、二分探索を使用してこのフェーズを完了することができます。n の値が大きいと仮定すると、最初の並べ替えは O(nlogn ) 時間で実行でき、残りのフェーズでは O(logn) 回の反復が必要になり、それぞれに O(n) 時間がかかります。
残念ながら、二分探索を第 2 段階に適用する方法がわかりません。この段階では、ナップザック制約がバインドされ、 λ>0 である解を探します。μ の値を再度検索しますが、今回は単調です。最初に、貪欲なヒューリスティックを問題 (1) に適用し、ナップザック制約を保持しますが、カウント制約を無視します。解がたまたまカウント制約を満たすように発生した場合は、完了です。ただし、ほとんどの場合、カウントの制約に違反します。カウントが b~ を超える場合、(4) の μ の最適値は正であると推測できます。カウントが b~ に満たない場合、μ の最適値は負になります。μ=0 で第 2 フェーズを開始し、最適値の方向に進みます。
貪欲なヒューリスティックはアイテムを c1/a1≥⋯≥cn/an となるようにソートし、 μ=0 から開始するため、現在のソート順は (c1−μ)/a1≥⋯≥(cn−μ)/an になります。 . μ の最適値を検索するときに、その順序を維持します (必要に応じて再ソートします)。混乱を避けるために (願わくば)、μ の最適値は正であると仮定して、μ を増やしていきます。(λ,μ) の値を探します。ここで、x 変数のうちの 2 つが基本であり、つまり、2 つの変数のコストが 0 に削減されています。なら ri=0=rj⟹ci−λai−μ=0=cj−λaj−μ(7)⟹ci−μai=λ=cj−μaj. μ の現在の値に対して (c1−μ)/a1≥⋯≥(cn−μ)/an の場合、μ の次に高い (低い) 値が(7)で同点を作成する場合、連続する連続するアイテムのペア(j = i + 1)が含まれる必要があります。さらに、再び縮退を振り払います (この場合、削減されたコスト 0 の 2 つ以上のアイテムを意味します)。アイテム i と i+1 がコスト 0 を削減した値をわずかに超えて μ を微調整すると、ソート順の唯一の変更はそのアイテムです。 i と i+1 は場所を入れ替えます。その方向にそれ以上移動しないと、i と i+1 が再び同点になりますが、もちろん、いずれかが新しい隣人と同点になる可能性があります。
μ=0 から始まる第 2 フェーズは、次のように進行します。各ペア (i,i+1) について、(ci−μ)/ai=(ci+1−μ)/ai+1 となる μ の値 μi を計算します。その値が μ の現在の値より小さい場合は、その値を ∞ に置き換えます (タイが間違った方向に発生することを示します)。μ を miniμi に更新し、(7) から λ を計算し、(5) と (6) から x を計算します。x が主実行可能 (0≤xi≤ui および 0≤xi+1≤ui+1 に縮小) である場合、停止: x が最適です。それ以外の場合は、i と i+1 をソート順に入れ替え、μi=∞ に設定し (再インデックスされたアイテム i と i+1 は再び結合しません)、μi−1 と μi+1 を再計算します (他の μj はスワップの影響を受けません)。
最初のフェーズで最適値が見つからなかった場合 (および、2 番目のフェーズの開始時の貪欲なヒューリスティックがうまくいかなかった場合)、チェックする μ の値がなくなる前に、2 番目のフェーズを最適値で終了する必要があります (すべての μj= ∞ )。縮退は、コーディングに少し余分な労力をかけるか (たとえば、3 方向以上の関係が発生した場合に第 2 フェーズで i と j の複数の組み合わせをチェックする)、または小さな摂動を作成して縮退を解消することで処理できます。