Si combinamos ambas permutaciones, el resultado tendrá paridad par cuando cada permutación tiene la misma paridad y paridad impar si tienen paridad diferente. Entonces, si resolvemos el problema de paridad , es trivial comparar dos permutaciones diferentes.
Paridad se puede determinar de la siguiente manera: escoja un elemento arbitrario, encontrar la posición de que la permutación mueve a este, repetir hasta que vuelvas a la que empezó. Ahora ha encontrado un ciclo: la permutación gira todos estos elementos en una posición. Necesitas un intercambio menor que la cantidad de elementos en el ciclo para deshacerlo.Ahora elige otro elemento con el que aún no te hayas ocupado y repite hasta que hayas visto todos los elementos. Observe que, en total, necesitaba un intercambio por elemento menos un intercambio por ciclo.
La complejidad del tiempo es O (N) en el tamaño de la permutación. Tenga en cuenta que aunque tenemos un bucle dentro de un bucle, el bucle interno solo puede iterar una vez para cualquier elemento en la permutación.
def parity(permutation):
permutation = list(permutation)
length = len(permutation)
elements_seen = [False] * length
cycles = 0
for index, already_seen in enumerate(elements_seen):
if already_seen:
continue
cycles += 1
current = index
while not elements_seen[current]:
elements_seen[current] = True
current = permutation[current]
return (length-cycles) % 2 == 0
def arePermsEqualParity(perm0, perm1):
perm0 = list(perm0)
return parity([perm0[i] for i in perm1])
Además, sólo por diversión, he aquí una aplicación mucho menos eficiente, pero mucho más corto de la función de la paridad en base a la definición en Wikipedia (volviendo True para uniforme y False para impar):
def parity(p):
return sum(
1 for (x,px) in enumerate(p)
for (y,py) in enumerate(p)
if x<y and px>py
)%2==0
¿Es una permutación una lista de ciclos disjuntos? Una lista de pares de transposición? Una lista de pares '(s, σ (s))' (donde σ es la permutación que se representará) – outis
Outis: Supongo que puede ser ambas cosas. –