Zmodyfikowałem tytuł, aby był bardziej zrozumiały.
Oto szczegółowa wersja pytania:
Mamy ciąg s
i chcemy go podzielić na podciągi . Każdy podciąg różni się od siebie. Jaka jest maksymalna liczba unikalnych podciągów, które możemy mieć z jednego cięcia. Innymi słowy, jaka jest maksymalna liczba unikalnych podciągów, które łączą się tworząc s
.
Oto kilka przykładów:
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
Uwaga : s
zawiera tylko małe litery. Nie powiedziano mi, jak długo s
i dlatego nie mogę odgadnąć optymalnej złożoności czasu. :(
Czy to trudny NP? Jeśli nie, jak mogę go rozwiązać skutecznie?
Słyszałem ten problem od jednego z moich przyjaciół i nie mogłem na nie odpowiedzieć. Próbuję użyć chciwości Trie +, aby rozwiązać ten problem. Metoda zawodzi w pierwszym przykładzie.
Oto rozwiązanie Trie, które wymyśliłem:
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
Na przykład 1, powyższy kod powróci 3, ponieważ stara się rozstali s
się a|ab|abaa
.
Dodaj: Dzięki pomysłowi wszystkich wygląda na to, że ten problem jest bardzo zbliżony do problemu NP. W tej chwili staram się myśleć w tym kierunku. Załóżmy, że mamy funkcję Guess(n)
. Ta funkcja zwróci się, True
jeśli będziemy mogli znaleźć n
unikalne podciągi z jednego podziału lub w False
inny sposób. Jedną z obserwacji jest to, że jeśli Guess(n) == True
, to Guess(i) == True
dla wszystkich i <= n
. Ponieważ możemy scalić dwa sąsiednie podciągi razem. Ta obserwacja może prowadzić do rozwiązania binarnego. Nadal jednak wymaga to Guess
bardzo wydajnego obliczenia tej funkcji. Niestety nadal nie mogłem znaleźć wielomianowego sposobu obliczania Guess(n)
.
aab|a|b|aa
jest to nadal 4a
lubb
?Odpowiedzi:
Jest to znane jako problem podziału struny rozpoznający kolizję, a wykazano, że jest on NP-zupełny dzięki redukcji z 3-SAT w pracy Anne Condon, Ján Maňuch i Chris Thachuk - Złożoność problemu podziału struny świadomego kolizji i jej związek z projektem oligo do syntezy genów ( International Computing and Combinatorics Conference , 265-275, 2008).
źródło
(Wielkie podziękowania dla Gilada Barkana (גלעד ברקן) za poinformowanie mnie o tej dyskusji.)
Pozwólcie, że podzielę się przemyśleniami na temat tego problemu z czysto teoretycznego punktu widzenia (zauważ, że używam również „czynnik” zamiast „podsłówka”).
Uważam, że rozważana tutaj wystarczająco formalna definicja problemu (lub problemów) jest następująca:
Biorąc pod uwagę słowo w, znajdź słowa u_1, u_2, ..., u_k takie, że
Wariant maksymalizacji (chcemy wielu u_i): maksymalizuj k
Wariant minimalizacji (chcemy krótkiego u_i): minimalizuj max {| u_i | : 1 <= i <= k}
Problemy te stają się problemami decyzyjnymi poprzez dodatkowe ograniczenie B, które zgodnie z tym, czy mówimy o wariancie „wielu czynników”, czy wariancie „czynników krótkich”, jest dolną granicą k (chcemy co najmniej B Czynniki) lub górna granica maks. {| u_i | : 1 <= i <= k} (chcemy odpowiednio współczynników długości co najwyżej B). Aby mówić o twardości NP, musimy mówić o problemach decyzyjnych.
Użyjmy wyrażeń SF dla wariantu „krótkich czynników” i MF dla wariantu „wielu czynników”. W szczególności, i to jest naprawdę kluczowa kwestia, problemy są zdefiniowane w taki sposób, że uzyskujemy słowo nad jakimś alfabetem, które nie jest w żaden sposób ograniczone. Wersja problemowa, w której wiemy z góry, że otrzymujemy tylko słowa wejściowe, powiedzmy, że alfabet {a, b, c, d} to inny problem! Twardość NP nie przenosi się automatycznie z „nieograniczonego” na wariant „ustalonego alfabetu” (ten drugi może być prostszy).
Zarówno SF, jak i MF są problemami NP-zupełnymi. Pokazano to odpowiednio w [1, 1b] i [2] (jak już wskazał Gilad). Jeśli dobrze rozumiem (być może też) nieformalną definicję problemu tutaj na początku tej dyskusji, to problemem tej dyskusji jest właśnie problem MF. Początkowo nie wspomniano, że wyrazy są ograniczone do jakiegoś stałego alfabetu, później mówi się, że możemy założyć, że używane są tylko małe litery. Jeśli to oznacza, że bierzemy pod uwagę tylko słowa nad ustalonym alfabetem {a, b, c, ..., z}, to zmieniłoby się bardzo dużo pod względem twardości NP.
Bliższe spojrzenie ujawnia pewne różnice w złożoności SF i MF:
Kilka komentarzy na temat tych wyników: Wrt (1) i (2), intuicyjnie jest jasne, że jeśli alfabet jest binarny, to w celu utrudnienia SF problem związany z B również nie może zostać naprawiony. I odwrotnie, ustalenie B = 2 oznacza, że rozmiar alfabetu musi być dość duży, aby stworzyć trudne przypadki. W konsekwencji (3) jest dość trywialny (w rzeczywistości [3] mówi nieco więcej: możemy go rozwiązać w czasie wykonywania nie tylko wielomianu, ale także | w | ^ 2 razy czynnik, który zależy tylko od wielkości alfabetu i związany B). (5) również nie jest trudne: jeśli nasze słowo jest długie w porównaniu do B, możemy uzyskać pożądaną faktoryzację, po prostu dzieląc na czynniki o różnych długościach. Jeśli nie, to możemy zastosować brutalną siłę wszystkich możliwości, która jest wykładnicza tylko w B, który w tym przypadku przyjmuje się za stały.
Obraz, który mamy, jest następujący: SF wydaje się trudniejszy, ponieważ mamy twardość nawet dla ustalonych alfabetów lub dla ustalonego wiązania B. Z drugiej strony problem MF staje się rozwiązywalny w czasie wielokrotnym, jeśli granica jest ustalona (w pod tym względem jest łatwiej niż SF), podczas gdy odpowiadające pytanie o rozmiar alfabetu jest otwarte. Zatem MF jest nieco mniej skomplikowane niż SF, nawet jeśli okaże się, że MF dla stałych alfabetów jest również NP-zupełny. Jeśli jednak można wykazać, że MF można rozwiązać dla stałych alfabetów w czasie wielozadaniowym, wówczas MF jest znacznie łatwiejsze niż SF ... ponieważ jeden przypadek, dla którego jest trudny, jest nieco sztuczny (nieograniczony alfabet!) .
Włożyłem trochę wysiłku w rozwiązanie problemu MF z ograniczonym alfabetem, ale nie byłem w stanie go rozwiązać i od tego czasu przestałem nad nim pracować. Nie wierzę, że inni badacze bardzo starali się go rozwiązać (więc nie jest to jeden z tych bardzo trudnych, otwartych problemów, wiele osób już próbowało i poniosło porażkę; uważam, że jest to jakoś wykonalne). Domyślam się, że jest to również trudne dla NP dla stałych alfabetów, ale może redukcja jest tak skomplikowana, że można uzyskać coś takiego jak „MF jest trudny dla alfabetów o rozmiarze 35 lub większym” lub coś, co nie byłoby super miłe .
Jeśli chodzi o dalszą literaturę, znam pracę [4], która rozważa problem podziału słowa w na odrębne czynniki u_1, u_2, ..., u_k, które wszystkie są palindromami, co również jest NP-zupełne.
Rzuciłem okiem na papier [5], na co zwrócił uwagę Gilad. Wydaje się jednak, że rozważa inne ustawienie. W tym artykule autorzy są zainteresowani kombinatoryjnym pytaniem, ile różnych podsekwencji lub pod słów może zawierać jedno słowo, ale mogą się one nakładać. Na przykład aaabaab zawiera 20 różnych podtytułów a, b, aa, ab, ba, bb, aaa, aab, aba, baa, aaab, aaba, abaa, baab, aaaba, aabaa, abaab, aabaab, aaabaa, aaabaab (może ja przeliczyłem, ale masz pomysł). Niektóre z nich mają tylko jedno wystąpienie, jak baa, inne kilka, jak aa. W każdym razie nie chodzi o to, w jaki sposób możemy jakoś podzielić słowo, aby uzyskać wiele różnych czynników, ponieważ oznacza to, że każdy pojedynczy symbol przyczynia się do dokładnie jednego czynnika.
Jeśli chodzi o praktyczne rozwiązania tego rodzaju problemów (pamiętaj, że jestem teoretykiem, więc weź to z odrobiną soli):
Według mojej wiedzy, nie ma teoretycznych dolnych granic (takich jak twardość NP), które wykluczałyby rozwiązanie MF w czasie wielomianowym, jeśli weźmiemy pod uwagę tylko słowa wpisane na ustalonym alfabecie. Jest jednak jedno zastrzeżenie: jeśli otrzymasz algorytm wielogodzinny, powinien on działać wykładniczo w liczbie symboli ze stałego alfabetu (lub wykładniczo w niektórych funkcjach tego)! W przeciwnym razie byłby to również algorytm wielomianowy w przypadku nieograniczonych alfabetów. Będąc teoretykiem, szukałbym zadań algorytmicznych, które można by obliczyć w czasie wykładniczym, tylko jeśli liczba symboli i które w jakiś sposób pomagają w opracowaniu algorytmu dla MF. Z drugiej strony jest prawdopodobne, że taki algorytm nie istnieje, a MF jest również NP-twardy w przypadku stałego alfabetu.
Jeśli interesują Cię praktyczne rozwiązania, pomocne może być przybliżenie rozwiązania. Tak więc uzyskanie faktoryzacji, które są gwarantowane tylko w połowie tak duże, jak optymalne w najgorszym przypadku, nie byłoby takie złe.
Interesujące wydaje się również heurystyka, która nie daje możliwego do udowodnienia współczynnika przybliżenia, ale działa dobrze w praktycznym otoczeniu.
Przekształcanie instancji problemowych w instancje SAT lub ILP nie powinno być zbyt trudne, a następnie możesz uruchomić SAT lub ILP-Solver, aby uzyskać nawet optymalne rozwiązania.
Moim osobistym zdaniem jest to, że chociaż nie wiadomo, czy przypadek MF z ustalonym alfabetem jest trudny do NP, istnieje wystarczająco dużo teoretycznych spostrzeżeń, które sugerują, że problem jest na tyle trudny, że uzasadnione jest poszukiwanie rozwiązań heurystycznych itp., Które działają dobrze w praktycznych warunkach.
Bibliografia:
[1] Anne Condon, Ján Manuch, Chris Thachuk: Złożoność partycjonowania łańcucha. J. Discrete Al Algorytmy 32: 24-43 (2015)
[1b] Anne Condon, Ján Manuch, Chris Thachuk: Złożoność świadomego kolizji problemu rozdziału struny i jego związek z projektem Oligo do syntezy genów. COCOON 2008: 265–275
[2] Henning Fernau, Florin Manea, Robert Mercas, Markus L. Schmid: Dopasowywanie wzorców ze zmiennymi: szybkie algorytmy i nowe wyniki twardości. STACS 2015: 302–315
[3] Markus L. Schmid: Obliczanie wolnych od równości i powtarzalnych faktoryzacji ciągów. Teoria Comput. Sci. 618: 42–51 (2016)
[4] Hideo Bannai, Travis Gagie, Shunsuke Inenaga, Juha Kärkkäinen, Dominik Kempa, Marcin Piatkowski, Shiho Sugimoto: Zróżnicowane faktowanie palindromiczne jest zakończone NP. Int. J. Znaleziono. Comput. Sci. 29 (2): 143–164 (2018)
[5] Abraham Flaxman, Aram Wettroth Harrow, Gregory B. Sorkin: Struny z maksymalnie wieloma odrębnymi podsekwencjami i podciągami. Electr. J. Comb. 11 (1) (2004)
źródło
Oto rozwiązanie, ale wybuchnie naprawdę szybko i nie jest blisko wydajnego rozwiązania. Najpierw rozkłada ciąg na listę unikatowych podciągów bez obawy o kolejność, a następnie próbuje użyć itertools.permutation, aby ponownie złożyć te podciągi z powrotem w oryginalny ciąg, testując KAŻDĄ permutację, aby sprawdzić, czy pasuje do oryginalnego ciągu.
Do pierwszego testu otrzymujemy to:
Być może można to jakoś zoptymalizować, ale na tym komputerze zajmuje to kilka sekund.
źródło
Podjąłem ten problem i zastanowiłem się nad nim w kategoriach lub czy utworzyć partycję pod danym indeksem. Ta funkcja jest rekurencyjna i tworzy 2 gałęzie przy każdym indeksie 1. Nie dziel na indeks i. 2. Podziel na indeks i.
Na podstawie partycji wypełniam zestaw, a następnie zwracam rozmiar zestawu
https://onlinegdb.com/HJynWw-iH
źródło
keep
funkcję, ponieważset.copy()
jest ona bardzo czasochłonna. Co powiesz na użycie śledzenia wstecznego, które jest po zakończeniu tego stosu funkcji, usunięcie bieżącego kandydata z zestawu?merge
rozdzielać zestawy, ponieważ zawsze rozgałęziamy się. Stąd łączenie lub kopiowanie. Czy potrafisz opracować?Możesz użyć funkcji rekurencyjnej z zestawem jako drugim parametrem, aby śledzić unikalne ciągi w bieżącej ścieżce do tej pory. Dla każdej rekurencji, iteruj przez wszystkie indeksy plus 1, przy których można podzielić ciąg dla możliwego ciągu kandydującego, a jeśli ciąg kandydujący nie znajduje się jeszcze w zestawie, wykonaj wywołanie rekurencyjne z pozostałym ciągiem i kandydatem dodanym do zestawu aby uzyskać maksymalną liczbę unikalnych podciągów z pozostałego ciągu, dodaj 1 do niego i zwróć maksimum maksimów z iteracji. Zwraca 0, jeśli podany ciąg jest pusty lub wszystkie ciągi kandydujące są już w zestawie:
Demo: https://repl.it/@blhsing/PriceyScalySphere
W Pythonie 3.8 powyższą logikę można również zapisać za pomocą wywołania
max
funkcji z wyrażeniem generatora, które filtruje kandydatów, którzy zostali „widziani” za pomocą wyrażenia przypisania:źródło
Oto odpowiedź oparta na teorii grafów.
Modelowanie
Ten problem można modelować jako maksymalny niezależny problem z zestawem na wykresie wielkości
O(n²)
w następujący sposób:Niech
w = c_1, ..., c_n
będzie łańcuchem wejściowym.Pozwolić
G = (V,E)
być nieukierunkowane wykres, zbudowany w następujący sposób:V = { (a, b) such that a,b in [1, n], a <= b }
. Widzimy, że rozmiarV
ton(n-1)/2
, gdzie każdy wierzchołek reprezentuje podłańcuchw
.Następnie dla każdej pary wierzchołków
(a1, b1)
i(a2, b2)
budujemy krawędzi((a1, b1), (a2, b2))
IFF(I)
[a1, b1]
przecina[a2, b2]
lub(ii)
c_a1...c_b1 = c_a2...c_b2
.Mówiąc inaczej, budujemy krawędź między dwoma wierzchołkami, jeśli (i) reprezentowane przez nie podciągi nachodzą na siebie
w
lub (ii) dwa podciągi są równe.Możemy wtedy zobaczyć, dlaczego maksymalna niezależny zestaw z
G
zapewnia odpowiedź na nasz problem.Złożoność
W ogólnym przypadku problem maksymalnego zestawu niezależnego (MIS) jest trudny do NP, ze złożonością czasową
O(1.1996^n)
w przestrzeni wielomianowej [Xiao, NamaGoshi (2017)] .Na początku myślałem, że otrzymany wykres będzie grafem akordowym (bez indukowanego cyklu długości> 3), co byłoby bardzo miłe, ponieważ problem MIS można rozwiązać w czasie liniowym na tej klasie grafów.
Ale szybko zdałem sobie sprawę, że tak nie jest, dość łatwo jest znaleźć przykłady, w których indukowane są cykle o długości 5 i więcej.
W rzeczywistości powstały wykres nie wykazuje żadnej „ładnej” właściwości, której zwykle szukamy i która pozwala zredukować złożoność problemu MIS do wielomianu.
Jest to tylko górna granica złożoności problemu, ponieważ wielomianowe skrócenie czasu idzie tylko w jednym kierunku (możemy zredukować ten problem do problemu MIS, ale nie na odwrót, przynajmniej nie trywialnie). Ostatecznie rozwiązujemy ten problem w
O(1.1996^(n(n-1)/2))
najgorszym przypadku.Tak więc, niestety, nie mogłem udowodnić, że jest w P lub że jest NP-kompletny lub NP-twardy. Pewne jest to, że problem dotyczy NP, ale chyba nikogo to nie zaskoczy.
Implementacja
Zaletą zmniejszenia tego problemu do problemu MIS jest to, że MIS jest klasycznym problemem, dla którego można znaleźć kilka implementacji, a problem MIS można łatwo napisać jako ILP.
Oto sformułowanie ILP problemu MIS:
Moim zdaniem powinien to być najskuteczniejszy sposób rozwiązania tego problemu (wykorzystanie tego modelowania jako problemu MIS), ponieważ solver ILP jest niezwykle wydajny, szczególnie w przypadku dużych instancji.
Jest to implementacja, którą zrobiłem używając Python3 i solvera GLPK . Aby to przetestować, potrzebujesz solwera LP zgodnego z formatem pliku Cplex.
Następnie możesz je rozwiązać za pomocą
glpsol
polecenia:glpsol --lp LP_file_1
Rozwiązanie
aababaa
jest rozwiązywane szybko (0,02 s na moim laptopie), ale zgodnie z oczekiwaniami, sprawy stają się (znacznie) trudniejsze wraz ze wzrostem rozmiaru łańcucha ....Ten program podaje tylko wartość liczbową (a nie optymalna partycja), jednak optymalną partycję i odpowiadające jej podciągi można znaleźć w podobnej implementacji, używając interfejsu solver LP / python, takiego jak pyomo
Czas i pamięć
aababaa
: 0,02 sekundy, 0,4 MB, wartość: 4kzshidfiouzh
: 1,4 sekundy, 3,8 MB, wartość: 10aababababbababab
: 60,2 sekundy, 31,5 MB, wartość: 8kzshidfiouzhsdjfyu
: 207,5 sekundy, 55,7 MB, wartość: 14Należy pamiętać, że solver LP oferuje również bieżące dolne i górne granice rozwiązania, więc w ostatnim przykładzie mogę uzyskać rzeczywiste rozwiązanie jako dolną granicę po minucie.
źródło
Moja inna odpowiedź była ściśle powiązana, ale nie odpowiadała dokładnie temu problemowi, pozostawiając niejednoznaczne, czy znalezienie największego wolnego od równości faktoryzacji ciągów może mieć inną klasę złożoności niż to, czy istnieje jakikolwiek wolny od równości faktoryzacja ze związaną długością czynnika (ta ostatnia skierowane przez cytowany artykuł).
W artykule Dopasowywanie wzorców ze zmiennymi: szybkie algorytmy i nowe wyniki twardości (Henning Fernau, Florin Manea, Robert Mercaş i Markus L. Schmid, w Proc. 32. sympozjum na temat teoretycznych aspektów informatyki, STACS 2015, tom 30 Leibniz International Proceedings in Informatics (LIPIcs) , strony 302–315, 2015), autorzy pokazują, że NP jest kompletne w podejmowaniu decyzji, dla danej liczby
k
i słowaw
, czyw
można je rozdzielić nak
odrębne czynniki.Jeśli weźmiemy pod uwagę templatetypedef za komentarz , co oznacza, że może być wielomianem rozwiązanie czas nieograniczony, największej równości wolne Faktoryzacji to z pewnością możemy użyć takiego algorytmu, aby odpowiedzieć, czy możemy podzielić ciąg znaków w
k
różnych czynników (podciągi), po prostu obserwując, czyk
jest mniej niż maksimum, które już znamy.Schmid (2016) pisze jednak, że „nadal jest otwartym problemem, czy MaxEFF-s pozostaje NP-kompletny, jeśli alfabet jest poprawiony”. (Obliczanie wolnych od równości i powtarzalnych faktoryzacji łańcuchów, Theoretical Computer Science Tom 618 , 7 marca 2016, strony 42-51)
Maksymalny rozmiar faktoryzacji wolnej od równości (MaxEFF-s) jest jednak nadal parametryzowany i definiowany jako:
Instancja: Słowo
w
i numerm
,1 ≤ m ≤ |w|
.Pytanie: Czy istnieje faktoryzacja bez równości p
w
zs(p) ≥ m
? (s(p)
jest wielkością faktoryzacji).źródło