Estaba buscando this porque estoy tratando de hacer un solucionador de quince rompecabezas. Realmente no entiendo de qué está hablando. ¿Cómo puedo verificar si un conjunto dado de números (de 0 a 15, almacenados en una matriz, 0 en blanco) es válido dado que "si el símbolo de permutación de la lista es +1, la posición es posible". Estoy trabajando en javascript, si es relevante.Encontrar el número de inversiones de permutación
Respuesta
Considere lo siguiente: Si tomó un 15 rompecabezas resuelto, y con un par de capas extraídas e intercambiadas físicamente y reemplazó los bloques 14
y 15
, y lo revolvió ... ¿podría devolverlo a un estado válido?
la respuesta es no. Hay un invariante que se conserva mediante todos los movimientos que puede hacer en un rompecabezas de 15, y el símbolo de permutación probablemente se está refiriendo a ese invariante.
Según http://en.wikipedia.org/wiki/Fifteen_puzzle:
El invariante es la paridad de la permutación de los 16 cuadrados (15 piezas más cuadrado vacío), además de la paridad de la distancia de taxi movido por el cuadrado vacío.
Esto es un invariante porque cada movimiento cambia tanto la paridad de la permutación como la paridad de la distancia del taxi. En particular, si el cuadrado vacío no se mueve, la permutación de las piezas restantes debe ser par.
Para calcular esta paridad, echa un vistazo a http://en.wikipedia.org/wiki/Parity_of_a_permutation (también se podría retirar Levi-Civita Símbolo, pero es un poco arcano), lo apliquen en Python, a continuación, calcular la distancia Manhattan la plaza vacía ha movido de su partida posición, y tome la paridad de la suma de ambos valores.
Algo así como:
#!/usr/bin/python3
from pprint import pprint
state_starting = list(range(1,16)) + [None]
START = state_starting
def positionIsPossible(state):
"""
state is a list, the starting position is [1,2,3,...,15,None]
"""
numInversions = sum(
state.index(START[j]) > state.index(START[i])
for i in range(16) for j in range(i) # each pair (i,j)
) #sum([True,True,False])==2
# Uncomment if you want to see what's going on here:
#pprint(list(
# ((i,j), (START[i],START[j]), state.index(START[j]) > state.index(START[i]))
# for i in range(15) for j in range(i)
#))
newEmptySquareYPos = state.index(None)//4
newEmptySquareXPos = state.index(None)%4
emptySquareMovedDistance = abs(3-newEmptySquareYPos)+abs(3-newEmptySquareXPos)
parity = (numInversions + emptySquareMovedDistance)%2
print('number of inversions:', numInversions)
print('distance empty square moved:', emptySquareMovedDistance)
print('parity:', parity)
return parity==0
He aquí algunos ejemplos/casos de prueba:
def swap(state, i, j):
state = list(state)
state[i], state[j] = (state[j], state[i])
return state
def validate(state):
def formatState(state):
return '\n'.join('|'+' '.join([str(y if y else '').rjust(2) for y in x])+'|' for x in [state[0:4],state[4:8],state[8:12],state[12:16]])
print(formatState(state))
print(state, 'is', 'reachable' if positionIsPossible(state) else 'unreachable')
print()
# reachable
validate(state_starting)
validate(swap(state_starting, 15,14))
validate(swap(state_starting, 15,11))
# unreachable
validate(swap(state_starting, 14,13))
Resultados:
| 1 2 3 4|
| 5 6 7 8|
| 9 10 11 12|
|13 14 15 |
number of inversions: 0
distance empty square moved: 0
parity: 0
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, None] is reachable
| 1 2 3 4|
| 5 6 7 8|
| 9 10 11 12|
|13 14 15|
number of inversions: 1
distance empty square moved: 1
parity: 0
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, None, 15] is reachable
| 1 2 3 4|
| 5 6 7 8|
| 9 10 11 |
|13 14 15 12|
number of inversions: 7
distance empty square moved: 1
parity: 0
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, None, 13, 14, 15, 12] is reachable
| 1 2 3 4|
| 5 6 7 8|
| 9 10 11 12|
|13 15 14 |
number of inversions: 1
distance empty square moved: 0
parity: 1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 14, None] is unreachable
Si el algoritmo no le importa realmente acerca de si la posición es posible o no (solo está haciendo esto para decir "¡entrada no válida! ¡posición imposible!" podría ignorar esta parte, ejecútalo de todos modos por unos cientos de iteraciones, y devuelve "imposible" si no se resuelve.
Debido a los "ciclos" necesarios para mover las piezas en uno de estos rompecabezas, las permutas de piezas no se pueden realizar de forma aislada. Considere la pizarra:
debe cambiar (11) una (12) para resolverlo. Pero como puedes? Simplemente "ciclar" (11, 12, 15, -) en cualquier dirección nunca cambiará el orden. Por lo tanto, debemos involucrar más piezas, pero al hacerlo, no podemos preservar el orden de esas otras piezas. Todo lo que intentemos dará como resultado el cambio de otro par.Por ejemplo, podríamos corregir (11) y (12) con la participación de la (7) y (8), pero al hacerlo, cambie el (8) y (-):
Por lo tanto, el número de intercambios necesarios para resolver el rompecabezas debe ser uniforme, o nos queda un "hombre extraño" como en el tablero de arriba.
Por lo tanto, una vez más, si detecta en su solucionador una situación en la que un intercambio único resolverá el rompecabezas, sabrá que este tablero no puede ser resuelto.
- 1. ¿Cómo encontrar el número de inversiones en una matriz?
- 2. Permutación rápida -> número -> algoritmos de asignación de permutación
- 3. Algoritmo para encontrar la permutación numérica dado el índice lexicográfico
- 4. Contando las inversiones utilizando BIT
- 5. Oráculo - permutación combinatoria de cadena
- 6. Encontrar el número de versión de Eclipse
- 7. permutación de un vector
- 8. ¿Calcular el paso de permutación enésimo?
- 9. Encontrar el número de procesos secundarios
- 10. Encontrar el número de núcleos en Java
- 11. Combinaciones Haskell y permutación
- 12. ¿Cómo generar una permutación?
- 13. Generador de permutación más rápido
- 14. Permutación con Repetición: desbordamiento Evitar
- 15. permutación del conjunto
- 16. Usar el recuento para encontrar el número de ocurrencias
- 17. Cómo encontrar el número de objetos en el montón
- 18. Colecciones: Guayaba límite de tamaño de permutación
- 19. C++ Encontrar el mayor número en serie
- 20. Encontrar el número de errores en un proyecto de eclipse
- 21. Cómo encontrar el número de versión de libxxx.a
- 22. ¿Cómo encontrar el número de fila de un registro?
- 23. Cómo encontrar el número de líneas de UITextView
- 24. ¿Cómo encontrar el complemento de N de un número?
- 25. Cómo encontrar el número de líneas de UILabel
- 26. Cómo encontrar el número de versión de Django-CMS
- 27. Forma rápida de encontrar el siguiente múltiplo de un número
- 28. ¿Cómo encontrar el número de puerto de la dirección IP?
- 29. Encontrar un número primo después de un número dado
- 30. generador de permutación recursivo para caracteres
discúlpeme, ¿puede traducir su posición de defEs Posible (estado) a Java por casualidad? – JRowan
lo tengo, gracias por su tiempo – JRowan