Максимальное количество уникальных подстрок из раздела

30

Я изменил название так, чтобы оно было более понятным.

Вот подробная версия вопроса:

У нас есть строка, s и мы хотим разбить ее на подстроки . Каждая подстрока отличается друг от друга. Какое максимальное количество уникальных подстрок мы можем получить из одного среза. Другими словами, каково максимальное количество уникальных подстрок, которые объединяются в форму 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

Например, приведенный выше код вернет 3, поскольку он пытается разбить sна a|ab|abaa.

Добавить: Благодаря идее каждого, похоже, что эта проблема очень близка к проблеме NP. Прямо сейчас я пытаюсь думать об этом с этой стороны. Предположим, у нас есть функция Guess(n). Эта функция вернется, Trueесли мы сможем найти nуникальные подстроки из одного разбиения или Falseиначе. Одно наблюдение здесь, что если Guess(n) == True, то Guess(i) == Trueдля всех i <= n. Так как мы можем объединить две соседние подстроки. Это наблюдение может привести к бинарному решению. Тем не менее, это все еще требует, чтобы мы могли вычислить Guessфункцию очень эффективно. К сожалению, я все еще не мог найти полиномиальный способ вычисления Guess(n).

wqm1800
источник
Первый также может быть разделен на aab|a|b|aa4
smac89
3
Из любопытства, как долго могут длиться твои струны?
templatetypedef
aababaa можно разделить на | aa | aab | aaba | aabab | aababa | aba | ... и так далее. Как ты получил только 4?
Suraj Motaparthy
Строка содержит только aили b?
Фам Трунг
@PhamTrung Нет, но вы можете предположить, что он содержит только строчные буквы.
wqm1800

Ответы:

15

Это известно как проблема разделения строк с учетом столкновений, и показано, что она является NP-полной за счет сокращения от 3-SAT в статье Анны Кондон, Яна Мауча и Криса Тачука - Сложность проблемы разделения строк с учетом столкновений и ее связь с олиго-дизайном для синтеза генов ( Международная конференция по вычислительной технике и комбинаторике , 265-275, 2008).

גלעד ברקן
источник
Я бегло осмотрел эту статью, и, похоже, результат доказывает, что это только показывает, что эта проблема сложна с точки зрения NP в случае, когда существует верхний предел количества символов, которое может быть в каждой подстроке. Это точно? Если так, то это немного отличает эту проблему. Рассуждая по аналогии, найти MST можно за полиномиальное время, даже если задача «найти MST с ограничением степени на узлах в дереве» является NP-трудной.
templatetypedef
1
Чтобы показать, что эта проблема является NP-сложной, мы должны быть в состоянии свести известную проблему NP-hard (k-разбиение) к этой проблеме (неограниченное разбиение), а не наоборот. Решатель для k-разбиения определенно может решить эту проблему, но это не доказывает NP-твердость.
templatetypedef
Я не вижу, что статья решает проблему: насколько я понимаю, статья о проблеме решения, если существует разбиение на подстроки длиной не более k. Если k больше половины длины строки, решение проблемы тривиально верно (насколько я понимаю).
Ганс Олссон
Нет, тот факт, что проблема имеет тривиальное решение для больших k, не означает, что k должно быть небольшим, и сокращение будет работать.
templatetypedef
8

(Большое спасибо Гиладу Баркану (גלעד ברקן) за то, что он дал мне знать об этом обсуждении.)

Позвольте мне поделиться своими мыслями об этой проблеме с чисто теоретической точки зрения (обратите внимание, что я также использую «фактор» вместо «подслово»).

Я думаю, что достаточно формальное определение рассматриваемой здесь проблемы (или проблем) заключается в следующем:

По заданному слову 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}

Эти проблемы становятся проблемами решения, если дополнительно дать оценку B, которая, в зависимости от того, говорим ли мы о «многофакторном» варианте или «короткофакторном», является нижней границей k (мы хотим по крайней мере B факторы), или верхняя граница max {| u_i | : 1 <= i <= k} (мы хотим, чтобы факторы длины были не более B), соответственно. Чтобы говорить о NP-сложности, нам нужно поговорить о решении проблем.

Давайте использовать термины SF для «коротких факторов» -варианта и MF для «многих факторов» -варианта. В частности, и это действительно важный момент, проблемы определены таким образом, что мы получаем слово в некотором алфавите, который никоим образом не ограничен. Версия проблемы, в которой мы знаем априори, что мы получаем только входные слова, скажем, по алфавиту {a, b, c, d}, - это другая проблема! NP-твердость вовсе не автоматически переносятся из «неограниченного» на «фиксированный алфавит» вариант (последний может быть проще).

