7

部分和問題を解くための新しいアルゴリズムを思いついたのですが、それは多項式時間だと思います。私が間違っているか、天才だと言ってください。

クイックスターターファクト:

部分和問題はNP完全問題です。多項式時間でそれを解くことは、P=NPを意味します。
長さNのセット内のサブセットの数は2^Nです。

より有用な一方で、長さNの一意のサブセットの数は、最大でセット全体の合計から最小の要素を引いたものです。または、サブセットが生成できる可能性のある合計の範囲は、すべての負の要素の合計の間にあります。そして、すべての正の要素の合計。これは、すべての正または負の合計よりも大きいまたは小さい合計はあり得ないためです。これらの合計は、要素を追加すると線形速度で増加します。

これが意味するのは、Nが増加すると、重複するサブセットの数が指数関数的に増加し、一意で有用なサブセットの数が直線的にのみ増加することです。可能な限り早い機会に重複サブセットを削除できるアルゴリズムを考案できれば、多項式時間で実行できます。簡単な例は、バイナリから簡単に取得できます。2の累乗である数値のみから、任意の整数値に対して一意のサブセットを作成できます。そのため、他の数を含むサブセット(2の累乗がすべてある場合)は重複していて無駄です。それらとその導関数を計算しないことにより、2の累乗である数値が任意の整数と比較して対数的に発生するため、アルゴリズムの実行時間を実質的にすべて節約できます。

そのため、これらの重複を削除し、それらとそのすべての導関数を計算する必要をなくす単純なアルゴリズムを提案します。

まず、O(N log N)のみのセットを並べ替え、正と負の2つに分割します。負の数の手順は同じなので、正の数の概要のみを説明します(明確にするために、セットは正の半分だけを意味します)。

sumでインデックス付けされた配列を想像してみてください。この配列には、正の側のすべての可能な結果の合計のエントリがあります(線形のみです。覚えておいてください)。エントリを追加すると、値はサブセット内のエントリになります。したがって、array [3] = {1、2}のようになります。

一般に、セット内のすべてのサブセットを列挙するように移動します。これを行うには、1つの長さのサブセットから始めて、それらに追加します。すべての一意のサブセットがある場合、それらは配列を形成し、Horowitz/Sahniで使用されている方法でそれらを単純に反復します。

ここで、「第1世代」の値から始めます。つまり、元のデータセットに重複する数値がなかった場合、これらの値に重複がないことが保証されます。つまり、すべての単一値サブセット、およびセットのすべての長さから1つの長さのサブセットを引いたものです。これらは、セットを合計し、各要素を順番に減算することで簡単に生成できます。さらに、セット自体は、有効な第1世代の合計とサブセット、およびサブセットの個々の要素です。

次に、第2世代の値を実行します。配列内の各値をループし、一意のサブセットごとに、値がない場合はそれを追加して、新しい一意のサブセットを計算します。重複していると、楽しいことが起こります。衝突リストに追加します。新しいサブセットを追加するときは、それらが衝突リストにあるかどうかを確認します。あまり望ましくない(通常は大きいが、任意である可能性がある)等しいサブセットによってキーを設定します。サブセットに追加する場合、衝突が発生したとしても、何もしません。より望ましいサブセットを追加する場合、チェックを見逃して追加し、共通のサブセットを生成します。その後、他の世代のために繰り返します。

この方法で重複サブセットを削除することにより、重複をセットの残りの部分と結合し続ける必要も、衝突をチェックし続ける必要も、合計する必要もありません。最も重要なことは、一意ではない新しいサブセットを作成しないことで、それらから新しいサブセットを生成しないことです。これにより、アルゴリズムがNPからPに変わる可能性があります。これは、サブセットの成長が指数関数的ではなくなったためです。破棄します。それらの大部分は、次世代で「複製」し、他の重複しないサブセットと組み合わせることによって、より多くのサブセットを作成する前に行われます。

私はこれをあまりよく説明していないと思います。私は写真を持っています...それらは私の頭の中にあります。重要なことは、重複するサブセットを破棄することで、実質的にすべての複雑さを取り除くことができるということです。

たとえば、(この例を手作業で行っているため)ゼロを目指す-7から7(ゼロではない)の単純なデータセットを想像してみてください。並べ替えて分割すると、(1、2、3、4、5、6、7)が残ります。合計は28です。ただし、2 ^ 7は128です。したがって、128個のサブセットが1 .. 28の範囲に収まります。つまり、100セットが重複していることが事前にわかっています。8の場合、スロットは36しかありませんが、サブセットは256になります。したがって、重複の数が以前の2倍を超える220になっていることが簡単にわかります。

この場合、第1世代の値は1、2、3、4、5、6、7、28、27、26、25、24、23、22、21であり、それらを構成コンポーネントにマップします。

1 = { 1 }
2 = { 2 }
...
28 = { 1, 2, 3, 4, 5, 6, 7 }
27 = { 2, 3, 4, 5, 6, 7 }
26 = { 1, 3, 4, 5, 6, 7 }
...
21 = { 1, 2, 3, 4, 5, 6 }

ここで、新しいサブセットを生成するために、各サブセットを順番に取得し、相互サブセットがない限り、他のサブセットに追加します。たとえば、28と27にはhueg相互サブセットがあります。したがって、1を取得して2に追加すると、3 = {1、2}になりますが、お待ちください。すでにアレイに含まれています。これが意味するのは、すでに2が含まれているサブセットに1を追加しないこと、およびその逆のことです。これは、3のサブセットと重複しているためです。

今、私たちは持っています

1 = { 1 }
2 = { 2 }
// Didn't add 1 to 2 to get 3 because that's a dupe
3 = { 3 } // Add 1 to 3, amagad, get a duplicate. Repeat the process.
4 = { 4 } // And again.
...
8 = { 1, 7 }

21? Already has 1 in.
...
27? We already have 28

ここで、すべてに2を追加します。

1? Existing duplicate
3? Get a new duplicate
...
9 = { 2, 7 }
10 = { 1, 2, 7 }

21? Already has 2 in
...
26? Already have 28
27? Got 2 in already.

3?

1? Existing dupe
2? Existing dupe
4? New duplicate
5? New duplicate
6? New duplicate
7? New duplicate
11 = { 1, 3, 7 }
12 = { 2, 3, 7 }
13 = { 1, 2, 3, 7 }

ご覧のとおり、毎回新しいサブセットを追加していますが、量は直線的にしか増加していません。

4?

1? Existing dupe
2? Existing dupe
3? Existing dupe
5? New duplicate
6? New duplicate
7? New duplicate
8? New duplicate
9? New duplicate
14 = {1, 2, 4, 7}
15 = {1, 3, 4, 7}
16 = {2, 3, 4, 7}
17 = {1, 2, 3, 4, 7}

5?

1,2,3,4 existing duplicate
6,7,8,9,10,11,12 new duplicate
18 = {1, 2, 3, 5, 7}
19 = {1, 2, 4, 5, 7}
20 = {1, 3, 4, 5, 7}
21 = new duplicate

これで範囲内のすべての値が得られたので、停止してリスト1-28に追加します。負の数について繰り返し、リストを繰り返します。

編集:

このアルゴリズムは、どのような場合でも完全に間違っています。合計が重複しているサブセットは、到達方法が異なるため、つまり、折りたたむことができないため、サブセットを生成できる目的で重複することはありません。

4

3 に答える 3

11

これはP=NPを証明するものではありません。

正の数が1、2、4、8、16などである可能性を考慮していません。したがって、サブセットを合計するときに重複がないため、O(2 ^ N)で実行されます。この場合の時間。

これを特殊なケースとして扱うことはできますが、それでもアルゴリズムは他の同様のケースでは多項式ではありません。あなたが行ったこの仮定は、サブセット和のNP完全バージョンから離れて、簡単な(多項式時間)問題のみを解くところです。

[正の数の合計が大きくなると仮定]要素を追加すると、線形の割合で。

ここでは、P(つまり問題を述べるために必要なビット数)がNよりも小さいと効果的に想定しています。ウィキペディアからの引用:

したがって、NとPが同じ次数である場合、問題は最も困難です。

NとPが同じ次数であると仮定すると、要素を追加するにつれて合計が無限に直線的に増加すると仮定することはできません。セットに要素を追加すると、問題を解決するのが難しいままになるように、それらの要素も大きくする必要があります。

P(場所の値の数)が小さい固定数である場合、それを正確に解くことができる動的計画法アルゴリズムがあります。

これらのアルゴリズムの1つを再発見しました。これは素晴らしい作品ですが、新しいものではなく、P=NPであることを証明するものでもありません。ごめん!

于 2010-06-26T23:07:43.197 に答える
6

デッドMG、

投稿してから半年近く経ちますが、とにかくお答えします。

マーク・バイアーズは、書かれるべきもののほとんどを書いた。

アルゴリズムは既知です。

このようなアルゴリズムは、母関数アルゴリズムまたは単に動的計画法アルゴリズムとして知られています。

algorihtmには、いわゆる疑似多項式の複雑さという非常に重要な機能があります。

従来の複雑さは、問題のサイズの関数です。従来の複雑さに関しては、アルゴリズムにはO(2 ^ n)の悲観的な複雑さがあります(つまり、前述のように、数値1、2、4、...の場合)。

あるいは、アルゴリズムアルゴリズムの複雑さは、問題のサイズと問題内のいくつかの数値のサイズの関数として表すことができます。アルゴリズムの場合、O(nw)のようになります。ここで、wは個別の合計の数です。

これは疑似多項式の複雑さです。これは非常に重要な機能です。このようなアルゴリズムは、問題の複雑さのクラスにもかかわらず、実際の問題のインスタンスの多くを解決できます。

Horowitz and Sahniアルゴリズムには、悲観的な複雑さO(2 ^ N / 2)があります。これは、アルゴリズムより2倍優れているわけではありませんが、アルゴリズムより2 ^ N/2倍優れています。グレッグがおそらく意味したのは、ホロウィッツとサーニのアルゴリズムが問題の2倍の大きなインスタンスを解決できるということでした(サブセット和に2倍の数がある)

これは理論的には真実ですが、実際にはHorowitzとSahniは(自宅のコンピューターで)約60の数値のインスタンスを解決できますが、あなたと同様のアルゴリズムは1000の数値のインスタンスでも処理できます(数値自体が大きすぎない場合)

実際、2つのアルゴリズムを混在させることもできます。つまり、あなたのようなものであり、HorowitzとSahniのアルゴリズムです。このようなソリューションには、疑似多項式の複雑さとO(2 ^ n / 2)の悲観的な複雑さの両方があります。

訓練を受けたコンピューター科学者は、関数理論を生成することにより、あなたのようなアルゴリズムを構築することができます。

訓練を受けた人も訓練を受けていない人も、あなたがしたようにそれを考えることができます。

必ずしも「知られている」という言葉で考える必要はありません。あなたがあなた自身でそのようなアルゴリズムを発明することができることはあなたにとって重要であるはずです。これは、おそらく他の重要なアルゴリズムを自分で発明できることを意味し、いつかは知られていないアルゴリズムを発明できるかもしれません。この分野の現在の進歩と文献の内容を知ることは役に立ちます。そうでなければ、あなたは車輪の再発明を続けるでしょう。

高校に戻ったとき、私はダイクストラアルゴリズムを再発明しました。私のバージョンは、データ構造について何も知らなかったため、ひどく複雑でした。とにかく、私はまだ自分を誇りに思っています。

まだ勉強している場合は、母関数理論に注意してください。

ウィキでチェックアウトすることもできます:

疑似多項式時間弱くNP完全強くNP完全母関数

メグリ

于 2010-12-22T10:17:38.033 に答える
1

これが意味するのは、Nが増加すると、重複するサブセットの数が指数関数的に増加し、一意で有用なサブセットの数が直線的にのみ増加することです。

必ずしもそうではありません-重複するサブセットの合計の数は、セット内のゼロに最も近い数の値によっても決定されます(ゼロまでの最小距離が大きいほど、セットの重複するサブセットの合計は少なくなります)。

一般に、セット内のすべてのサブセットを列挙するように移動します。

残念ながら、セットのサブセットのすべての合計を列挙するには、指数関数的な数の加算演算(この例では2 ^ 7または128)を実行する必要があります。そうでなければ、アルゴリズムはどのようにして一意の合計が何であるかを決定しますか?したがって、最初のステップに続くステップは、多項式の実行時間を非常によく持つ可能性がありますが、アルゴリズムは全体として指数関数的に複雑になります(アルゴリズムは最も遅い部分と同じくらい速いため)。

ちなみに、部分和問題を解くための最もよく知られているアルゴリズム(Horowitz and Sahni、1974)は、O(2 ^ N / 2)の複雑さを持っています。これにより、このアルゴリズムの約2倍の速度になります。

于 2010-07-20T22:30:57.697 に答える