33

sum-subset 問題は次のように述べています。

整数の集合が与えられたとき、合計がゼロである空でないサブセットはありますか?

この問題は一般に NP 完全です。このわずかな変種の複雑さがわかっているかどうか、興味があります。

k整数のセットが与えられたとき、合計がゼロになるサイズのサブセットはありますか?

たとえば、 の場合k = 1、バイナリ検索を実行して で答えを見つけることができますO(log n)。の場合k = 2、次のように取得できますO(n log n)(たとえば、合計が指定された数値に等しい配列から要素のペアを検索するを参照)。の場合k = 3、実行できますO(n^2)(たとえば、合計が指定された数値に最も近い配列内の 3 つの要素を見つけるを参照してください)。

の関数としてこの問題に配置できる既知の境界はありkますか?

動機として、この質問について考えていました。2 つの部分の平均が等しくなるように、配列を 2 つの部分に分割するにはどうすればよいですか? 実際にNP完全かどうかを判断しようとしています。その答えは、上記の公式があるかどうかにあります。

一般的な解がなければ、 の最適な境界を知ることに非常に興味がありk=4ます。

4

6 に答える 6

16

k=4 の場合、空間複雑度 O(n)、時間複雑度 O(n 2 * log(n))

配列をソートします。2 つの最小要素と 2 つの最大要素から始めて、2 つの要素のすべてのlesser合計を(a[i] + a[j])非減少の順序で計算し、2 つの要素のすべてのgreater合計を(a[k] + a[l])非増加の順序で計算します。lesser合計が 0 未満の場合は合計を増やし、greater合計が 0 より大きい場合は 1 を減らし、合計が 0 (成功) またはa[i] + a[j] > a[k] + a[l](失敗) の場合は停止します。

トリックは、すべてのインデックスを反復処理するiことでありj、そのような方法で(a[i] + a[j])は決して減少しません。そして、とkは決して増加してはなりません。プライオリティ キューは、これを行うのに役立ちます。l(a[k] + a[l])

  1. key=(a[i] + a[j]), value=(i = 0, j = 1)優先キューに入れます。
  2. (sum, i, j)プライオリティ キューからポップします。
  3. sum上記のアルゴリズムで使用します。
  4. これらの要素がまだ使用されていない場合にのみ、プライオリティ キューに(a[i+1] + a[j]), i+1, j入れます。(a[i] + a[j+1]), i, j+1使用された要素を追跡するには、「i」ごとに使用される最大の「j」の配列を維持します。「i」より大きい「j」の値のみを使用するだけで十分です。
  5. ステップ 2 から続行します。

k>4 の場合

スペースの複雑さが O(n) に制限されている場合、値にブルート フォースを使用k-4し、残りの4値に上記のアルゴリズムを使用するよりも優れたものを見つけることはできません。時間計算量 O(n (k-2) * log(n))。

非常に大きなk 整数の場合、線形計画法でいくらか改善される可能性があります。

アップデート

が非常に大きい場合n(最大整数値と同じオーダー)、O(1) プライオリティ キューを実装して、O(n 2 ) および O(n (k-2) ) の複雑さを改善できます。

の場合n >= k * INT_MAX、O(n) 空間の複雑さを持つ別のアルゴリズムが可能です。すべての可能なk/2値の合計のビットセットを事前に計算します。そして、それを使用して他の値の合計を確認しk/2ます。時間計算量は O(n (ceil(k/2)) ) です。

于 2012-01-19T13:03:31.690 に答える
4

W + X + Y + Z = {w + x + y +z|の0かどうかを判断する問題 w in W、x in X、y in Y、z in Z}は、煩わしい退化したケースがないことを除いて、基本的に同じです(つまり、問題は最小限のリソースで相互に削減できます)。

この問題(したがって、k = 4の元の問題)には、O(n ^ 2 log n)時間、O(n)空間アルゴリズムがあります。k = 2のO(n log n)時間アルゴリズム(A + Bの0かどうかを判断するため)は、ソートされた順序でAにアクセスし、逆にソートされた順序でBにアクセスします。したがって、必要なのはA = W + XのO(n)空間イテレータです。これはB = Y +Zに対して対称的に再利用できます。W={w1、...、wn}をソートされた順序で使用します。X内のすべてのxについて、Key-Valueアイテム(w1 + x、(1、x))を優先キューに挿入します。min要素(wi + x、(i、x))を繰り返し削除し、(wi + 1 + x、(i + 1、x))を挿入します。

于 2012-01-19T04:44:25.123 に答える
3

O(n^2log(n)) における k=4 の解

ステップ 1: ペアごとの合計を計算し、リストを並べ替えます。n(n-1)/2 個の合計があります。したがって、複雑さは O(n^2log(n)) です。合計を作る個人の身元を保持します。

ステップ 2: 上記のリストの各要素について、補数を検索し、それらが「個人」を共有していないことを確認します。n^2 回の検索があり、それぞれの複雑度は O(log(n)) です。

編集: 元のアルゴリズムのスペースの複雑さは O(n^2) です。スペースの複雑さは、仮想 2D 行列をシミュレートすることで O(1) に減らすことができます (並べ替えられたバージョンの配列を格納するスペースを考慮する場合は O(n))。