Как SF, так и MF являются NP-полными задачами. Это было показано в [1, 1b] и [2] соответственно (как уже указывал Гилад). Если я правильно понимаю (возможно, слишком) неформальное определение проблемы здесь, в начале этого обсуждения, то проблема этого обсуждения - именно проблема MF. Первоначально не упоминается, что слова ограничены, чтобы прийти из некоторого фиксированного алфавита, позже говорится, что мы можем предположить, что используются только строчные буквы. Если это означает, что мы рассматриваем слова только с фиксированным алфавитом {a, b, c, ..., z}, то это на самом деле сильно изменится с точки зрения NP-твердости.

При ближайшем рассмотрении выявляются некоторые различия в сложности SF и MF:

  1. В статье [1, 1b] показано, что SF остается NP-полной, если мы фиксируем алфавит в двоичном (точнее: получая слово w над буквами a и b и границей B, можем ли мы разложить его на разные множители длины при самое б?).
  2. статья [1, 1b] показывает, что SF остается NP-полной, если мы фиксируем оценку B = 2 (точнее: получая слово w, можем ли мы разложить его на различные множители длины не более 2?).
  3. В работе [3] показано, что если и алфавит, и граница B фиксированы, то SF можно решить за полиномиальное время.
  4. статья [2] показывает, что MF является NP-полной, но только если алфавит не ограничен или фиксирован априори! В частности, он не отвечает на вопрос, является ли задача NP-полной, если мы рассматриваем входные слова только по некоторому фиксированному алфавиту (как это обычно бывает в практических условиях).
  5. В работе [3] показано, что MF может быть решена за полиномиальное время, если входные границы B снова ограничены сверху некоторой константой, т. е. входной вопрос задачи является словом и границей B из {1, 2, ..., K} где K - некоторая фиксированная константа.

Некоторые комментарии к этому результату: Wrt (1) и (2), интуитивно понятно, что если алфавит является двоичным, то для усложнения задачи SF граница B также не может быть зафиксирована. И наоборот, установка B = 2 означает, что размер алфавита должен быть достаточно большим, чтобы создавать сложные экземпляры. Как следствие, (3) является довольно тривиальным (на самом деле, [3] говорит немного больше: тогда мы можем решить это во время выполнения не только полиномиального, но также и | w | ^ 2 раза множителя, который зависит только от размера алфавита и связаны Б). (5) тоже не сложно: если наше слово длиннее по сравнению с B, то мы можем получить желаемую факторизацию, просто разбив на факторы разной длины. Если нет, то мы можем перебрать все возможности, которые экспоненциальны только в B, который в этом случае предполагается постоянным.

Итак, картина, которую мы имеем, выглядит следующим образом: SF кажется более трудным, потому что у нас есть твердость даже для фиксированных алфавитов или для фиксированной границы B. С другой стороны, проблема MF становится многократной, разрешимой, если граница фиксирована (в это проще, чем SF), в то время как соответствующий вопрос по размеру алфавита открыт. Таким образом, MF немного менее сложен, чем SF, даже если окажется, что MF для фиксированных алфавитов также NP-завершен. Однако, если можно показать, что MF может быть решена для фиксированных алфавитов за многократное время, то MF будет гораздо проще, чем SF ... потому что один случай, для которого это сложно, является несколько искусственным (неограниченный алфавит!) ,

Я приложил некоторые усилия, чтобы попытаться разрешить случай MF с помощью ограниченного алфавита, но я не смог уладить его и с тех пор прекратил работать над ним. Я не верю, что другие исследователи изо всех сил пытались решить ее (так что это не одна из этих очень сложных открытых проблем, многие люди уже пытались и потерпели неудачу; я считаю, что это как-то выполнимо). Я предполагаю, что это также NP-hard для фиксированных алфавитов, но, возможно, сокращение настолько сложно, что вы могли бы получить что-то вроде «MF is hard для алфавитов размером 35 или больше» или что-то, что тоже не было бы супер приятно ,

Что касается дальнейшей литературы, мне известна статья [4], в которой рассматривается проблема разбиения слова w на отдельные факторы u_1, u_2, ..., u_k, которые являются палиндромами, что также является NP-полным.

Я быстро взглянул на статью [5], на которую указал Гилад. Похоже, рассмотреть другие настройки, хотя. В этой статье авторов интересует комбинаторный вопрос о том, сколько разных подпоследовательностей или подслов может содержаться в данном слове, но они могут перекрываться. Например, aaabaab содержит 20 различных подслов a, b, aa, ab, ba, bb, aaa, aab, aba, baa, aaab, aaba, abaa, baab, aaaba, aabaa, abaab, aabaab, aaabaa, aaabaab (возможно, я просчитался, но вы поняли). Некоторые из них имеют только одно вхождение, например baa, некоторые из них несколько, например aa. В любом случае, вопрос не в том, как мы можем каким-то образом разделить слово, чтобы получить много разных факторов, поскольку это означает, что каждый отдельный символ вносит свой вклад ровно в один фактор.

