tg4/Chapitre 4 - Graphes/C08_activite_reseau.py
2023-12-20 08:40:17 +01:00

143 lines
5.5 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#
# Chapitre 8 - Activité 2 - Réseau social simple
#
class Personne:
def __init__(self, nom, annee_naissance):
self.nom = nom
self.annee_naissance = annee_naissance
self.relations = {} # clés : noms, valeurs : année de début de la relation
def __repr__(self):
""" La fonction appelée par `print` """
texte = f"Personne '{self.nom}' née en {self.annee_naissance}"
if len(self.relations) > 0:
texte += ", connait :"
for nom, annee in self.relations.items():
texte += f"\n{nom} depuis {annee}"
return texte
donnees_personnes = { "Rafael": 1994, "Stéphanie": 1980, "Dinesh": 1980,
"Margot": 1987, "Sofiane": 1985, "Lucia": 1988,
"Antti": 1979, "Johanna": 1980, "Ahmed": 1986,
"Didier": 1971, "Chimène": 1984, "Marc": 1980,
"Charles": 1991, "Antoine": 1991, "Maurice": 1992,
"Samuli": 1989, "Marlène": 1980, "Carl": 1986 }
exemple_reseau = { nom: Personne(nom, annee)
for nom, annee in donnees_personnes.items() }
donnees_liens = { ('Rafael', 'Margot'): 2021,
('Dinesh', 'Antti'): 1998,
('Margot', 'Lucia'): 2022,
('Margot', 'Ahmed'): 2004,
('Margot', 'Didier'): 2011,
('Antti', 'Samuli'): 1999,
('Chimène', 'Carl'): 2011,
('Charles', 'Antoine'): 2021,
('Samuli', 'Marlène'): 2020,
('Stéphanie', 'Dinesh'): 2003,
('Margot', 'Sofiane'): 2020,
('Margot', 'Johanna'): 2021,
('Margot', 'Charles'): 2021,
('Ahmed', 'Maurice'): 2008,
('Didier', 'Charles'): 2004,
('Marc', 'Chimène'): 2000,
('Chimène', 'Marlène'): 1992,
('Antoine', 'Maurice'): 1999,
('Marlène', 'Carl'): 2010,
}
for lien, annee in donnees_liens.items():
nom1 = lien[0]
nom2 = lien[1]
p1 = exemple_reseau[nom1]
p2 = exemple_reseau[nom2]
if (nom1 in p2.relations) or (nom2 in p1.relations):
print(f"/!\\ Attention, la relation {nom1} - {nom2} existe déjà !")
if (annee < p1.annee_naissance):
raise ValueError(f"L'année de relation {annee} est antérieure à la naissance de {nom1} ({p1.annee_naissance}) !")
if (annee < p2.annee_naissance):
raise ValueError(f"L'année de relation {annee} est antérieure à la naissance de {nom2} ({p2.annee_naissance}) !")
p1.relations[nom2] = annee
p2.relations[nom1] = annee
from datetime import date
def duree_relation(p1, p2):
annee = p1.relations.get(p2.nom, None)
if annee is None:
return None
return date.today().year - annee
def plus_ancienne_relation(personnes):
plus_ancienne_relation = None
gens = None
for p1 in personnes:
for p2 in personnes:
if p1.nom == p2.nom:
continue
d = duree_relation(p1, p2)
if plus_ancienne_relation is None or (d is not None and d > plus_ancienne_relation):
plus_ancienne_relation = d
gens = (p1, p2)
return gens
# print(plus_ancienne_relation(exemple_reseau.values()))
def plus_de_relations(personnes):
return max(personnes, key=lambda p: len(p.relations))
# print(plus_de_relations(exemple_reseau.values()))
def search(personnes, personne, target, depth=1):
if depth > len(personnes):
return None
if target in personne.relations:
return depth
distances = [search(personnes, personnes[relation], target, depth+1) for relation in personne.relations]
distances = [distance for distance in distances if distance is not None]
if distances:
return min(distances)
def search(personnes, personne, target, depth=1):
# Condition d'arret
if depth > len(personnes):
return None
if target in personne.relations:
return depth, [personne, personnes[target]]
# On appelle récursivement pour toutes les relations
distances = []
for relation in personne.relations:
other = personnes[relation]
distance = search(personnes, other, target, depth + 1)
if distance is not None:
distances.append(distance)
# Autre méthode
# distances = [search(personnes, personnes[relation], target, depth + 1) for relation in personne.relations]
# distances = [distance for distance in distances if distance is not None]
# On trouve la liaison la plus courte
if distances:
distance, personnes = min(distances, key=lambda d: d[0])
return distance, [personne] + personnes
distance, personnes = search(exemple_reseau, exemple_reseau["Marc"], "Stéphanie")
print(f"La relation la plus courte entre Marc est Stéphanie est de {distance} relations:")
for personne in personnes:
print(f" - {personne}")
# On vérifie si des personnes ne sont pas reliées
checked = []
for personne in exemple_reseau.values():
for other in exemple_reseau.values():
if personne == other:
continue
two = sorted([personne.nom, other.nom])
if two in checked:
continue
checked.append(two)
if search(exemple_reseau, personne, other.nom) is None:
print(f"{personne.nom} et {other.nom} n'ont pas de liaison possible")