まず 2D 行列について: 数値を並べ替え、ペアワイズ和を使用して行列 X を作成します。これで、行列はすべての行と列が並べ替えられるようになりました。この行列の値を検索するには、対角線上の数字を検索します。数値が X[i,i] と X[i+1,i+1] の間にある場合、基本的には行列 X[i:N, 0:i] と X[0:i] によって検索空間を半分にすることができます。 、 の]。結果の検索アルゴリズムは O(log^2n) です (あまり確信が持てません。誰かチェックしてもらえますか?)。

ここで、実際の行列を使用する代わりに、事前に計算する代わりに X[i,j] が必要に応じて計算される仮想行列を使用します。

結果の時間計算量: O( (nlogn)^2 )。

PS: 次のリンクでは、2D ソートされたマトリックス検索の複雑さは O(n) の複雑さであると述べています。それが真 (つまり、O(log^2n) が正しくない) の場合、最終的な複雑さは O(n^3) です。

于 2012-01-18T21:47:49.963 に答える
3

awesomoの答えに基づいて構築するには...数値がソートされていると仮定できる場合、特定のkに対してO(n ^ k)よりもうまくいくことができます。サイズ (k-1) のすべての O(n^(k-1)) サブセットを取得し、最初の (k-1) に追加されたときに残りの数値をバイナリ検索します。これは O(n^(k-1) log n) です。これは、複雑さが確かにそれよりも少ないことを意味します。

実際、複雑さが k=3 の場合に O(n^2) であることがわかっている場合、k > 3 の場合はさらに適切に処理できます: O(n^( k-3))、残りの要素で O(n^2) の問題を解きます。これは、k >= 3 の場合、O(n^(k-1)) です。

しかし、おそらくあなたはもっとうまくやれるでしょうか?これについて考えてみます。

編集: 最初は、この問題に対する別の見方を提案する多くのことを追加するつもりでしたが、要約版を投稿することにしました。他の投稿者には、このアイデアにメリットがあるかどうかを確認することをお勧めします。分析は難しいですが、機能するのに十分クレイジーかもしれません。

k が固定されているという事実と、奇数と偶数の合計が特定の方法で動作するという事実を使用して、この問題を解決するための再帰アルゴリズムを定義できます。

最初に、リストに偶数と奇数の両方が含まれるように問題を修正します (これは、すべてが偶数の場合は 2 で割るか、すべてが奇数の場合は数値から 1 を引き、目標の合計から k を引き、繰り返します。必要に応じて)。

次に、奇数の偶数を使用することによってのみ目標合計が偶数に達することができ、奇数の奇数の奇数のみを使用することによってのみ目標合計が奇数に達することができるという事実を使用します。適切な奇数のサブセットを生成し、偶数、合計から検査対象の奇数のサブセットの合計を引いたもの、および k から奇数のサブセットのサイズを引いたものを使用して、再帰的にアルゴリズムを呼び出します。k = 1 の場合、二分探索を行います。k > n の場合 (これが起こるかどうかはわかりません)、false を返します。

奇数が非常に少ない場合、これにより、勝者のサブセットの一部である必要がある用語を非常に迅速に選択したり、そうでないものを破棄したりできます。引き算のトリックを使用して、偶数が多い問題を奇数が多い同等の問題に変換できます。したがって、最悪のケースは、偶数と奇数の数が非常に似ている場合に違いありません...そしてそれが私が今いる場所です. これに対する無駄に緩い上限は、ブルートフォースよりも何桁も悪いですが、少なくともブルートフォースと同じくらい良いと思います. 考えは大歓迎です!

EDIT2:説明のための上記の例。

{1, 2, 2, 6, 7, 7, 20}, k = 3, sum = 20.
Subset {}:
 {2, 2, 6, 20}, k = 3, sum = 20
 = {1, 1, 3, 10}, k = 3, sum = 10
 Subset {}:
  {10}, k = 3, sum = 10
  Failure
 Subset {1, 1}:
  {10}, k = 1, sum = 8
  Failure
 Subset {1, 3}:
  {10}, k = 1, sum = 6
  Failure
Subset {1, 7}:
 {2, 2, 6, 20}, k = 1, sum = 12
 Failure
Subset {7, 7}:
 {2, 2, 6, 20}, k = 1, sum = 6
 Success
于 2012-01-18T21:46:44.467 に答える
2

非常によく似た質問:

部分和問題のこの変種は、より簡単に解決できますか?

それはまだNP完全です。

F(1) | F(2) | ... F(n)そうでない場合、F が関数であるとして表すことができるため、サブセット合計も P になります。これはO(O(F(1)) + O(F(2)) + O(F(n)))まだ多項式であり、NP完全であることがわかっているため、これは正しくありません。

入力に特定の境界がある場合、多項式時間を達成できることに注意してください。

また、総当たり実行時間は二項係数で計算できることにも注意してください。

于 2012-01-18T21:40:01.297 に答える
0

時間の複雑さは自明です(要素からの のサイズのサブセットO(n^k)の数)。kn

は与えられた定数であるためk、(おそらく非常に高次の) 多項式の上限は の関数として複雑さを制限しますn

于 2012-01-18T20:16:03.567 に答える