Что касается практических решений таких проблем (имейте в виду, что я теоретик, так что возьмите это с крошкой соли):

  • Насколько мне известно, не существует теоретических нижних границ (например, NP-твердости), которые исключали бы возможность решать MF за полиномиальное время, если мы рассмотрим только входные слова в фиксированном алфавите. Однако есть одно предостережение: если вы получаете алгоритм поли-времени, то он должен работать экспоненциально в количестве символов из фиксированного алфавита (или экспоненциально в некоторой функции этого)! В противном случае это был бы также алгоритм полиномиального времени для случая неограниченных алфавитов. Так что, будучи теоретиком, я бы искал алгоритмические задачи, которые можно вычислить по экспоненте, только если число символов и которые каким-то образом помогают разработать алгоритм для MF. С другой стороны, вероятно, что такого алгоритма не существует, и MF также NP-труден в случае с фиксированным алфавитом.

  • Если вы заинтересованы в практических решениях, может быть полезно приблизить решение. Таким образом, получение факторизации, которая гарантированно будет вдвое меньше оптимальной в худшем случае, не будет слишком плохим.

  • Эвристика, которая не дает доказуемого коэффициента аппроксимации, но хорошо работает на практике, также будет интересна, я думаю.

  • Преобразование экземпляров проблемы в экземпляры SAT или ILP не должно быть слишком сложным, и тогда вы можете запустить SAT или ILP-Solver, чтобы даже получить оптимальные решения.

  • Мое личное мнение таково, что хотя неизвестно, является ли случай MF с фиксированным алфавитом NP-сложным, существует достаточно теоретических выводов, которые предполагают, что проблема достаточно сложна, так что оправданно искать эвристические решения и т.д., которые хорошо работать в практической обстановке.


Список используемой литературы:

[1] Энн Кондон, Ян Мануч, Крис Тачук: Сложность разбиения строк. J. Дискретные алгоритмы 32: 24-43 (2015)

[1b] Энн Кондон, Ян Мануч, Крис Тачук: Сложность проблемы разделения строк с учетом столкновений и ее связь с олиго-дизайном для синтеза генов. COCOON 2008: 265-275

[2] Хеннинг Фернэу, Флорин Манеа, Роберт Меркас, Маркус Л. Шмид: Сопоставление шаблонов с переменными: быстрые алгоритмы и новые результаты твердости. STACS 2015: 302-315

[3] Маркус Л. Шмид: Вычисление равноправных и повторяющихся факторизаций струн. Теор. Вычи. Sci. 618: 42-51 (2016)

[4] Хидео Баннаи, Трэвис Гэги, Шунсуке Иненага, Юха Кярккяйнен, Доминик Кемпа, Марцин Пятковски, Шихо Сугимото: Разнообразная палиндромная факторизация является NP-полной. Int. J. Найдено. Вычи. Sci. 29 (2): 143-164 (2018)

[5] Авраам Флэксман, Арам Веттрот Харроу, Грегори Б. Соркин: Строки с максимально большим количеством различных подпоследовательностей и подстрок. Электр. J. Comb. 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

Возможно, это можно как-то оптимизировать, но это займет довольно много секунд на этой машине.

neutrino_logic
источник
3

Я дал этой проблеме попытку и думал об этом с точки зрения или сделать ли раздел по данному индексу. Таким образом, эта функция является рекурсивной и создает 2 ветви в каждом индексе 1. Не делайте разбиения в индексе 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()функция очень трудоемкая. Как насчет обратного отслеживания, когда закончите этот стек функций, удалите текущего кандидата из набора?
wqm1800
@ wqm1800 Можете ли вы уточнить, извините, я не совсем понимаю. Даже если мы используем возврат, нам все равно придется mergeразделять наборы, поскольку мы всегда разветвляемся. Следовательно, это либо слияние, либо копирование. Можешь уточнить?
Рави Чандак
1
Вот мое решение для возврата . Это может сработать, потому что стек функций выполняется как DFS, поэтому, когда функция завершает работу, это означает, что она закончила поиск по всем ее поддеревьям.
wqm1800
3

Вы можете использовать рекурсивную функцию с набором в качестве второго параметра, чтобы отслеживать уникальные строки в текущем пути. Для каждой рекурсии переберите все индексы плюс 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)
blhsing
источник
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))тогда
и только тогда, когда (i) [a1, b1]пересекается [a2, b2]или
(ii) c_a1...c_b1 = c_a2...c_b2.
Иначе говоря, мы строим ребро между двумя вершинами, если (i) подстроки, которые они представляют, перекрываются wили (ii) две подстроки равны.

