Skip to content
Snippets Groups Projects
Commit 40aa263a authored by Bastien Auvray's avatar Bastien Auvray
Browse files

Upload New File

parent d35edc1a
No related branches found
No related tags found
No related merge requests found
import itertools
#Fonction outil pour calculer la parent distance.
#max_j(seq, i) trouve le plus grand entier j tq S[j] < S[i]
#et retourne j, ou retourne 0 si un tel j n'existe pas.
def max_j(seq, i):
j = 0
for k in range(0, i):
if seq[k] < seq[i]:
j = k + 1 #+1 pour la numérotation
return j
#Parent-distance classique, lue de la gauche vers la droite.
def pdd(seq):
res = []
for i in range(len(seq)):
j = max_j(seq, i)
if j != 0:
res.append(i + 1 - j) #+1 pour la numérotation
else:
res.append(0)
return res
#Parent-distance de la droite vers la gauche, version paresseuse
#Il serait peut-être bon de la redéfinir comme pdd.
def pdg(seq):
s = seq.copy()
list.reverse(s)
res = pdd(s)
list.reverse(res)
return res
#first_diff gauche et droite identifient la première position
#où les parent-distances diffèrent afin de mettre en évidence
#les deux indices sur lesquels le swap s'est possiblement produit.
#Chaque fonction renvoie l'indice de la première position qui diffère
#ou -1 si une telle position n'existe pas
def first_diff_d(pdd1, pdd2):
for index, value in enumerate(zip(pdd1, pdd2)):
if value[0] != value[1]:
return index
return -1
def first_diff_g(pdg1, pdg2):
for index, value in reversed(list(enumerate(zip(pdg1, pdg2)))):
if value[0] != value[1]:
return index
return -1
#Vérifie les conditions nécessaires (mais pas suffisantes)
#sur les éléments des parent-distances
#Voir pour factoriser le code plus tard
def check_abcd(pdd1, pdd2, pdg1, pdg2, i):
ad = pdd1[i]
bd = pdd1[i+1]
cd = pdd2[i]
dd = pdd2[i+1]
ag = pdg1[i+1]
bg = pdg1[i]
cg = pdg2[i+1]
dg = pdg2[i]
#cas x[i] < x[i+1]
if (bd == 1 and dg == 1):
if ((ad == 0 and dd != 0)
or (ad > 0 and (cd > ad or dd != ad + 1))
or (bg == 0 and cg != 0)
or (bg > 1 and cg != bg - 1)
or (bg == 1)):
return False
#cas x[i] > x[i+1]
if (bg == 1 and dd == 1):
if ((ag == 0 and dg != 0)
or (ag > 0 and (cg > ag or dg != ag + 1))
or (bd == 0 and cd != 0)
or (bd > 1 and cd != bd - 1)
or (bd == 1)):
return False
#Tout est cohérent sinon
return True
#Vérifie si seq2 peut être CT-équivalente (à un swap près) à seq1
def check_swap(seq1, seq2):
pdd1 = pdd(seq1)
pdd2 = pdd(seq2)
pdg1 = pdg(seq1)
pdg2 = pdg(seq2)
i = first_diff_d(pdd1, pdd2)
j = first_diff_g(pdg1, pdg2)
if i == -1 or j == -1:
return False
diff = j - i
if diff == 1:
return check_abcd(pdd1, pdd2, pdg1, pdg2, i)
if diff == -1:
return check_abcd(pdd1, pdd2, pdg1, pdg2, j)
if diff == 0:
return (check_abcd(pdd1, pdd2, pdg1, pdg2, i-1)
or check_abcd(pdd1, pdd2, pdg1, pdg2, i))
return False
#Fonction outil qui onstruit la séquence '1..n' qui permet
#d'ensuite générer toutes les permutations à l'aide d'itertools
def seq_n(n):
res = ''
for i in range(n):
res += str(i+1)
return res
#Brute force pour des permutations de taille n en effectuant
#toutes les poignées de mains possibles, puis retourne
#le nombre de matchs d'après check_swap ainsi que le nombre de
#poignées de main
#Décommenter la partie sur res permet de retourner une liste de
#toutes les permutations qui ont match en plus
def check_all(n):
perm = list(itertools.permutations(seq_n(n)))
l = len(perm)
check = 0
handshake = 0
#res = []
for i in range(l):
for j in range(i + 1, l):
if check_swap(list(perm[i]), list(perm[j])):
check += 1
#res.append((i,j))
handshake += 1
return check, handshake#, res
#LEGACY CODE - USELESS AS OF NOW
# def check_swap_flag_or(seq1, seq2):
# pdd1 = pdd(seq1)
# pdd2 = pdd(seq2)
# pdg1 = pdg(seq1)
# pdg2 = pdg(seq2)
# i = first_diff_d(pdd1, pdd2)
# j = first_diff_g(pdg1, pdg2)
# if i == -1 or j == -1:
# return (False, False)
# diff = j - i
# if diff == 1:
# return (check_abcd(pdd1, pdd2, pdg1, pdg2, i), False)
# if diff == -1:
# return (check_abcd(pdd1, pdd2, pdg1, pdg2, j), False)
# if diff == 0:
# return ((check_abcd(pdd1, pdd2, pdg1, pdg2, i-1)
# or check_abcd(pdd1, pdd2, pdg1, pdg2, i)), True)
# return (False, False)
# def check_all_flag_or(n):
# perm = list(itertools.permutations(seq_n(n)))
# l = len(perm)
# check = 0
# handshake = 0
# res = []
# for i in range(l):
# for j in range(i + 1, l):
# ref = check_swap_flag_or(list(perm[i]), list(perm[j]))
# if (ref == (True, True)):
# check += 1
# res.append((i+1,j+1))
# handshake += 1
# return check, handshake, res
# def check_swap_flag_xor(seq1, seq2):
# pdd1 = pdd(seq1)
# pdd2 = pdd(seq2)
# pdg1 = pdg(seq1)
# pdg2 = pdg(seq2)
# i = first_diff_d(pdd1, pdd2)
# j = first_diff_g(pdg1, pdg2)
# if i == -1 or j == -1:
# return (False, False)
# diff = j - i
# if diff == 1:
# return (check_abcd(pdd1, pdd2, pdg1, pdg2, i), False)
# if diff == -1:
# return (check_abcd(pdd1, pdd2, pdg1, pdg2, j), False)
# if diff == 0:
# return ((check_abcd(pdd1, pdd2, pdg1, pdg2, i-1)
# ^ check_abcd(pdd1, pdd2, pdg1, pdg2, i)), True)
# return (False, False)
# def check_all_flag_xor(n):
# perm = list(itertools.permutations(seq_n(n)))
# l = len(perm)
# check = 0
# handshake = 0
# res = []
# for i in range(l):
# for j in range(i + 1, l):
# ref = check_swap_flag_xor(list(perm[i]), list(perm[j]))
# if (ref == (True, True)):
# check += 1
# res.append((i+1,j+1))
# handshake += 1
# return check, handshake, res
#-------------------------------------------
#TESTS
#list(itertools.permutations('012'))
#max_j(["5","6","1","3","4","2"], 4)
#max_j(('5','6','1','3','4','2'), 2)
#pdd(["4","5","6","1","2","7","8","3","9"])
#pdg(["4","5","6","1","2","7","8","3","9"])
#pdd(["4","5","6","3","1","7","8","2","9"])
#pdg(["4","5","6","3","1","7","8","2","9"])
#s1 = ["4","5","6","1","2","7","8","3","9"]
#s2 = ["4","5","6","3","1","7","8","2","9"]
#s3 = ("4","5","6","1","2","7","8","3","9")
#pd1 = pdd(s1)
#pd2 = pdd(s2)
#pd3 = pdg(s1)
#pd4 = pdg(s2)
#pd5 = pdd(s3)
#first_diff_d(pd1, pd2)
#first_diff_g(pd3, pd4)
#check_swap(s1, s2)
#check_swap(s1, s1)
#seq_n(3)
#list(itertools.permutations('1234'))
#l1 = check_all_flag_or(4)[2]
#l2 = check_all_flag_xor(4)[2]
#set(l1).symmetric_difference(set(l2))
#s4 = ["1","4","2","3"]
#s5 = ["3","2","1","4"]
#first_diff_d(pdd(s4), pdd(s5))
#first_diff_g(pdg(s4), pdg(s5))
#pdd(s4)
#pdd(s5)
#pdg(s4)
#pdg(s5)
#check_all_flag_or(4)
#check_all_flag_xor(4)
check_all(3)
check_all(4)
check_all(5)
check_all(6)
check_all(7)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment