Se uniamo due permutazioni, il risultato avrà parità pari quando ogni permutazione ha la stessa parità e parità dispari se hanno la parità diversa. Quindi, se risolviamo il problema di parità , è banale confrontare due diverse permutazioni.
La parità può essere determinata come segue: selezionare un elemento arbitrario, trovare la posizione in cui la permutazione lo sposta, ripetere fino a tornare a quello con cui si è iniziato. Ora hai trovato un ciclo: la permutazione ruota tutti questi elementi intorno di una posizione. È necessario uno swap in meno del numero di elementi nel ciclo per annullarlo.Ora scegli un altro elemento che non hai ancora affrontato e ripeti finché non hai visto tutti gli elementi. Osserva che in totale hai avuto bisogno di uno swap per elemento meno uno swap per ciclo.
La complessità temporale è O (N) nella dimensione della permutazione. Notare che sebbene abbiamo un ciclo all'interno di un ciclo, il ciclo interno può sempre iterare una sola volta per qualsiasi elemento nella permutazione.
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])
Inoltre, solo per divertimento, ecco un'implementazione molto meno efficiente, ma molto più breve della funzione di parità in base alla definizione di Wikipedia (ritorno vero anche per e False per dispari):
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
È una permutazione un elenco di cicli disgiunti? Un elenco di coppie di trasposizione? Una lista di coppie '(s, σ (s)) (dove σ è la permutazione da rappresentare)? – outis
Outis: Suppongo che possa essere entrambi. –