Para un entero positivo dado n
, considere todas las cadenas binarias de longitud 2n-1
. Para una cadena dada S
, dejemos L
ser una matriz de longitud n
que contiene el recuento del número de 1
s en cada subcadena de longitudn
de S
. Por ejemplo, si n=3
y S = 01010
entonces L=[1,2,1]
. Llamamos a L
la matriz de conteo de S
.
Decimos que dos cuerdas S1
y S2
de la misma longitud coinciden si sus respectivas matrices de conteoL1
y L2
tienen la propiedad eso L1[i] <= 2*L2[i]
y L2[i] <= 2*L1[i]
para todos i
.
Tarea
Para aumentar a n
partir de n=1
, la tarea es encontrar el tamaño del conjunto de cadenas más grande, cada uno de longitud 2n-1
para que no coincidan dos cadenas.
Su código debe generar un número por valor de n
.
Puntuación
Su puntaje es el más alto n
para el que nadie más ha publicado una respuesta correcta más alta para ninguna de sus respuestas. Claramente, si tiene todas las respuestas óptimas, obtendrá la puntuación más alta n
que publique. Sin embargo, incluso si su respuesta no es la óptima, aún puede obtener el puntaje si nadie más puede superarlo.
Ejemplos de respuestas
Por lo n=1,2,3,4
que entiendo 2,4,10,16
.
Idiomas y bibliotecas
Puede usar cualquier idioma y bibliotecas disponibles que desee. Siempre que sea posible, sería bueno poder ejecutar su código, por lo tanto, si es posible, incluya una explicación completa sobre cómo ejecutar / compilar su código en Linux.
Entradas principales
- 5 por Martin Büttner en Mathematica
- 6 por Reto Koradi en C ++ . Los valores son
2, 4, 10, 16, 31, 47, 75, 111, 164, 232, 328, 445, 606, 814, 1086
. Se sabe que los primeros 5 son óptimos. - 7 de Peter Taylor en Java . Los valores son
2, 4, 10, 16, 31, 47, 76, 111, 166, 235
. - 9 por joriki en Java . Los valores son
2, 4, 10, 16, 31, 47, 76, 112, 168
.
L1[i]/2 <= L2[i] <= 2*L1[i]
.match(A, B)
ymatch(B, C)
no implicamatch(A, C)
(lo mismo para el inverso). Ejemplo: [1] y [2] coinciden, [2] y [3] coinciden, pero [1] y [3] no. Del mismo modo, [1,3] y [3,1] no coinciden, [3, 1] y [2, 3] no coinciden, pero [1, 3] y [2, 3] coinciden.Respuestas:
2, 4, 10, 16, 31, 47, 76, 112, 168
Para cada n, este código de Java determina las posibles matrices de conteo y luego encuentra conjuntos no coincidentes de tamaño creciente, para cada tamaño que comienza con un conjunto aleatorio y lo mejora mediante el descenso aleatorio más pronunciado. En cada paso, uno de los elementos del conjunto se selecciona aleatoriamente de manera uniforme y se reemplaza por otro conjunto de conteo seleccionado aleatoriamente de manera uniforme entre los que no están en uso. El paso se acepta si no aumenta el número de coincidencias. Esta última prescripción parece ser crucial; aceptar pasos solo si reducen el número de coincidencias no es tan efectivo. Los pasos que dejan el número de coincidencias invariables permiten explorar el espacio de búsqueda y, finalmente, se puede abrir algo de espacio para evitar una de las coincidencias. Después de 2 ^ 24 pasos sin mejora, el tamaño anterior se genera para el valor presente de n, yn se incrementa.
Los resultados hasta n = 9 son
2, 4, 10, 16, 31, 47, 76, 112, 168
, mejorando en los resultados anteriores para n = 8 por uno y para n = 9 por dos. Para valores más altos de n, puede que sea necesario aumentar el límite de 2 ^ 24 pasos.También probé el recocido simulado (con el número de partidos como la energía), pero sin mejorar el descenso más pronunciado.
Código
guardar como
Question54354.java
compilar con
javac Question54354.java
ejecutar con
java Question54354
fuente
2, 4, 10, 16, 31, 47, 76, 111, 166, 235
Notas
Si consideramos un gráfico
G
con vértices0
an
y bordes de unión de dos números que partido, entonces el poder tensorG^n
tiene vértices(x_0, ..., x_{n-1})
que forman el poder cartesiano{0, ..., n}^n
y bordes entre tuplas las características determinadas. El gráfico de interés es el subgrafo deG^n
inducido por aquellos vértices que corresponden a las posibles "matrices de conteo".Entonces, la primera subtarea es generar esos vértices. El enfoque ingenuo enumera sobre
2^{2n-1}
cadenas, o en el orden de4^n
. Pero si en cambio observamos la matriz de primeras diferencias de las matrices de conteo, encontramos que solo hay3^n
posibilidades, y de las primeras diferencias podemos deducir el rango de posibles valores iniciales al requerir que ningún elemento en las diferencias de cero sea menor0
o mayor quen
.Entonces queremos encontrar el conjunto independiente máximo. Estoy usando un teorema y dos heurísticas:
(n, n, ..., n)
estará en un conjunto máximo independiente. Hay una camarilla de vértices bastante grande{m, m+1, ..., n}^n
dondem
es el número entero más pequeño que coinciden
;(n, n, ..., n)
se garantiza que no tendrá partidos fuera de esa camarilla.En mi equipo esta hallazgos
111
paran=8
en 16 segundos,166
paran=9
en unos 8 minutos, y235
paran=10
en aproximadamente 2 horas.Código
Guardar como
PPCG54354.java
, compilar comojavac PPCG54354.java
y ejecutar comojava PPCG54354
.fuente
Mathematica
n = 5
,, 31 cuerdasAcabo de escribir una solución de fuerza bruta usando las funciones integradas de Mathematica para verificar las respuestas de ejemplo de Lembik, pero también puede manejar
n = 5
:Como beneficio adicional, este código produce una visualización del problema como un gráfico donde cada borde indica dos cadenas coincidentes.
Aquí está el gráfico para
n = 3
:fuente
C ++ (heurístico): 2, 4, 10, 16, 31, 47, 75, 111, 164, 232, 328, 445, 606, 814, 1086
Esto está ligeramente por detrás del resultado de Peter Taylor, siendo 1 a 3 más bajo para
n=7
,9
y10
. La ventaja es que es mucho más rápido, por lo que puedo ejecutarlo para valores más altos den
. Y se puede entender sin ninguna matemática elegante. ;)El código actual está dimensionado para ejecutarse hasta
n=15
. Los tiempos de ejecución aumentan aproximadamente en un factor de 4 por cada aumento enn
. Por ejemplo, fue 0.008 segundosn=7
, 0.07 segundosn=9
, 1.34 segundosn=11
, 27 segundosn=13
y 9 minutosn=15
.Hay dos observaciones clave que utilicé:
c
excluyendo el rango dec / 2
a2 * c
de otros valores. Para valores más pequeños dec
, este rango es más pequeño, lo que significa que se excluyen menos valores al usarlo.Generar matrices de recuento únicas
Fui fuerza bruta en este, iterando a través de todos los valores, generando la matriz de conteo para cada uno de ellos y uniquificando la lista resultante. Ciertamente, esto podría hacerse de manera más eficiente, pero es lo suficientemente bueno para los tipos de valores con los que estamos operando.
Esto es extremadamente rápido para los valores pequeños. Para los valores más grandes, la sobrecarga se vuelve sustancial. Por ejemplo, para
n=15
, utiliza aproximadamente el 75% de todo el tiempo de ejecución. Definitivamente, este sería un área a tener en cuenta cuando se intenta ir mucho más alto quen=15
. Incluso el uso de memoria para construir una lista de las matrices de conteo para todos los valores comenzaría a ser problemático.El número de matrices de conteo únicas es aproximadamente el 6% del número de valores para
n=15
. Este recuento relativo se vuelve más pequeño a medida que sen
hace más grande.Selección codiciosa de valores de matriz de conteo
La parte principal del algoritmo selecciona los valores de la matriz de conteo de la lista generada utilizando un enfoque codicioso simple.
Según la teoría de que el uso de matrices de conteo con recuentos pequeños es beneficioso, las matrices de conteo se ordenan por la suma de sus recuentos.
Luego se verifican en orden y se selecciona un valor si es compatible con todos los valores utilizados anteriormente. Por lo tanto, esto implica un único paso lineal a través de las matrices de conteo únicas, donde cada candidato se compara con los valores que se seleccionaron previamente.
Tengo algunas ideas sobre cómo podría mejorarse la heurística. Pero esto parecía un punto de partida razonable, y los resultados parecían bastante buenos.
Código
Esto no está muy optimizado. Tenía una estructura de datos más elaborada en algún momento, pero habría necesitado más trabajo para generalizarla más allá
n=8
, y la diferencia en el rendimiento no parecía muy sustancial.fuente
n=4
ya. Podría haber terminadon=5
con algo de paciencia. Debes haber utilizado una mejor estrategia de retroceso para lograrlon=7
. ¿Fue el suyo heurístico, o exploró todo el espacio de solución? Estoy contemplando algunas ideas sobre cómo mejorar esto, ya sea ajustando el orden de clasificación o quizás no siendo puramente codicioso.3^n
y las dos heurísticas que describe.n=7
rápidamente. Pero al intentarlon=9
, todavía estaba atascado en 164 cuando lo detuve después de 20 minutos. Por lo tanto, ampliar esto con una forma limitada de retroceso simple no parece generalmente prometedor.