パーティションからの一意の部分文字列の最大数


30

タイトルをわかりやすくするために変更しました。

これは質問の詳細なバージョンです:

文字列がs あり、それを部分文字列に分割したいとします。各部分文字列は互いに異なります。1回のカットで取得できる一意の部分文字列の最大数はいくつですか。言い換えれば、formに連結する一意の部分文字列の最大数はいくつですかs

ここではいくつかの例を示します。

Example 1
s = 'aababaa'
output = 4
Explain: we can split `s` into aa|b|aba|a or aab|a|b|aa, 
         and 4 is the max number of substrings we can get from one split.

Example 2
s = 'aba'
output = 2
Explain: a|ba

Example 3
s = 'aaaaaaa'
output = 3
Explain: a|aa|aaaa

s小文字のみが含まれます。どのくらいのs時間がかかるかはわかりません。したがって、最適な時間の複雑さを推測することはできません。:(

NP難しい問題ですか?そうでない場合、どうすれば効率的に解決できますか?

友人からこの問題を聞いたが、答えられなかった。私はこの問題を解決するためにTrie +貪欲を使用しようとしています。最初の例では、メソッドは失敗します。

これが私が思いついたTrieソリューションです:

def triesolution(s):
    trie = {}
    p = trie
    output = 0
    for char in s:
        if char not in p:
            output += 1
            p[char] = {}
            p = trie
        else:
            p = p[char]
    return output

それを分割しようとしているので、実施例1について、上記のコードは、3を返しますsa|ab|abaa

追加:みんなのアイデアのおかげで、この問題はNP問題に非常に近いようです。今、私はこの方向から考えようとしています。関数があるとしますGuess(n)。この関数は、1つの分割などから一意の部分文字列をTrue見つけた場合に返されます。ここでの観察の1つは、ifの場合、すべての場合です。2つの隣接する部分文字列をマージできるからです。この観察は、バイナリソリューションにつながる可能性があります。ただし、関数を非常に効率的に計算できる必要があります。悲しいことに、私はまだ計算する多項式の方法を見つけることができませんでした。nFalseGuess(n) == TrueGuess(i) == Truei <= nGuessGuess(n)


最初のものも分割できるため、aab|a|b|aaまだ4のままです
smac89

3
好奇心から、あなたの弦はどれくらいの長さですか?
templatetypedef

aababaaは、a | aa | aab | aaba | aabab | aababa | aba | ...などに分割できます。どのようにしてたったの4になりましたか?
Suraj Motaparthy

文字列に含まれるのはaまたはb
Pham Trung

@PhamTrungいいえ。ただし、小文字のみが含まれていると想定できます。
wqm1800

回答:


15

これは衝突認識文字列パーティション問題として知られており、アンネコンドン、ジャンマチュフ、クリスタチュクによる論文の3-SATからの削減によりNP完全であることが示されています-衝突認識文字列パーティション問題の複雑さとその遺伝子合成のためのオリゴ設計との関係(International Computing and Combinatorics Conference、265-275、2008)。


その紙をざっと見たところ、結果は、各部分文字列に含めることができる文字数に上限がある場合、この問題がNP困難であることのみを示しているように見えます。それは正確ですか?その場合は、この問題とは少し異なります。類推によると、「ツリー内のノードの次数制約の対象となるMSTを見つける」という問題はNP困難ですが、MSTを見つけることは多項式時間で実行できます。
templatetypedef

1
この問題がNPハードであることを示すには、既知のNPハード問題(kパーティション)をこの問題(非制約パーティション)に減らすのではなく、逆にする必要があります。kパーティション化のソルバーはこの問題を確実に解決できますが、それはNP困難さを証明しません。
templatetypedef

この論文が問題を解決することはありません。私が理解しているように、この論文は、最大で長さkの部分文字列へのパーティションが存在する場合の意思決定問題に関するものです。kが文字列全体の長さの半分よりも大きい場合、その決定問題は(私が理解しているように)ほんの少し真実です。
Hans Olsson、

いいえ、問題が大きなkに対して簡単な解決策を持っているという事実は、kを小さくする必要があり、削減が機能することを意味しません。
templatetypedef

8

(私にこの議論を知らせてくれたGilad Barkan(גלעדברקן)に感謝します。)

純粋に理論的な観点からこの問題についての私の考えを共有させてください(「サブワード」の代わりに「ファクター」も使用していることに注意してください)。

ここで考慮されている問題(または複数の問題)の十分に正式な定義は次のとおりです。

単語wが与えられた場合、次のような単語u_1、u_2、...、u_kを検索します

  • u_i!= u_jすべてのi、jに対して1 <= i <j <= kおよび
  • u_1 u_2 ... u_k = w

最大化バリアント(多くのu_iが必要です):最大化k

最小化バリアント(短いu_iが欲しい):最小化max || u_i | :1 <= i <= k}