После этого мы можем понять , почему максимальное независимое множество из 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.
Вот формулировка ILP проблемы MIS:

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

На мой взгляд, это должен быть наиболее эффективный способ решения этой проблемы (с использованием этого моделирования в качестве задачи MIS), поскольку решатель ILP невероятно эффективен, особенно когда речь идет о крупных случаях.

Это реализация, которую я сделал с использованием Python3 и решателя GLPK . Чтобы проверить это, вам нужен LP-решатель, совместимый с форматом файла Cplex.

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команды:
glpsol --lp LP_file_1
« aababaaРешается быстро» (0,02 сек на моем ноутбуке), но, как и ожидалось, все становится намного (намного) сложнее с ростом размера строки ....
Эта программа дает только числовое значение (а не оптимальное разбиение), тем не менее, оптимальное разбиение и соответствующие подстроки могут быть найдены с аналогичной реализацией, используя интерфейс LP solver / python, такой как pyomo

Время и память
aababaa : 0,02 секунды, 0,4 МБ, значение: 4
kzshidfiouzh: 1,4 секунды, 3,8 МБ, значение: 10
aababababbababab: 60,2 секунды, 31,5 МБ, значение: 8
kzshidfiouzhsdjfyu: 207,5 секунды, 55,7 МБ, значение: 14
Обратите внимание, что решатель LP также предлагает текущие нижняя и верхняя границы решения, поэтому для последнего примера я мог бы получить реальное решение в виде нижней границы через минуту.

m.raynal
источник
Моделирование не является сокращением или доказательством сложности, хотя может быть полезным при реализации решений. Первоначально я написал эту модель (MIS) в качестве комментария под основным ответом, а затем удалил ее. Маркус Шмид, один из немногих теоретиков-авторов статей на эту тему, уже представил подробный ответ на этой веб-странице. Класс сложности решения проблемы остается открытым в литературе.
גלעד ברקן
В этом случае MIS является своего рода тривиальной ассоциацией, так как, конечно, мы ищем большую группу «свободных от соединения (ребер)» вещей. Например, для односимвольного алфавита ответом является числовое разбиение, для которого было бы простое решение за полиномиальное время. Могут быть аспекты проблемы, которые предлагают оптимизацию, которая может обойти LP на основе O (n ^ 2), учитывая больше исследований, и будет упущена из-за паузы в представлении MIS. Но это выглядит отлично для общего рабочего решения.
גלעד ברקן
Вы читали мой ответ? Я предлагаю тривиальное однонаправленное полиномиальное сокращение времени от MIS к этой проблеме, а не наоборот. Что касается односимвольного алфавита, проблема явно в P с жадным тривиальным разрешением.
м.райнал
Казалось, что вы сделали предположения о его классе сложности на основе MIS.
גלעד ברקן
Так что прочитайте ответ :-) вы увидите, что это не так, я использую только сложность MIS, чтобы дать верхнюю границу сложности проблемы. Не нижняя граница.
м.райнал
0

Мой другой ответ был тесно связан, но не точно соответствовал этой проблеме, оставляя неоднозначным, может ли нахождение наибольшей факторизации строки без равенства иметь класс сложности, отличающийся от того, существует ли факторизация без равенства с длиной связанного фактора (последний решается в цитируемой статье).

В статье «Сопоставление с образцом с переменными: быстрые алгоритмы и новые результаты твердости» (Хеннинг Фернэу, Флорин Манеа, Роберт Меркаш и Маркус Л. Шмид, в Proc. 32-й симпозиум по теоретическим аспектам информатики, STACS 2015, том 30, Лейбниц Международные труды в области информатики (LIPIcs) , стр. 302–315, 2015 г.), авторы показывают, что NP-завершено, чтобы решить, для данного числа kи слова w, wможно ли разложить на kотдельные факторы.

Если мы рассмотрим комментарий templatetypedef , подразумевая, что может быть решение неограниченной, наибольшей факторизации без равенства с полиномиальным временем, тогда, конечно, мы могли бы использовать такой алгоритм, чтобы ответить, если бы мы могли разбить строку на kотдельные факторы (подстроки), просто наблюдая, если kесть меньше, чем максимум, который мы уже знаем.

Шмид (2016), однако, пишет, что «все еще остается открытой проблемой, остается ли MaxEFF-s NP-полным, если алфавит фиксирован». (Вычисление равноправных и повторяющихся факторизаций струн, Теоретическая информатика, Том 618 , 7 марта 2016 г., стр. 42-51)

Максимальный размер факторизации без равенства (MaxEFF-s) все еще параметризован и определяется как:

Instance: слово wи число m, 1 ≤ m ≤ |w|.

Вопрос: существует ли равноправная факторизация p of wс s(p) ≥ m? ( s(p)будучи размером факторизации.)

גלעד ברקן
источник