Максимальна кількість унікальних підрядів з розділу


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

Для прикладу 1, наведений вище код буде повертати 3 , оскільки він намагається розкол sв a|ab|abaa.

Додайте: Завдяки всім ідеям, схоже, ця проблема дуже близька до проблеми NP. Зараз я намагаюся думати це з цього напрямку. Припустимо, у нас є функція Guess(n). Ця функція повернеться, Trueякщо ми зможемо знайти nунікальні підрядки з одного розбиття чи Falseіншого. Одне спостереження тут полягає в тому, що якщо Guess(n) == True, то Guess(i) == Trueдля всіх i <= n. Оскільки ми можемо об'єднати дві сусідні підрядки разом. Це спостереження може призвести до бінарного рішення. Однак це все ще вимагає, щоб ми могли обчислити Guessфункцію дуже ефективно. На жаль, я все ще не міг знайти поліноміальний спосіб обчислення Guess(n).


Перший також можна розділити, як aab|a|b|aaце все ще 4
smac89

3
Як цікаво, як довго можуть дістатися твої струни?
templatetypedef

аабаба може бути розділена на | аа | ааб | ааба | аабаб | аабаба | аба | ... тощо. Як у вас вийшло всього 4?
Сурай Мотапарті

Рядок містить лише 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): мінімізувати максимум {| u_i | : 1 <= i <= k}

Ці проблеми стають проблемами вирішення, додатково даючи пов'язану B, яка відповідно до того, чи говоримо ми про "багатофакторну" -варіантну або "коротку фактори" -варіантну, є нижньою межею k (ми хочемо принаймні B факторів) або верхня межа макс {| u_i | : 1 <= i <= k} (ми хочемо, щоб коефіцієнти довжини були не більше B) відповідно. Якщо говорити про твердість NP, нам потрібно поговорити про проблеми рішення.

Давайте використовуємо терміни SF для "коротких факторів" -варіант і MF для "багатьох факторів" -варіант. Зокрема, і це дійсно вирішальний момент, проблеми визначаються таким чином, що ми отримуємо слово над деяким алфавітом, який жодним чином не обмежений. Версія проблеми, коли ми апріорі знали, що ми отримуємо лише вхідні слова над, скажімо, алфавітом {a, b, c, d} - це інша проблема! NP-твердість не переходить автоматично від "необмеженого" до "фіксованого алфавіту" (останній може бути простішим).

І SF, і MF - це проблеми, що не стосуються NP. Це було показано у [1, 1b] та [2] відповідно (як уже вказував Гілад). Якщо я зрозумів (можливо, занадто) неофіційне визначення проблеми тут на початку цієї дискусії правильно, то проблема цієї дискусії - саме проблема МФ. Спочатку не згадується, що слова можуть походити з якоїсь фіксованої абетки, пізніше йдеться про те, що ми можемо вважати, що використовуються лише малі літери. Якщо це означає, що ми розглядаємо лише слова над фіксованим алфавітом {a, b, c, ..., z}, то це фактично змінило б насправді з точки зору твердості NP.

