Modifiqué el título para que sea más comprensible.
Aquí hay una versión detallada de la pregunta:
Tenemos una cadena s
y queremos dividirla en subcadenas . Cada subcadena es diferente entre sí. ¿Cuál es el número máximo de subcadenas únicas que podemos tener de un corte? En otras palabras, ¿cuál es el número máximo de subcadenas únicas que se concatenan para formar s
?
Aquí hay unos ejemplos:
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
Nota : s
solo contiene caracteres en minúscula. No se me dice cuánto tiempo s
y, por lo tanto, no puedo adivinar la complejidad óptima del tiempo. :(
¿Es un problema NP-difícil? Si no, ¿cómo puedo resolverlo de manera eficiente?
Escuché este problema de uno de mis amigos y no pude responderlo. Estoy tratando de usar un Trie + codicioso para resolver este problema. El método falla para el primer ejemplo.
Aquí está la solución Trie que se me ocurrió:
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
Por ejemplo 1, el código anterior devolverá 3 ya que está intentando dividirse s
en a|ab|abaa
.
Agregar: Gracias a la idea de todos, parece que este problema está muy cerca de un problema de NP. En este momento, estoy tratando de pensarlo desde esta dirección. Supongamos que tenemos una función Guess(n)
. Esta función volverá True
si pudiéramos encontrar n
subcadenas únicas de una división o de False
otra manera. Una observación aquí es que si Guess(n) == True
, entonces Guess(i) == True
para todos i <= n
. Ya que podemos fusionar dos subcadenas adyacentes juntas. Esta observación puede conducir a una solución binaria. Sin embargo, todavía requiere que podamos calcular la Guess
función de manera muy eficiente. Lamentablemente, todavía no pude encontrar una forma polinómica para calcular Guess(n)
.
aab|a|b|aa
que todavía es 4a
ob
?Respuestas:
Esto se conoce como el problema de partición de cuerdas con detección de colisión y se demuestra que se completa NP mediante una reducción de 3-SAT en un documento de Anne Condon, Ján Maňuch y Chris Thachuk - Complejidad de un problema de partición de cuerda con detección de colisión y su relación con el diseño del oligo para la síntesis génica ( International Computing and Combinatorics Conference , 265-275, 2008).
fuente
(Muchas gracias a Gilad Barkan (גלעד ברקן) por informarme sobre esta discusión).
Permítanme compartir mis pensamientos sobre este problema desde un punto de vista puramente teórico (tenga en cuenta que también uso "factor" en lugar de "subword").
Creo que una definición suficientemente formal del problema (o problemas) considerada aquí es la siguiente:
Dada una palabra w, encuentre las palabras u_1, u_2, ..., u_k de modo que
Variante de maximización (queremos muchos u_i): maximizar k
Variante de minimización (queremos corto u_i): minimizar max {| u_i | : 1 <= i <= k}
Estos problemas se convierten en problemas de decisión al dar además un límite B, que, de acuerdo con si estamos hablando de la variable "muchos factores" o de la variable "factores cortos", es un límite inferior en k (queremos al menos B factores), o un límite superior en max {| u_i | : 1 <= i <= k} (queremos factores de longitud como máximo B), respectivamente. Para hablar sobre la dureza NP, necesitamos hablar sobre problemas de decisión.
Usemos los términos SF para la variable "factores cortos" y MF para la variable "muchos factores". En particular, y este es un punto realmente crucial, los problemas se definen de tal manera que obtenemos una palabra sobre algún alfabeto que no está restringido de ninguna manera. La versión del problema es que sabemos a priori que solo recibimos palabras de entrada, por ejemplo, el alfabeto {a, b, c, d} es un problema diferente. La dureza NP no se transfiere automáticamente de la variante "sin restricciones" a la "alfabeto fijo" (esta última podría ser más simple).
Tanto SF como MF son problemas NP-completos. Esto se ha demostrado en [1, 1b] y [2], respectivamente (como Gilad ya ha señalado). Si entiendo la definición de problema informal (quizás también) aquí al comienzo de esta discusión correctamente, entonces el problema de esta discusión es exactamente el problema MF. Inicialmente no se menciona que las palabras están restringidas para provenir de un alfabeto fijo, luego se dice que podemos suponer que solo se usan letras minúsculas. Si esto significa que solo consideramos palabras sobre el alfabeto fijo {a, b, c, ..., z}, entonces esto realmente cambiaría mucho en términos de dureza NP.
Una mirada más cercana revela algunas diferencias en la complejidad de SF y MF:
Algunos comentarios sobre estos resultados: Wrt (1) y (2), es intuitivamente claro que si el alfabeto es binario, entonces, para dificultar el problema SF, el límite B no se puede arreglar también. Por el contrario, corregir B = 2 significa que el tamaño del alfabeto debe ser bastante grande para producir instancias difíciles. Como consecuencia, (3) es bastante trivial (de hecho, [3] dice un poco más: luego podemos resolverlo en tiempo de ejecución no solo polinomial, sino también | w | ^ 2 veces un factor que solo depende del tamaño del alfabeto y obligado B). (5) tampoco es difícil: si nuestra palabra es larga en comparación con B, entonces podemos obtener la factorización deseada simplemente dividiéndonos en factores de diferentes longitudes. Si no es así, entonces podemos aplicar la fuerza bruta a todas las posibilidades, que es exponencial solo en B, que en este caso se supone que es una constante.
Entonces, la imagen que tenemos es la siguiente: SF parece más difícil, porque tenemos dureza incluso para alfabetos fijos o para un límite fijo B. El problema MF, por otro lado, se resuelve en el tiempo polivinílico si el límite es fijo (en esto es más fácil que SF), mientras que la pregunta correspondiente es el tamaño del alfabeto abierto. Por lo tanto, MF es un poco menos complejo que SF, incluso si resulta que MF para alfabetos fijos también es NP completo. Sin embargo, si se puede demostrar que MF se puede resolver para alfabetos fijos en tiempo múltiple, entonces se muestra que MF es mucho más fácil que SF ... porque el único caso para el que es difícil es algo artificial (¡alfabeto sin límites!) .
Hice un esfuerzo para tratar de resolver el caso de MF con alfabeto limitado, pero no pude resolverlo y desde entonces dejé de trabajar en él. No creo que otros investigadores hayan intentado mucho resolverlo (por lo que este no es uno de estos problemas abiertos muy difíciles, muchas personas ya lo han intentado y han fallado; lo considero factible de alguna manera). Supongo que también es NP-hard para alfabetos fijos, pero tal vez la reducción es tan complicada que obtendrías algo como "MF es difícil para alfabetos de tamaño 35 o mayor" o algo así, que tampoco sería súper agradable .
Con respecto a la literatura adicional, conozco el artículo [4], que considera el problema de dividir una palabra w en factores distintos u_1, u_2, ..., u_k que son todos palíndromos, que también es NP-completo.
Eché un vistazo rápido al papel [5], señalado por Gilad. Sin embargo, parece considerar una configuración diferente. En este artículo, los autores están interesados en la pregunta combinatoria de cuántas subsecuencias o subpalabras distintas pueden estar contenidas en una palabra determinada, pero estas pueden superponerse. Por ejemplo, aaabaab contiene 20 subpalabras diferentes a, b, aa, ab, ba, bb, aaa, aab, aba, baa, aaab, aaba, abaa, baab, aaaba, aabaa, abaab, aabaab, aaabaa, aaabaab (tal vez yo mal contado, pero entiendes la idea). Algunos de ellos tienen solo una ocurrencia, como baa, algunos de ellos varios, como aa. En cualquier caso, la pregunta no es cómo podemos dividir la palabra de alguna manera para obtener muchos factores distintos, ya que esto significa que cada símbolo individual contribuye exactamente a un factor.
Con respecto a las soluciones prácticas para este tipo de problemas (tenga en cuenta que soy un teórico, así que tómelo con gran detalle):
Que yo sepa, no hay límites inferiores teóricos (como la dureza NP) que descartarían resolver MF en tiempo polinómico si consideramos solo palabras de entrada sobre un alfabeto fijo. Sin embargo, hay una advertencia: si obtienes un algoritmo de poli-tiempo, ¡esto debería ejecutarse exponencialmente en el número de símbolos del alfabeto fijo (o exponencial en alguna función de eso)! De lo contrario, también sería un algoritmo de tiempo polinómico para el caso de alfabetos no acotados. Entonces, como teórico, estaría buscando tareas algorítmicas que se puedan calcular en tiempo exponencial solo si el número de símbolos y que de alguna manera ayudan a diseñar un algoritmo para MF. Por otro lado, es probable que dicho algoritmo no exista y MF también sea NP-hard en el caso del alfabeto fijo.
Si está interesado en soluciones prácticas, puede ser útil aproximar la solución. Por lo tanto, obtener la factorización que se garantiza que sea solo la mitad del óptimo en el peor de los casos no sería tan malo.
Supongo que las heurísticas que no ofrecen una relación de aproximación demostrable, pero funcionan bien en un entorno práctico también serían interesantes.
Transformar las instancias problemáticas en instancias SAT o ILP no debería ser demasiado difícil y luego podría ejecutar un SAT o ILP-Solver para incluso obtener soluciones óptimas.
Mi opinión personal es que, aunque no se sabe si el caso del alfabeto fijo de MF es NP-hard, hay suficientes conocimientos teóricos que sugieren que el problema es lo suficientemente difícil como para justificar la búsqueda de soluciones heurísticas, etc. funcionan bien en un entorno práctico.
Bibliografía:
[1] Anne Condon, Ján Manuch, Chris Thachuk: La complejidad de la partición de cuerdas. J. Algoritmos discretos 32: 24-43 (2015)
[1b] Anne Condon, Ján Manuch, Chris Thachuk: Complejidad de un problema de partición de cuerdas consciente de colisión y su relación con el diseño de Oligo para la síntesis génica. COCOON 2008: 265-275
[2] Henning Fernau, Florin Manea, Robert Mercas, Markus L. Schmid: coincidencia de patrones con variables: algoritmos rápidos y nuevos resultados de dureza. STACS 2015: 302-315
[3] Markus L. Schmid: Computación de factorizaciones de cuerdas repetitivas y sin igualdad. Theor Comput Sci. 618: 42-51 (2016)
[4] Hideo Bannai, Travis Gagie, Shunsuke Inenaga, Juha Kärkkäinen, Dominik Kempa, Marcin Piatkowski, Shiho Sugimoto: la factorización palindrómica diversa es NP-completa. En t. J. encontrado. Comput Sci. 29 (2): 143-164 (2018)
[5] Abraham Flaxman, Aram Wettroth Harrow, Gregory B. Sorkin: Cuerdas con muchas subsecuencias y subcadenas distintas. Electr. J. Comb. 11 (1) (2004)
fuente
Aquí hay una solución, pero explota muy rápido y no está cerca de una solución eficiente. Primero divide la cadena en una lista de subcadenas únicas sin preocuparse por ordenar, luego intenta usar itertools.permutation para volver a ensamblar esas subcadenas en la cadena original, probando CADA permutación para ver si coincide con la cadena original.
Para la primera prueba obtenemos esto:
Quizás esto se pueda optimizar de alguna manera, pero eso lleva unos segundos en esta máquina.
fuente
He probado este problema y lo he pensado en términos o si se debe hacer una partición en un índice determinado. Entonces, esta función es recursiva y crea 2 ramas en cada índice 1. No particione en el índice i 2. Partición en el índice i.
Basado en la partición, completo un conjunto y luego devuelvo el tamaño del conjunto
https://onlinegdb.com/HJynWw-iH
fuente
keep
función ya que laset.copy()
función consume mucho tiempo. ¿Qué hay de usar el backtracking que es cuando finaliza esta pila de funciones, elimina el candidato actual del conjunto?merge
separar los conjuntos ya que siempre estamos bifurcando. Por lo tanto, ya sea fusionando o copiando. ¿Puedes elaborar?Puede utilizar una función recursiva con un conjunto como segundo parámetro para realizar un seguimiento de las cadenas únicas en la ruta actual hasta el momento. Para cada recursión, repita todos los índices más 1 para dividir la cadena para una posible cadena candidata, y si la cadena candidata aún no está en el conjunto, realice una llamada recursiva con la cadena restante y el candidato agregado al conjunto Para obtener el número máximo de subcadenas únicas de la cadena restante, agregue 1 y devuelva el máximo de los máximos de las iteraciones. Devuelve 0 si la cadena dada está vacía o si todas las cadenas candidatas ya están en el conjunto:
Demostración: https://repl.it/@blhsing/PriceyScalySphere
En Python 3.8, la lógica anterior también se puede escribir con una llamada a la
max
función con una expresión generadora que filtra los candidatos que se han "visto" con una expresión de asignación:fuente
Aquí hay una respuesta basada en la teoría de grafos.
Modelado
Este problema se puede modelar como un problema de conjunto independiente máximo en un gráfico de tamaño de la
O(n²)
siguiente manera:Sea
w = c_1, ..., c_n
la cadena de entrada.Vamos a
G = (V,E)
ser un grafo no dirigido, construido de la siguiente manera:V = { (a, b) such that a,b in [1, n], a <= b }
. Podemos ver que el tamaño deV
esn(n-1)/2
, donde cada vértice representa una subcadena dew
.Luego, por cada par de vértices
(a1, b1)
y(a2, b2)
, construimos el borde((a1, b1), (a2, b2))
sif (i) se
[a1, b1]
cruza[a2, b2]
o(ii)
c_a1...c_b1 = c_a2...c_b2
.Dicho de otro modo, construimos un borde entre dos vértices si (i) las subcadenas en las que representan se superponen
w
o (ii) las dos subcadenas son iguales.Entonces podemos ver por qué un máximo conjunto independiente de
G
proporciona la respuesta a nuestro problema.Complejidad
En el caso general, el problema del conjunto independiente máximo (MIS) es NP-duro, con una complejidad temporal
O(1.1996^n)
y en el espacio polinomial [Xiao, NamaGoshi (2017)] .Al principio pensé que el gráfico resultante sería un gráfico cordal (sin ciclo inducido de longitud> 3), lo que habría sido muy bueno desde entonces, el problema MIS se puede resolver en tiempo lineal en esta clase de gráficos.
Pero rápidamente me di cuenta de que no es el caso, es bastante fácil encontrar ejemplos donde hay ciclos inducidos de longitud 5 y más.
En realidad, el gráfico resultante no exhibe ninguna propiedad 'agradable' que generalmente buscamos y que permite reducir la complejidad del problema MIS a uno polinómico.
Esto es solo un límite superior en la complejidad del problema, ya que la reducción del tiempo polinomial va solo en una dirección (podemos reducir este problema al problema MIS, pero no al revés, al menos no trivialmente). Así que finalmente terminamos resolviendo este problema
O(1.1996^(n(n-1)/2))
en el peor de los casos.Entonces, por desgracia, no pude demostrar que está en P, o que es NP completo o NP-duro. Una cosa segura es que el problema está en NP, pero supongo que esto no es una sorpresa para nadie.
Implementación
La ventaja de reducir este problema al problema MIS es que el MIS es un problema clásico, para el cual se pueden encontrar varias implementaciones, y que el problema MIS también se escribe fácilmente como un ILP.
Aquí hay una formulación ILP del problema MIS:
En mi opinión, esa debería ser la forma más eficiente de resolver este problema (usando este modelado como un problema MIS), ya que el solucionador de ILP es increíblemente eficiente, especialmente cuando se trata de grandes instancias.
Esta es una implementación que hice usando Python3 y el solucionador GLPK . Para probarlo, necesita un solucionador de LP compatible con el formato de archivo Cplex.
A continuación, puede solucionarlo con la
glpsol
orden:glpsol --lp LP_file_1
El
aababaa
se resolvió rápidamente (0,02 seg en mi portátil), pero como era de esperar, las cosas se ponen (mucho) más dura como el tamaño de la cadena crece ....Este programa sólo da el valor numérico (y no la partición óptima), sin embargo, la partición óptima y las subcadenas correspondientes se pueden encontrar con una implementación similar, utilizando una interfaz LP solver / python como pyomo
Tiempo y memoria
aababaa
: 0.02 segundos, 0.4 MB, valor: 4kzshidfiouzh
: 1.4 segundos, 3.8 MB, valor: 10aababababbababab
: 60.2 segundos, 31.5 MB, valor: 8kzshidfiouzhsdjfyu
: 207.5 segundos, 55.7 MB, valor: 14Tenga en cuenta que el solucionador de LP también ofrece los límites inferior y superior actuales en la solución, por lo que para el último ejemplo, podría obtener la solución real como límite inferior después de un minuto.
fuente
Mi otra respuesta estaba estrechamente relacionada, pero no correspondía exactamente a este problema, dejando ambiguo si encontrar la factorización de cuerdas libre de igualdad más grande podría ser de una clase de complejidad diferente a si existe alguna factorización libre de igualdad con longitud de factor enlazado (este último siendo abordado por el documento citado).
En el documento, Coincidencia de patrones con variables: Algoritmos rápidos y nuevos resultados de dureza (Henning Fernau, Florin Manea, Robert Mercaş y Markus L. Schmid, en Proc. 32º Simposio sobre aspectos teóricos de la informática, STACS 2015, volumen 30 de Leibniz International Proceedings in Informatics (LIPIcs) , páginas 302–315, 2015), los autores muestran que es NP completo para decidir, para un número dado
k
y una palabraw
, siw
se puede factorizar enk
factores distintos.Si consideramos el comentario de templatetypedef , lo que implica que podría haber una solución de tiempo polinomial para la factorización libre de igualdad más grande y sin restricciones, entonces seguramente podríamos usar dicho algoritmo para responder si pudiéramos dividir la cadena en
k
factores distintos (subcadenas) simplemente observando sik
es menos del máximo que ya conocemos.Schmid (2016), sin embargo, escribe que "todavía es un problema abierto si MaxEFF-s permanece NP-completo si el alfabeto es fijo". (Cálculo de factorizaciones de cuerdas repetitivas y sin igualdad, Theoretical Computer Science Volume 618 , 7 de marzo de 2016, páginas 42-51)
Sin embargo, el tamaño máximo de factorización libre de igualdad (MaxEFF-s) todavía está parametrizado y se define como:
Instancia: Una palabra
w
y un númerom
,1 ≤ m ≤ |w|
.Pregunta: ¿Existe una factorización libre de igualdad p de
w
cons(p) ≥ m
? (s(p)
siendo el tamaño de la factorización).fuente