これらの問題は、「多因子」バリアントまたは「短因子」バリアントのどちらについて話しているかに応じて、kの下限であるBを追加して決定問題になります(少なくともB係数)、またはmaxの上限{| u_i | :1 <= i <= k}(最大でBの長さの係数が必要です)、それぞれ。NP困難性について話すには、意思決定の問題について話す必要があります。

「ショートファクター」バリアントにはSF、「マルチファクター」バリアントにはMFという用語を使用します。特に、これは本当に重要なポイントは、問題は、我々は上の単語を取得するようなAの方法で定義されている、あるいくつかの制限された任意の方法ではないアルファベット。問題のバージョンは、入力された単語のみを取得するというアプリオリを知っていた場合、たとえば、アルファベット{a、b、c、d}は別の問題です!NP硬度は、「無制限」から「固定アルファベット」バリアントに自動的に引き継がれませ(後者はより単純かもしれません)。

SFとMFはどちらもNP完全問題です。これはそれぞれ[1、1b]と[2]に示されています(Giladがすでに指摘したように)。この議論の冒頭にある(多分あまりに)非公式の問題定義を正しく理解していれば、この議論の問題はまさに問題のMFです。単語がいくつかの固定アルファベットに由来するように制限されていることは最初は言及されていませんが、小文字のみが使用されていると想定できると後で述べられています。これが固定アルファベット{a、b、c、...、z}の上の単語のみを考慮することを意味する場合、これは実際にはNP硬さの点で大きく変化します。

よく見ると、SFとMFの複雑さにいくつかの違いがあることがわかります。

  1. 論文[1、1b]は、アルファベットを2進数に固定した場合、SFはNP完全のままであることを示しています(より正確には、文字aとbおよび境界Bに単語wを付けると、ほとんどのB?)。
  2. 論文[1、1b]は、境界B = 2を修正した場合、SFがNP完全のままであることを示しています(より正確には、単語wを取得し、長さの異なる因子で最大2に因数分解できますか?)。
  3. 論文[3]は、アルファベットと境界Bの両方が固定されている場合、SFは多項式時間で解けることを示しています。
  4. 論文[2]は、MFがNP完全であることを示していますが、これはアルファベットが制限されていないか、アプリオリに固定されていない場合のみです。特に、問題がNP完全なものであるかどうかを、実際の設定では通常行われているように、固定されたアルファベットの入力単語のみを考慮した場合は、質問に回答しません
  5. 論文[3]は、入力境界Bが定数によって再び上限がある場合、つまり問題の入力がワードと{1、2、...、K}の境界Bである場合、多項式時間でMFを解くことができることを示しています。ここで、Kは固定定数です。

これらの結果に関するコメント:Wrt(1)および(2)、アルファベットがバイナリの場合、問題SFを困難にするために、境界Bも修正できないことは直感的に明らかです。逆に、B = 2を修正すると、難しいインスタンスを生成するために、アルファベットのサイズがかなり大きくなる必要があります。結果として、(3)はかなり自明です(実際、[3]は少し多めに言います。多項式だけでなく、| w | ^ 2倍のアルファベットサイズにのみ依存する係数も実行時に解決できます。およびバインドされたB)。(5)も難しいことではありません。Bと比較して単語が長い場合、単純に異なる長さの要素に分割することで、目的の因数分解を取得できます。そうでない場合は、すべての可能性を総当たりにすることができます。これはBでのみ指数関数的であり、この場合は定数であると想定されます。

