Commit 17ed6aff authored by Francois Mares's avatar Francois Mares
Browse files
parents ca0b7423 1d369422
......@@ -3,194 +3,103 @@ from Monoide import MonoideAleatoire
import random
import copy
import itertools
from collections import defaultdict
from config import *
# class GrapheCompositionAleatoire(GC):
# """Construit un graphe de composition aléatoire."""
# def __init__(self, nb_objets = None, nb_morph = None, proba_brancher:float=1/100):
# """`nb_morph` est le nombre de morphismes élémentaires à ajouter aléatoirement.
# `proba_brancher` est la probabilité de brancher lors de la création de l'arbre de composition des cycles,
# Plus la probabilité est grande plus il y aura de cycles et plus la loi de composition ne sera pas triviale.
# Si la probabilité est 0, tous les cycles seront des isomorphismes
# et les flèches de obj vers obj seront idempotents."""
# GC.__init__(self,"Graphe de composition aléatoire")
# if nb_objets == None:
# nb_objets = random.randint(5,20)
# if nb_morph == None:
# nb_morph = random.randint(0,30)
# if PRINT_AVANCEMENT_CREATION_CAT_ALEA:
# print("Création d'une catégorie avec "+str(nb_objets)+" objets et "+str(nb_morph)+" morphismes")
# for i in range(nb_objets): #ajout des objets
# self |= {i}
# for i in range(nb_morph): # ajout des morphismes
# source = random.randint(0,nb_objets-1)
# cible = random.randint(0,nb_objets-1)
# self |= {MGC(source,cible)}
# on définit la loi de composition pour les cycles
# for obj in self.objets:
# cycles_minimaux = self.trouver_cycles_minimaux(obj,inclure_id=False)
# cycles_finaux = cycles_minimaux
# cycles_graines = set(cycles_minimaux) # cycles qui ont un chance de brancher
# while len(cycles_graines) > 0:
# cycle = cycles_graines.pop()
# if random.random() < proba_brancher:
# on branche
# nouveaux_cycles = {c@cycle for c in cycles_minimaux}
# cycles_finaux |= nouveaux_cycles
# cycles_graines |= nouveaux_cycles
# maintenant on a tous les cycles finaux
# nb_cycles = len(cycles_finaux)+1
# monoide_alea = MonoideAleatoire()
# if PRINT_AVANCEMENT_CREATION_CAT_ALEA:
# print("Fin création")
# if TOUJOURS_VERIFIER_COHERENCE:
# self.verifier_coherence()
class GrapheCompositionAleatoire(GC):
"""Construit un graphe de composition aléatoire."""
def __init__(self, nb_fleches:int = None, nom:str = "Catégorie Aléatoire"):
def __init__(self, nb_fleches:int = None, proba_arreter_generation_loi_de_compo:float = 1/100,nom:str = "Catégorie Aléatoire"):
if nb_fleches == None:
nb_fleches = random.randint(5,30)
nb_fleches = random.randint(1,30)
GC.__init__(self,nom=nom)
elements = list(range(nb_fleches))
table = dict()
for a in elements:
for b in elements:
if (a,b) not in table:
table[(a,b)] = random.choice(elements)
# on force l'associativité si on peut
for c in elements:
if (table[(a,b)],c) in table and (b,c) in table:
if (a,table[(b,c)]) not in table:
table[(a,table[(b,c)])] = table[(table[(a,b)],c)]
elements += [-1]
for i in elements:
table[(-1,i)] = i
table[(i,-1)] = i
table = defaultdict(lambda:None)
i,j = random.randint(0,nb_fleches-1),random.randint(0,nb_fleches-1)
cases_modifiees = set()
while random.random() > proba_arreter_generation_loi_de_compo:
cases_modifiees |= {(i,j)}
if table[(i,j)] == None:
table[(i,j)] = random.randint(0,nb_fleches-1)
for a,b,c in itertools.product(range(nb_fleches),repeat=3):
if table[(table[(a,b)],c)] != table[(a,table[(b,c)])]:
# l'associativité n'est pas vérifiée
for case in cases_modifiees:
table[case] = None
cases_modifiees = set()
i,j = random.randint(0,nb_fleches-1),random.randint(0,nb_fleches-1)
break
if cases_modifiees == set():
# l'associativité n'est pas vérifiée
continue
for a,b in itertools.product(range(nb_fleches),repeat=2):
if table[(a,b)] != None:
for c in range(nb_fleches):
if table[(table[(a,b)],c)] != None and table[(b,c)] == None:
# les compositions ne sont pas respectées
i,j = b,c
break
if table[(table[(a,b)],c)] == None and table[(b,c)] != None:
# les compositions ne sont pas respectées
i,j = table[(a,b)],c
break
else:
continue
break
else:
#il n'y a eu aucune erreur de composition on valide les changements
cases_modifiees = set()
i,j = random.randint(0,nb_fleches-1),random.randint(0,nb_fleches-1)
GC.__init__(self)
#on a une table aléatoire
#maintenant on vérifie l'associativité
for a,b,c in itertools.product(elements,repeat=3):
if table[(a,b)] != "x" and table[(b,c)] != "x" and table[(table[(a,b)],c)] != table[(a,table[(b,c)])]:
table[(a,b)] = "x"
table[(b,c)] = "x"
for a,b,c in itertools.product(elements,repeat=3):
if table[(a,b)] != "x" and table[(b,c)] != "x" and table[(table[(a,b)],c)] != table[(a,table[(b,c)])]:
raise Exception(str(a)+" "+str(b)+" "+str(c))
with open("out.csv","w") as f:
f.write(","+",".join(map(str,elements))+"\n")
for a in elements:
f.write(str(a))
for b in elements:
f.write(','+str(table[(a,b)]))
f.write('\n')
#on a une table de loi de composition aléatoire
graphe_equiv = defaultdict(set)
#la source d'une flèche i est représentée par le nombre 2*i
#la cible d'une flèche i est représentée par le nombre 2*i+1
#on va faire le graphe d'équivalence entre ces nombres
for a,b in itertools.product(range(nb_fleches),repeat=2):
if table[(a,b)] != None:
# b o a = talbe[(a,b)]
graphe_equiv[2*b] |= {2*a+1}
graphe_equiv[2*a+1] |= {2*b}
graphe_equiv[2*a] |= {2*table[(a,b)]}
graphe_equiv[2*table[(a,b)]] |= {2*a}
graphe_equiv[2*b+1] |= {2*table[(a,b)]+1}
graphe_equiv[2*table[(a,b)]+1] |= {2*b+1}
elem_a_mapper = {i for i in range(nb_fleches*2)}
application = dict()
dernier_element = 0
while len(elem_a_mapper) > 0:
elem = elem_a_mapper.pop()
dernier_element += 1
self |= {dernier_element}
elem_visites = set()
file = {elem}
while len(file) > 0:
elem = file.pop()
application[elem] = dernier_element
elem_visites |= {elem}
file |= graphe_equiv[elem]-elem_visites
elem_a_mapper -= elem_visites
fleches = {i:MGC(application[2*i],application[2*i+1]) for i in range(nb_fleches)}
self |= set(fleches.values())
for i,j in itertools.product(range(nb_fleches),repeat=2):
if table[(i,j)] != None:
MGC.identifier_morphismes(fleches[j]@fleches[i],fleches[table[(i,j)]])
def test_GrapheCompositionAleatoire():
random.seed(1)
GCA = GrapheCompositionAleatoire()
GCA.transformer_graphviz()
GCA.loi_de_composition_to_csv('lois de composition/loi_de_compo.csv')
for i in range(20):
GCA = GrapheCompositionAleatoire()
GCA.transformer_graphviz()
GCA.loi_de_composition_to_csv('lois de composition/loi_de_compo.csv')
return GCA
# class CategorieAleaIsomorph(Categorie):
# """Construit une catégorie aléatoire où tous les cycles sont des isomorphismes."""
# def __init__(self, nb_objets = None, nb_morph = None):
# """nb_morph est le nombre de morphismes élémentaires à ajouter aléatoirement."""
# Categorie.__init__(self,"Catégorie aléatoire")
# if nb_objets == None:
# nb_objets = random.randint(5,20)
# if nb_morph == None:
# nb_morph = random.randint(0,30)
# if PRINT_AVANCEMENT_CREATION_CAT_ALEA:
# print("Création d'une catégorie avec "+str(nb_objets)+" objets et "+str(nb_morph)+" morphismes")
# self.ajouter_objets(list(range(nb_objets))) # ajout des objets
# for i in range(nb_morph): # ajout des morphismes
# pool = [(source,cible) for source,cible in itertools.product(range(nb_objets),repeat=2) if source != cible and len(self.enumerer_composees_sans_cycle(source,cible)) == 0 or len(self.enumerer_composees_sans_cycle(cible,source)) == 0]
# if len(pool) == 0:
# break
# source,cible = random.choice(pool)
# self.ajouter_morphisme(Morphisme(source,cible,str(i)))
# on définit la loi de composition pour les cycles
# for obj in self.objets:
# cycles = self.trouver_cycles_elementaires(obj)
# for c in cycles:
# diag = Parallele(self,[obj]*2,[c,self.identites[obj]])
# diag.faire_commuter()
# if PRINT_AVANCEMENT_CREATION_CAT_ALEA:
# print("Fin création")
# class CategorieAleaPreOrdre(Categorie):
# """Construit une catégorie pré-ordre aléatoire."""
# def __init__(self,nb_objets = None, proportion_morph = None, retirer_obj_isoles = True):
# """proportion morph est la proportion de morphismes de 0 (graphe sans flèche) à 1 (graphe complet)"""
# if nb_objets == None:
# nb_objets = random.randint(5,20)
# if proportion_morph == None:
# proportion_morph = min(random.expovariate(10),1)
# nb_morph = max(int(proportion_morph*(nb_objets)*(nb_objets-1)/2),5) # min 5 morphismes
# Categorie.__init__(self,"Catégorie pré-ordre aléatoire")
# self.ajouter_objets(list(range(nb_objets))) #ajout des objets
# i = 1
# for source,cible in random.sample(list(itertools.product(range(nb_objets),repeat=2)),nb_morph): # ajout des morphismes
# self.ajouter_morphisme(Morphisme(source,cible,str(i)))
# i += 1
# if retirer_obj_isoles:
# self.retirer_noeuds_isoles()
# diag = DiagrammeIdentite(self)
# diag.faire_commuter()
# def retirer_noeuds_isoles(self):
# self.supprimer_objets([obj for obj in self.objets if len(self.morph_sortants[obj]) == len(self.morph_entrants[obj]) == 0])
# class CategorieAleaPreOrdreAcyclique(Categorie):
# """Construit une catégorie pré-ordre aléatoire."""
# def __init__(self,nb_objets = None, proportion_morph = None, retirer_obj_isoles = True):
# """proportion morph est la proportion de morphismes de 0 (graphe sans flèche) à 1 (graphe complet)"""
# if nb_objets == None:
# nb_objets = random.randint(5,20)
# if proportion_morph == None:
# proportion_morph = min(random.expovariate(10),1)
# nb_morph = max(int(proportion_morph*(nb_objets)*(nb_objets-1)/2),5) # min 5 morphismes
# Categorie.__init__(self,"Catégorie pré-ordre aléatoire")
# self.ajouter_objets(list(range(nb_objets))) #ajout des objets
# i = 1
# for source,cible in random.sample(list(itertools.combinations(range(nb_objets),2)),nb_morph): # ajout des morphismes
# self.ajouter_morphisme(Morphisme(source,cible,str(i)))
# i += 1
# if retirer_obj_isoles:
# self.retirer_noeuds_isoles()
# diag = DiagrammeIdentite(self)
# diag.faire_commuter()
# def retirer_noeuds_isoles(self):
# self.supprimer_objets([obj for obj in self.objets if len(self.morph_sortants[obj]) == len(self.morph_entrants[obj]) == 0])
# class DiagrammeAlea(Diagramme):
# def __init__(self, cat_cible, nb_objets_restants=None, retirer_objets_isoles=True):
# """nb_objets_restants entre 0 et len(cat_cible.objets)
# retirer_objets_isoles n'est pas considéré s'il n'y a que des objets isolés"""
# if nb_objets_restants == None:
# nb_objets_restants = random.randint(1,len(cat_cible.objets))
# cat_source = copy.copy(cat_cible)
# obj_a_suppr = random.sample(cat_cible.objets,len(cat_cible.objets)-nb_objets_restants)
# print(obj_a_suppr)
# cat_source.supprimer_objets(obj_a_suppr)
# if retirer_objets_isoles and len([obj for obj in cat_source.objets if not(len(cat_source.morph_sortants[obj]) == len(cat_source.morph_entrants[obj]) == 0)]) != 0:
# cat_source.supprimer_objets([obj for obj in cat_source.objets if len(cat_source.morph_sortants[obj]) == len(cat_source.morph_entrants[obj]) == 0])
# Diagramme.__init__(self,cat_source,cat_cible,{o:o for o in cat_source.objets},{m:m for m in cat_source.morphismes})
if __name__ == '__main__':
random.seed(2579)
test_GrapheCompositionAleatoire()
\ No newline at end of file
......@@ -26,7 +26,7 @@ class MorphismeProduit(Morphisme,tuple):
__len__ = tuple.__len__
class CategorieProduit(CategorieLibre,tuple):
class CategorieProduit(tuple,CategorieLibre):
"""Catégorie produit de plusieurs catégories.
Soient C1,C2,...,Cn n catégories.
Un objet de C1xC2x...xCn est un n-uplet (o_1,o_2,...,o_n) avec o_i \in |Ci|.
......@@ -57,11 +57,6 @@ class CategorieProduit(CategorieLibre,tuple):
for nuplet in itertools.product(*tuple(tuple.__getitem__(self,i)[{source[i]},{cible[i]}] for i in range(len(source)))):
yield MorphismeProduit(*nuplet)
return fleches_elem()
__eq__ = tuple.__eq__
__hash__ = tuple.__hash__
__iter__ = tuple.__iter__
__len__ = tuple.__len__
def test_CategorieProduit():
......
......@@ -61,7 +61,7 @@ class MonoideGC(GrapheDeComposition,Monoide):
C'est un graphe de composition à un objet."""
def __init__(self,nom:str = "MonoïdeGC"):
GrapheDeComposition.__init__(self,nom)
GrapheDeComposition.__init__(self,nom=nom)
Monoide.__init__(self,nom=nom)
def identite(self, objet:Any = None) -> ElementMonoideGC:
......@@ -121,6 +121,12 @@ class PetitMonoideAleatoire(MonoideGC):
associativite_verifiee = False
table[(a,table[(b,c)])] = table[(table[(a,b)],c)]
break
if (c,table[(a,b)]) in table and (c,a) in table:
if (table[(c,a)],b) not in table:
table[(table[(c,a)],b)] = table[(c,table[(a,b)])]
elif table[(table[(c,a)],b)] != table[(c,table[(a,b)])]:
associativite_verifiee = False
break
else:
continue
break
......@@ -170,21 +176,21 @@ class MonoideAleatoire(CategorieProduit,Monoide):
if DEBUG_MONOIDE_ALEATOIRE:
print("Simplification du nombre d'éléments à "+str(nb_elements))
petits_monoides = tuple(PetitMonoideAleatoire(x) for x in facteurs_premiers(nb_elements))
instance = super().__new__(cls,*petits_monoides)
instance = CategorieProduit.__new__(cls,*petits_monoides)
if DEBUG_MONOIDE_ALEATOIRE:
print("Fin de création d'un monoïde à "+str(nb_elements)+" éléments")
return instance
def __init__(self, nb_elements:int = random.randint(1,20), nom:str = "Monoïde aléatoire"):
CategorieProduit.__init__(self,*self)
Monoide.__init__(self,tuple(1 for i in range(len(self))),nom)
Monoide.__init__(self,nom)
def __ior__(self, objets:set) -> 'MonoideAleatoire':
if objets == {tuple(1 for i in range(len(self)))}:
CategorieLibre.__ior__(self,{tuple(1 for i in range(len(self)))})
return self
raise Exception("Tentative d'ajout d'un objet à un monoide : "+str(objets))
return CategorieLibre.__ior__(self,{tuple(1 for i in range(len(self)))})
elif objets == {1}:
return CategorieLibre.__ior__(self,{tuple(1 for i in range(len(self)))})
raise Exception("Tentative d'ajout d'objet dans un monoide "+str(objets))
def test_MonoideGC():
random.seed(22453)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment