-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathetape3.py
More file actions
137 lines (98 loc) · 2.93 KB
/
Copy pathetape3.py
File metadata and controls
137 lines (98 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
An implementation of the Irving Algorithm for the Stable roommates problem by:
Vincent LIU - MAIN - Polytech Sorbonne 2017/18
Comments are in French.
"""
def cycle(pref):
"""
Identifie un cycle
:param pref: Les clés correspondent aux noms des colocataires, donc ce sont des chaînes de caractères
Les valeurs sont les listes de préférences du colocataire, donc une liste des chaînes de caractères.
:type pref: dict()
:return reject: On retourne une liste de tuple, qui correspond aux cycles.
Ce sont les personnes que l'on va rejeter.
:rtype: list()
"""
p1 = None
# Chercher un début de cycle, trouver un p_1 qui convient
for e in pref:
if len(pref[e])>1:
p1 = e
break
# Pas de cycle
if p1 is None:
return None
p11 = []
p11.append(p1)
p = []
q = []
while p1 not in p:
# q est la deuxieme personne prefere de p_1, donc indice 1
q.append(pref[p1][1])
p.append(p1)
# le nouveau p_i est la personne la moins désirée de q_i donc indice -1
p1 = pref[q[-1]][-1]
if len(pref[p1]) <= 1:
p = []
q = []
p1 = None
for e in pref:
if len(pref[e]) > 1 and e not in p11:
p1 = e
p11.append(p1)
break
# Pas de cycle
if p1 is None:
return None
# les q{i} et les p_{i+1} vont se rejeter, on les stock dans une liste de tuple
c = []
for i in range(len(p)-1):
c.append((p[i+1], q[i]))
c.append((p[0],q[len(q)-1]))
return c
def etape3(prefReduit):
"""
Effectue l'étape 3 de l'algorithme de Irving pour le problème des colocataires.
:param prefReduit: les clés correspondent aux noms des colocataires, donc ce sont des chaînes de caractères
Les valeurs sont les listes de préférences réduites du colocataire, donc une liste des chaînes de caractères
:type prefReduit: dict()
:return: Les clés correspondent aux noms des colocataires, donc ce sont des chaînes de caractères
Les valeurs sont les listes de préférences réduites du colocataire, donc une liste des chaînes de caractères
:rtype: dict()
"""
# On va chercher un cycle initial
c = cycle(prefReduit)
if c == None:
return None
# Tant qu'il existe un cycle
while c != None:
# Rejet symétrique des (q_{i+1}, pi)
reject(prefReduit, c)
test = False
# Rejet symétrique
for e in prefReduit:
if len(prefReduit[e]) > 1:
test = True
break
if len(prefReduit[e]) == 0:
print("Pas de solution stable")
return None
if test == False:
break
# On cherche un nouveau cycle pour l'iteration suivante
c = cycle(prefReduit)
return prefReduit
def reject(prefReduit, c):
"""
Rejet des pi, qi dans l'etape 3
"""
## On rejette symetriquement les (p_i, q_i):
# Lorsqu'on rejette a dans la liste de preference de b,
# on rejette egalement b dans la liste de preference de a.
for (a,b) in c:
if a in prefReduit[b]:
prefReduit[b].remove(a)
if b in prefReduit[a]:
prefReduit[a].remove(b)