だから、私たちが持っている絵は次のとおりです:固定されたアルファベットまたは固定された境界Bに対してさえ硬度があるので、SFはより難しく見えます。この点はSFよりも簡単ですが、対応する質問はアルファベットサイズで公開されています。したがって、固定アルファベットのMFもNP完全であることがわかったとしても、MFはSFよりも少し複雑ではありません。ただし、MFがポリタイムで固定アルファベットに対して解決できることが示されている場合、MFはSFよりもはるかに簡単であることが示されます...難しいのはやや人工的なものであるためです(無限のアルファベット!) 。

私は制限のあるアルファベットでMFのケースを解決しようと努力しましたが、それを解決することができず、それ以来作業を停止しました。私は他の研究者がそれを解決するために一生懸命努力したとは思いません(したがって、これはこれらの非常に難しいオープンな問題の1つではありません。私の推測では、固定アルファベットの場合もNP困難であると考えられますが、削減が非常に複雑であるため、「サイズが35以上のアルファベットの場合、MFは難しい」などの問題が発生する可能性があります。 。

さらなる文献に関して、私は論文[4]を知っています。この論文は、単語wをすべてパリンドロームである別個の因子u_1、u_2、...、u_kに分割する問題を検討します。これもまたNP完全です。

Giladが指摘した論文[5]をざっと見ました。ただし、別の設定を検討しているようです。この論文では、著者は、特定の単語にいくつの異なるサブシーケンスまたはサブワードを含めることができるかという組み合わせの質問に関心がありますが、これらは重複する場合があります。たとえば、aaabaabには20個の異なるサブワードa、b、aa、ab、ba、bb、aaa、aab、aba、baa、aaab、aaba、abaa、baab、aaaba、aabaa、abaab、aabaab、aaabaa、aaabaab(maybe I誤算されますが、あなたはアイデアを理解します)。それらのいくつかは、baaのように1回だけ出現し、いくつかはaaのようにいくつか出現します。いずれにせよ、問題は、どのようにして単語を分割して多くの異なる要素を取得できるかではありません。これは、個々のシンボルがそれぞれ1つの要素に寄与することを意味します。

これらの種類の問題に対する実際的な解決策について(私は理論家であることを念頭に置いて、これを塩の粒と考えてください):

  • 私の知る限り、固定アルファベット上の入力単語のみを考慮した場合、多項式時間でMFを解くことを除外する理論的な下限(NP硬度など)はありません。ただし、注意点が1つあります。ポリタイムアルゴリズムを取得した場合、これは固定アルファベットからのシンボル数で指数関数的に実行する必要があります(またはその関数の一部では指数関数的です)。それ以外の場合は、無制限のアルファベットの場合の多項式時間アルゴリズムになります。したがって、理論家として、シンボルの数と、MFのアルゴリズムを考案するのに何らかの形で役立つ場合にのみ、時間指数で計算できるアルゴリズムタスクを探しています。一方、そのようなアルゴリズムは存在せず、MFも固定アルファベットの場合はNP困難である可能性があります。

  • 実用的なソリューションに興味がある場合は、ソリューションを概算すると役立つ場合があります。したがって、最悪の場合の最適値の半分の大きさであることが保証されている分解を取得しても、それほど悪くはありません。

  • 証明可能な近似比を与えないが、実際の設定でうまく機能するヒューリスティックスも興味深いと思います。

  • 問題のインスタンスをSATまたはILPインスタンスに変換することはそれほど難しくないはずです。SA​​TまたはILPソルバーを実行して、最適なソリューションを取得することもできます。

  • 私の個人的な見解では、MFの固定アルファベットのケースがNPハードであるかどうかは不明ですが、問題が十分に難しいため、ヒューリスティックソリューションなどを探すことが正当化されることを示唆する十分な理論的洞察があります。実用的な設定でうまく機能します。


参考文献:

[1]アン・コンドン、ジャン・マヌッチ、クリス・タチュク:文字列分割の複雑さ。J.離散アルゴリズム32:24-43(2015)

[1b]アン・コンドン、ジャン・マヌッチ、クリス・タチュク:衝突を意識した文字列分割問題の複雑さと、遺伝子合成のオリゴ設計との関係。COCOON 2008:265-275

[2] Henning Fernau、Florin Manea、Robert Mercas、Markus L. Schmid:変数とのパターンマッチング:高速アルゴリズムと新しい硬度の結果。STACS 2015:302-315

[3] Markus L. Schmid:等式のない反復的な文字列分解を計算しています。理論。計算。サイエンス。618:42-51(2016)

[4] Bannai Hideo、Travis Gagie、Shunsuke Inenaga、JuhaKärkkäinen、Dominik Kempa、Marcin Piatkowski、Shimoto Sugimoto:多様なパリンドローム分解はNP完全です。Int。J.見つかりました。計算。サイエンス。29(2):143-164(2018)

[5] Abraham Flaxman、Aram Wettroth Harrow、Gregory B. Sorkin:非常に多くの異なるサブシーケンスとサブストリングを持つストリング。電気。J.コーム 11(1)(2004)


(!経由で投稿してくれてありがとう、)だけでは明確にするために、およそ参照上記の私のコメント[5]は、別の質問については確かだった-それはLukStorms'に対応したメインコメント欄に質問、「Nの任意の文字列についてP可能な文字の長さ、そのような文字列に含めることができる一意のサブ文字列の最大数は何ですか?」
גלעדברקן

3

ここに解決策がありますが、それは本当に速く爆発し、効率的な解決策の近くにはどこにもありません。最初に文字列を順序付けの問題なしに一意の部分文字列のリストに分解し、次にitertools.permutationを使用してそれらの部分文字列を元の文字列に再構成し、各置換をテストして元の文字列と一致するかどうかを確認します。

import itertools as it

def splitter(seq):                                                             
    temp = [seq]
    for x in range(1, len(seq)):
        print(seq[:x], seq[x:])
        temp.append(seq[:x])
        temp.append(seq[x:])
    return temp

if __name__ == "__main__":
    test = input("Enter a string: ")
    temp = splitter(test)
    copy = temp[::]
    condition = True
    for x in temp:
        if len(x) > 1:
            copy.extend(splitter(x))
    copy = sorted(list(set(copy)))
    print(copy)
    count = []
    for x in range(len(test)):
        item = it.permutations(copy, x)
        try:
            while True:
                temp = next(item)
                if "".join(list(temp)) == test:
                    if len(temp) == len(set(temp)):
                        count.append((len(temp), temp))
        except StopIteration:
            print('next permutation begin iteration')
            continue
    print(f"All unique splits: {count}")
    print(f"Longest unique split : {max(count)[0]}")

最初のテストでは、これを取得します。

All unique splits: [(1, ('aababaa',)), (2, ('a', 'ababaa')), (2, ('aa', 'babaa')), (2, 
('aab', 'abaa')), (2, ('aaba', 'baa')), (2, ('aabab', 'aa')), (2, ('aababa', 'a')), (3, 
('a', 'ab', 'abaa')), (3, ('a', 'aba', 'baa')), (3, ('a', 'abab', 'aa')), (3, ('aa', 'b',
 'abaa')), (3, ('aa', 'ba', 'baa')), (3, ('aa', 'baba', 'a')), (3, ('aab', 'a', 'baa')),
 (3, ('aab', 'ab', 'aa')), (3, ('aab', 'aba', 'a')), (3, ('aaba', 'b', 'aa')), (3,
 ('aaba', 'ba', 'a')), (4, ('a', 'aba', 'b', 'aa')), (4, ('aa', 'b', 'a', 'baa')), (4,
 ('aa', 'b', 'aba', 'a')), (4, ('aab', 'a', 'b', 'aa'))]
Longest unique split : 4

おそらくこれは何らかの方法で最適化できますが、このマシンではかなりの数秒かかります。


3

私はこの問題を試して、特定のインデックスでパーティションを作成するかどうかという観点から考えました。したがって、この関数は再帰的で、各インデックス1に2つのブランチを作成 します。インデックスiでパーティション分割しないでください。2. インデックスiでパーティション分割します。

パーティションに基づいて、私はセットに入力し、セットのサイズを返します

def max(a,b):
    if a>b: return a
    return b



def keep(last, current, inp, map):
    # print last
    # print current
    # print map

    if len(inp) == 2 :
        if inp[0]==inp[1]: return 1
        return 2

    if current >= len(inp):
        return len(map)
    // This is when we are at the start of the string. 
    // In this case we can only do one thing not partition and thus take the entire string as a possible string.

    if current == last :
        map11 = map.copy()
        map11.add(inp[current:])
        return keep(last, current + 1, inp, map11)

    map1 = map.copy();
    if current != (len(inp)-1):
        map1.add(inp[last:current])

    map2 = map.copy()

    return max(keep(last,current+1,inp, map2), keep(current, current+1, inp, map1))

print keep(0,0,"121", set([]))
print keep(0,0,"aaaaaaa", set([]))
print keep(0,0,"aba", set([]))
print keep(0,0,"aababaa", set([]))
print keep(0,0,"21", set([]))
print keep(0,0,"22", set([]))

https://onlinegdb.com/HJynWw-iH


解決策をありがとう!このDFSソリューションは非常に明確です。関数は非常に時間がかかるkeepので、set.copy()関数を加速することができる小さな提案が1つあります。この関数スタックを終了するときのバックトラッキングを使用して、現在の候補をセットから削除しませんか?
wqm1800

@ wqm1800精巧に説明してもらえますか、正確に理解できなくて申し訳ありません。バックトラックを使用する場合でも、merge常に分岐しているため、セットを分離する必要があります。したがって、そのマージまたはコピーのいずれかです。詳しく説明できますか?
Ravi Chandak

1
これが私のバックトラックソリューションです。関数スタックはDFSウェイとして実行されるため、これは機能する可能性があります。関数が終了すると、関数のすべてのサブツリーの検索が終了したことになります。
wqm1800

3

セットを2番目のパラメーターとして再帰関数を使用して、現在のパス内の一意の文字列をこれまで追跡できます。再帰ごとに、すべてのインデックスに1を加えたものを繰り返し、候補となる候補ストリングのストリングを分割します。候補ストリングがまだセットにない場合は、残りのストリングと候補をセットに追加して再帰呼び出しを行います。残りの文字列から一意の部分文字列の最大数を取得するには、それに1を加算して、反復から最大値の最大値を返します。指定された文字列が空であるか、すべての候補文字列がすでにセット内にある場合、0を返します。

def max_unique_substrings(s, seen=()):
    maximum = 0
    for i in range(1, len(s) + 1):
        candidate = s[:i]
        if candidate not in seen:
            maximum = max(maximum, 1 + max_unique_substrings(s[i:], {candidate, *seen}))
    return maximum

デモ:https : //repl.it/@blhsing/PriceyScalySphere

Python 3.8では、上記のロジックはmax、割り当て式で「見られた」候補をフィルターするジェネレータ式を使用した関数の呼び出しで記述することもできます。

def max_unique_substrings(s, seen=()):
    return max((1 + max_unique_substrings(s[i:], {candidate, *seen}) for i in range(1, len(s) + 1) if (candidate := s[:i]) not in seen), default=0)

1

これがグラフ理論に基づく答えです。

モデル化
、この問題がサイズのグラフ上の最大独立集合問題としてモデル化することができるO(n²)次のように
させるw = c_1, ..., c_n入力文字列です。
ましょうG = (V,E)、次のように構築された無向グラフ、こと:
V = { (a, b) such that a,b in [1, n], a <= b }。我々は、サイズがいることを確認できVているn(n-1)/2各頂点のサブストリングを表し、w
その後、頂点のすべてのカップルのために(a1, b1)(a2, b2)、私たちはエッジ構築((a1, b1), (a2, b2))IFFを
(I)[a1, b1]と交差[a2, b2]または
(ⅱ) c_a1...c_b1 = c_a2...c_b2
別の言い方をすると、(i)それらが表す部分文字列が重複している場合、wまたは(ii)2つの部分文字列が等しい場合、2つの頂点間にエッジを作成します。

次に、最大の独立したセットG問題の答えを提供する理由を確認できます。

複雑さ
一般的なケースでは、最大独立集合(MIS)問題はNP困難であり、時間の複雑さはO(1.1996^n)多項式空間にあります[Xiao、NamaGoshi(2017)]
最初に、結果のグラフは弦グラフ(長さ> 3の誘導サイクルなし)になると思っていましたが、このクラスのグラフでMIS問題を線形時間で解決できるため、これは非常に優れています。
しかし、そうではないことにすぐに気付きました。長さ5以上の誘導サイクルがある例を見つけるのは非常に簡単です。
実際、結果のグラフは、私たちが通常探している「素敵な」特性を示さず、MIS問題の複雑さを多項式の問題に減らすことができます。
これは、問題の複雑さの上限にすぎません。多項式時間の短縮は一方向にしか行かないためです(この問題をMIS問題に減らすことはできますが、少なくともその逆はできません)。したがって、最終的O(1.1996^(n(n-1)/2))には最悪の場合、この問題を解決することになります。
だから、悲しいかな、私はそれがPにあること、またはそれがNP完全またはNP困難であることを証明できませんでした。確かに問題はNPにあるということですが、これは誰にとっても驚きではないと思います。

実装
この問題をMIS問題に減らすことの利点は、MISが古典的な問題であり、いくつかの実装が見つかることと、MIS問題もILPとして簡単に記述できることです。
MIS問題のILP公式は次のとおりです。

Objective function 
maximize sum(X[i], i in 1..n)
Constraints:
for all i in 1..n, X[i] in {0, 1}
for all edge (i, j), X[i] + X[j] <= 1

私の意見では、ILPソルバーは特に大きなインスタンスに関しては非常に効率的であるため、(このモデリングをMIS問題として使用して)この問題を解決する最も効率的な方法である必要があります。

これは、Python3とGLPKソルバーを使用して実装したものです。テストするには、Cplexファイル形式と互換性のあるLPソルバーが必要です。

from itertools import combinations

def edges_from_string(w):
    # build vertices
    vertices = set((a, b) for b in range(len(w)) for a in range(b+1))
    # build edges
    edges = {(a, b): set() for (a, b) in vertices}
    for (a1, b1), (a2, b2) in combinations(edges, 2):
        # case: substrings overlap
        if a1 <= a2 <= b1:
            edges[(a1, b1)].add((a2, b2))
        if a2 <= a1 <= b2:
            edges[(a2, b2)].add((a1, b1))
        # case: equal substrings
        if w[a1:b1+1] == w[a2:b2+1]:
            if a1 < a2:
                edges[(a1, b1)].add((a2, b2))
            else:
                edges[(a2, b2)].add((a1, b1))
    return edges

def write_LP_from_edges(edges, filename):
    with open(filename, 'w') as LP_file:
        LP_file.write('Maximize Z: ')
        LP_file.write("\n".join([
            "+X%s_%s" % (a, b)
            for (a, b) in edges
        ]) + '\n')
        LP_file.write('\nsubject to \n')
        for (a1, b1) in edges:
            for (a2, b2) in edges[(a1, b1)]:
                LP_file.write(
                    "+X%s_%s + X%s_%s <= 1\n" %
                    (a1, b1, a2, b2)
                )
        LP_file.write('\nbinary\n')
        LP_file.write("\n".join([
            "X%s_%s" % (a, b)
            for (a, b) in edges.keys()
        ]))
        LP_file.write('\nend\n')
write_LP_from_edges(edges_from_string('aababaa'), 'LP_file_1')
write_LP_from_edges(edges_from_string('kzshidfiouzh'), 'LP_file_2')

あなたは、その後でそれらを解決することができglpsolます。コマンド文字列のサイズが大きくなるにつれて....厳しい(私のラップトップ上で0.02秒)早く解決しますが、期待される、物事は(あまり)を取得として このプログラムは数値のみを与える(とは最適なパーティション)、それにもかかわらず、最適なパーティションと対応する部分文字列は、pyomoなどのLPソルバー/ Pythonインターフェイスを使用して、同様の実装で見つけることができます
glpsol --lp LP_file_1
aababaa

時間とメモリ
aababaa:0.02秒、0.4 MB、値:4
kzshidfiouzh:1.4秒、3.8 MB、値:10
aababababbababab:60.2秒、31.5 MB、値:8
kzshidfiouzhsdjfyu:207.5秒、55.7 MB、値:14
LPソルバーも提供することに注意してくださいソリューションの現在の下限と上限なので、最後の例では、1分後に実際のソリューションを下限として取得できました。


モデリングは、ソリューションの実装には役立ちますが、複雑さの軽減または証明ではありません。私はもともとこの非常にモデル(MIS)をメインの回答の下にコメントとして書いて、後でそれを削除しました。このトピックに関する論文を執筆した数少ない理論家の1人であるMarkus Schmidは、すでにこのWebページで詳細な回答を提供しています。決定問題の複雑さのクラスは、文献で公開されたままです。
גלעדברקן

この場合、当然、「接続(エッジ)フリー」なものの大規模なグループを探しているため、MISは些細な関連の一種です。たとえば、1文字のアルファベットの場合、答えは単純な多項式時間解がある数値パーティションです。より多くの研究があればO(n ^ 2)ベースのLPを回避できる最適化を提供する問題の側面があり、MISビューで一時停止すると見逃される可能性があります。しかし、それは一般的な作業ソリューションに最適です。
גלעדברקן

私の答えを読みましたか?私は、MISからこの問題への簡単な一方向の多項式時間削減を提供します。単一文字のアルファベットに関しては、問題は明らかにPにあり、貪欲なささいな解決策があります。
m.raynal

MISに基づいてその複雑さのクラスを想定しているようです。
גלעדברקן

だから答えを読んでください:-)あなたはそれがそうではないことがわかります、私は問題の複雑さの上限を与えるためにMISの複雑さのみを使用しています。下限ではありません。
m.raynal