При ближчому розгляді виявляються деякі відмінності в складності СФ та ПН:

  1. стаття [1, 1b] показує, що SF залишається NP-завершеним, якщо ми зафіксуємо алфавіт до двійкового (точніше: отримавши слово w над літерами a і b і пов'язаним B, чи можемо ми поділити його на різні коефіцієнти довжини при найбільше Б?).
  2. документ [1, 1b] показує, що SF залишається NP-повним, якщо ми фіксуємо пов'язану B = 2 (точніше: отримавши слово w, чи можемо ми його розрізнити на різні коефіцієнти довжини не більше 2?).
  3. Папір [3] показує, що якщо і алфавіт, і зв'язаний В є фіксованими, то 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-важко для фіксованих алфавітів, але, можливо, скорочення настільки складне, що ви отримаєте щось на кшталт "MF важко для алфавітів розміром 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, абаа, baab, aaaba, aabaa, abaab, aabaab, aaabaa, aaabaab (можливо, я неправильно рахувати, але ви розумієте). Деякі з них мають лише одне явище, як baa, деякі з них кілька, як aa. У будь-якому випадку, питання полягає не в тому, як ми можемо якось розділити слово, щоб отримати багато різних факторів, оскільки це означає, що кожен окремий символ сприяє рівно одному фактору.

Що стосується практичного вирішення подібних проблем (майте на увазі, що я теоретик, тому прийміть це із зерном солі):

  • Наскільки мені відомо, немає жодних теоретичних нижчих меж (наприклад, твердість NP), які виключали б рішення МФ у поліноміальний час, якщо ми розглянемо лише вхідні слова через фіксований алфавіт. Однак є одне застереження: Якщо ви отримуєте алгоритм багаторазового часу, то він повинен працювати експоненціально в кількості символів фіксованого алфавіту (або експоненціальної в деякій функції цього)! Інакше це був би також поліноміальний алгоритм часу для випадку безмежних алфавітів. Отже, будучи теоретиком, я б шукав алгоритмічні завдання, які можна обчислити в експоненціальному часі лише за умови, що кількість символів і якимось чином допоможуть розробити алгоритм для MF. З іншого боку, ймовірно, що такого алгоритму не існує, і MF також є жорстким NP у випадку фіксованого алфавіту.

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

  • Евристика, яка не дає переліченого коефіцієнта наближення, але добре працює в практичній обстановці, також була б цікава.

  • Трансформація проблемних примірників у SAT або ILP-інстанції не повинна бути надто складною, і тоді ви можете запустити SAT або ILP-Solver, щоб навіть отримати оптимальні рішення.

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


Бібліографія:

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

[1b] Енн Кондон, Ян Манух, Кріс Тачук: Складність проблеми, що усвідомлює колізію, і струнко-стрункову зв'язок із дизайном Оліго для синтезу генів. КОКОН 2008: 265-275

[2] Геннінг Фернау, Флорін Манеа, Роберт Меркас, Маркус Л. Шмід: Узгодження картини зі змінними: швидкі алгоритми та нові результати твердості. STACS 2015: 302-315

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

[4] Hideo Bannai, Travis Gagie, Shunsuke Inenaga, Juha Kärkkäinen, Dominik Kempa, Marcin Piatkowski, Shiho Sugimoto: Різноманітна паліндромна факторизація завершена NP. Int. J. Знайдено. Обчислення. Наук. 29 (2): 143-164 (2018)

[5] Авраам Флексман, Арам Веттрот Борона, Грегорі Б. Соркін: Струни з максимально багатьма чіткими наслідками та підрядками. Електр. Дж. Гребінь. 11 (1) (2004)


(До речі, спасибі за публікацію!) Просто для уточнення, мій коментар вище щодо посилання [5], справді стосувався іншого питання - це був відповідь на запитання LukStorms у головному розділі коментарів "Для будь-якого рядка N довжина P можливих символів, що максимум унікальних підрядків, які можуть містити такі рядки? "
גלעד ברקן

3

Ось рішення, але воно вибухає дуже швидко і не є поблизу ефективного рішення. Спочатку він розбиває рядок вниз на список унікальних підрядків, не турбуючись про впорядкування, потім намагається використовувати itertools.permutation, щоб зібрати ці підрядки назад у початковий рядок, тестуючи перестановку EACH, щоб побачити, чи відповідає вона вихідній рядку.

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

Я постарався постаратися з цією проблемою і продумав її з точки зору того, чи потрібно робити розділ за заданим індексом. Отже, ця функція є рекурсивною і створює 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 Ви можете, будь ласка, розробити, вибачте, я точно не розумію. Навіть якщо ми використовуємо backtrack, нам все одно доведеться 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)

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]або
(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 до поліноміальної.
Це лише верхня межа складності проблеми, оскільки скорочення поліноміального часу йде лише в одному напрямку (ми можемо звести цю проблему до проблеми МІС, але не навпаки, принаймні не тривіально). Отже, врешті-решт, ми вирішуємо цю проблему в O(1.1996^(n(n-1)/2))гіршому випадку.
Отже, на жаль, я не міг довести, що він знаходиться в P, або що він 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

На мою думку, це має бути найефективнішим способом вирішення цієї проблеми (використання цього моделювання як проблеми МІС), оскільки вирішувач 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команди: отримує вирішена швидко (0,02 сек на моєму ноутбуці), але , як і очікувалося, все стає (багато) складніше , так як розмір рядка зростає .... Ця програма дає тільки числове значення (а не оптимальний розділ), тим не менш, оптимальний розділ та відповідні підрядки можна знайти з аналогічною реалізацією, використовуючи інтерфейс LP Solver / python, такий як pyomo
glpsol --lp LP_file_1
aababaa

Час і пам'ять
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 також пропонує поточна нижня та верхня межі рішення, тому для останнього прикладу я міг отримати фактичне рішення у вигляді нижньої межі через хвилину.


Моделювання не є зменшенням чи доказом складності, хоча може бути корисним у впровадженні рішень. Я спочатку написав цю саму модель (MIS) в якості коментаря під основним відповіддю і пізніше її видалив. Маркус Шмід, один з небагатьох теоретиків, які авторських робіт писав на цю тему, вже надав детальну відповідь на цій веб-сторінці. Клас складності проблеми рішення залишається відкритим у літературі.
גלעד ברקן

У цьому випадку MIS є своєрідною тривіальною асоціацією, оскільки, звичайно, ми шукаємо велику групу речей, що "вільні" (крайові). Наприклад, з алфавітом з одним символом, відповідь - це розділ числа, для якого було б просте поліноміальне рішення часу. Можливо, є аспекти проблеми, які пропонують оптимізацію, яка могла б обійти LP на основі O (n ^ 2), отримавши додаткові дослідження, і була б пропущена, зупинившись у поданні MIS. Але це виглядає чудово для загального робочого рішення.
גלעד ברקן

Ви читали мою відповідь? Я пропоную тривіальне одностороннє скорочення полінома від MIS до цієї проблеми, не навпаки. Що стосується алфавіту з одним символом, проблема, очевидно, в P, з жадібним тривіальним рішенням.
m.raynal

Здавалося, ви зробили припущення про його клас складності на базі MIS.
גלעד ברקן

Тому прочитайте відповідь :-) Ви побачите, що це не так, я використовую лише складність MIS, щоб дати верхню межу складності проблеми. Не нижня межа.
м.райнал

0

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

У статті Збірка шаблонів із змінними: швидкі алгоритми та нові результати твердості (Геннінг Фернау, Флорін Манеа, Роберт Меркаш та Маркус Л. Шмід, 32-й симпозіум з теоретичних аспектів інформатики, STACS 2015, том 30 Лейбніца Міжнародні матеріали з інформатики (LIPIcs) , стор. 302–315, 2015), автори показують, що вирішувати , чи може бути поділене число факторів на певне число kта слово w, НП є повним чинником.wk

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

Schmid (2016), однак, пише, що "все ще залишається відкритою проблемою, чи MaxEFF-і залишаються NP-завершеними, якщо алфавіт закріплений". (Обчислення вільних рівностей і повторюваних струнних факторізацій. Теоретична комп’ютерна наука. Том 618 , 7 березня 2016, Сторінки 42-51)

Максимальний розмір факторизації без рівності (MaxEFF-ті) все ще параметризований і визначається як:

Екземпляр: Слово wі число m,1 ≤ m ≤ |w| .

Питання: Чи існує факторизація без рівності p wз s(p) ≥ m? ( s(p)будучи розміром факторизації.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.