0

私の他の答えは密接に関連していましたが、この問題に正確には対応していませんでした。引用された論文で扱われている)。

この論文では、変数とのパターンマッチング:高速アルゴリズムと新しい硬度の結果(Henning Fernau、Florin Manea、RobertMercaş、Markus L. Schmid、Proc。32nd Symposium on Theoretical Aspects of Computer Science、STACS 2015、volume 30 of Leibniz International Proceedings in Informatics(LIPIcs)、pages 302–315、2015)、著者は、特定の数kと単語についてw、個別の要因に因数w分解できるかどうかを決定することはNP完全であることを示していkます。

我々はtemplatetypedefの考える場合はコメントを、そして確かに私たちはに文字列を分割することができれば、我々はその答えに、このようなアルゴリズムを使用することができます無制限の、最大の平等フリー因数分解に多項式時間ソリューションがある可能性が暗示kするだけならば観察することによって個別の要因(ストリング)kです私たちがすでに知っている最大よりも少ない。

しかし、Schmid(2016)は、「アルファベットが修正された場合、MaxEFF-sがNP完全のままであるかどうかは未解決の問題です」と書いています。(平等のない反復的な文字列因数分解の計算、理論計算機科学第618巻、2016年3月7日、ページ42-51)

ただし、最大不等分解因数分解サイズ(MaxEFF-s)は引き続きパラメーター化されており、次のように定義されます。

インスタンス:単語wと数字m1 ≤ m ≤ |w|

質問:の平等のない因数分解pはwありs(p) ≥ mますか?(s(p)因数分解のサイズです。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.