示例#1
0
def test_simulation_score():
    cInt = 0.5
    T = list(range(10))
    tExt = [1 for i in range(10)]
    tInt = list(range(10))
    pInt = [0 for i in range(10)]
    g = Arbre(cInt, T, tExt, tInt, pInt)
    f1 = g.racine
    f2 = Feuille()
    sA = f1.ajoutFils(f2, forme="serie")
    f3 = Feuille()
    sA.ajoutFils(f3, index=2)
    f4 = Feuille()
    pB = f3.ajoutFils(f4, forme="parallele")
    f5 = Feuille()
    sC = f3.ajoutFils(f5, forme="serie")
    f6 = Feuille()
    sC.ajoutFils(f6, index=0)
    f7 = Feuille()
    sD = f2.ajoutFils(f7, forme="serie")
    f8 = Feuille()
    pE = f2.ajoutFils(f8, forme="parallele")
    f9 = Feuille()
    pE.ajoutFils(f9, index=2)
    s = g.score()
    assert s < 0
    # Il n'y a rien d'autre à tester pour score, le code est transparent.
    return g
示例#2
0
def test_simulation_coherence():
    cInt = 0.5
    T = list(range(10))
    tExt = [1 for i in range(10)]
    tInt = list(range(10))
    pInt = [0 for i in range(10)]
    g = Arbre(cInt, T, tExt, tInt, pInt)
    f1 = g.racine
    f2 = Feuille()
    sA = f1.ajoutFils(f2, forme="serie")
    f3 = Feuille()
    sA.ajoutFils(f3, index=2)
    f4 = Feuille()
    pB = f3.ajoutFils(f4, forme="parallele")
    f5 = Feuille()
    sC = f3.ajoutFils(f5, forme="serie")
    f6 = Feuille()
    sC.ajoutFils(f6, index=0)
    f7 = Feuille()
    sD = f2.ajoutFils(f7, forme="serie")
    f8 = Feuille()
    pE = f2.ajoutFils(f8, forme="parallele")
    f9 = Feuille()
    pE.ajoutFils(f9, index=2)
    sol = g.simulation()
    x, y = sol.t, sol.y[0]
    assert sol.success
    assert (x == np.array(T)).all()
    for temperature in sol.y:
        assert temperature[0] == tExt[0]
    assert len(x) == len(y)
    # C'est à peu près tout ce que l'on peut vérifier simplement sur la
    # cohérence de la simulation...
    return g
示例#3
0
def test_complexe_creation():
    g = Arbre(None, None, None, None, None)
    f1 = g.racine
    f2 = Feuille()
    sA = f1.ajoutFils(f2, forme="serie")
    f3 = Feuille()
    sA.ajoutFils(f3, index=0)
    f4 = Feuille()
    pB = f1.ajoutFils(f4, forme="parallele")
    f5 = Feuille()
    pB.ajoutFils(f5, index=1)
    f6 = Feuille()
    sC = f2.ajoutFils(f6, forme="serie")
    # Tests de généalogie
    assert g.forme == [1, 3, 5]
    assert g.racine is sA
    assert sA.parent is None
    assert sA.fils == [f3, pB, sC]
    assert pB.parent is sA
    assert f3.parent is sA
    assert sC.parent is sA
    assert pB.fils == [f1, f5, f4]
    assert f1.parent is pB
    assert f5.parent is pB
    assert f4.parent is pB
    assert sC.fils == [f2, f6]
    assert f2.parent is sC
    assert f6.parent is sC
    # Tests sur les capacités
    assert len(sA.capacites) == 2
    assert len(sC.capacites) == 1
    assert g.nbCondensateurs == 4
    return g
示例#4
0
def test_creationSimulation_complexe():
    cInt = 0.5
    T = [float(i) for i in range(10)]
    tExt = [1 for i in range(10)]
    tInt = list(range(10))
    pInt = [0 for i in range(10)]
    g = Arbre(cInt, T, tExt, tInt, pInt)
    f1 = g.racine
    f2 = Feuille()
    sA = f1.ajoutFils(f2, forme="serie")
    f3 = Feuille()
    sA.ajoutFils(f3, index=2)
    f4 = Feuille()
    pB = f3.ajoutFils(f4, forme="parallele")
    f5 = Feuille()
    sC = f3.ajoutFils(f5, forme="serie")
    f6 = Feuille()
    sC.ajoutFils(f6, index=0)
    f7 = Feuille()
    sD = f2.ajoutFils(f7, forme="serie")
    f8 = Feuille()
    pE = f2.ajoutFils(f8, forme="parallele")
    f9 = Feuille()
    pE.ajoutFils(f9, index=2)
    # Oui, c'est un exemple assez compliqué, c'est parce que j'essaie de tester
    # l'implémentation de curseur, qui n'intervient que dans des cas assez
    # importants.
    cA, cB = sA.capacites
    cC = sD.capacites[0]
    cD, cE = sC.capacites
    # Pour proposer les solutions qui suivent j'ai suivi l'algorithme à la main
    # sur un tableau.
    solA = np.array([
        [f4.H + f5.H, 0, -f4.H, 0, 0, -f5.H],
        [0, f1.H + f2.H + f8.H + f9.H, 0, -f2.H - f8.H - f9.H, 0, 0],
        [-f4.H, 0, f4.H + f6.H + f7.H, -f7.H, -f6.H, 0],
        [0, -f2.H - f8.H - f9.H, -f7.H, f2.H + f7.H + f8.H + f9.H, 0, 0],
        [0, 0, -f6.H, 0, f3.H + f6.H, -f3.H],
        [-f5.H, 0, 0, 0, -f3.H, f3.H + f5.H],
    ])
    solB = np.array([[0, 1], [-f1.H, 0], [0, 0], [0, 0], [0, 0], [0, 0]])
    solC = np.diag([1 / cInt, 1 / cA, 1 / cB, 1 / cC, 1 / cD, 1 / cE])
    A, B, C = g.creationSimulation()
    assert (A == solA).all()
    assert (B == solB).all()
    assert (C == solC).all()
    return g
示例#5
0
def test_creationSimulation_minimal():
    Cint = 0.5
    T = list(range(10))
    Text = [1 for i in range(10)]
    Tint = list(range(10))
    Pint = [0 for i in range(10)]
    g = Arbre(0.5, T, Text, Tint, Pint)
    f = g.racine
    A, B, C = g.creationSimulation()
    assert np.shape(A) == (1, 1)
    assert A[0, 0] == f.H
    assert np.shape(C) == (1, 1)
    assert C[0, 0] == 2
    assert np.shape(B) == (1, 2)
    assert B[0, 0] == -f.H
    assert B[0, 1] == 1
    return g
示例#6
0
def test_creation_arbre_minimal():
    g = Arbre(None, None, None, None, None)
    assert g.forme == [1]
    f = g.racine
    assert f.arbre == g
    assert f.parent is None
    assert f.profondeur == 0
    assert g.forme == [1]
    return g, f
示例#7
0
def test_creationSimulation_parallele_simple():
    Cint = 0.5
    T = list(range(10))
    Text = [1 for i in range(10)]
    Tint = list(range(10))
    Pint = [0 for i in range(10)]
    g = Arbre(0.5, T, Text, Tint, Pint)
    f1 = g.racine
    f2 = Feuille()
    p = f1.ajoutFils(f2, forme="parallele")
    f3 = Feuille()
    p.ajoutFils(f3, index=2)
    A, B, C = g.creationSimulation()
    assert np.shape(A) == (1, 1)
    assert A[0, 0] == f1.H + f2.H + f3.H
    assert np.shape(C) == (1, 1)
    assert C[0, 0] == 2
    assert np.shape(B) == (1, 2)
    assert B[0, 0] == -(f1.H + f2.H + f3.H)
    assert B[0, 1] == 1
    return g
示例#8
0
def test_creationSimulation_serie_simple():
    cInt = 0.5
    T = np.array(list(range(10)))
    tExt = np.array([1 for i in range(10)])
    tInt = np.array(list(range(10)))
    pInt = np.array([0 for i in range(10)])
    g = Arbre(cInt, T, tExt, tInt, pInt)
    f1 = g.racine
    f2 = Feuille()
    p = f1.ajoutFils(f2, forme="serie")
    f3 = Feuille()
    p.ajoutFils(f3, index=2)
    c1, c2 = p.capacites
    A, B, C = g.creationSimulation()
    assert (A == np.array([
        [f3.H, 0, -f3.H],
        [0, f1.H + f2.H, -f2.H],
        [-f3.H, -f2.H, f2.H + f3.H],
    ])).all()
    assert (C == np.array([[1 / cInt, 0, 0], [0, 1 / c1, 0], [0, 0,
                                                              1 / c2]])).all()
    print(B)
    assert (B == np.array([[0, 1], [-f1.H, 0], [0, 0]])).all()
    return g
示例#9
0
    def ameliorerPopulation(self):
        """Effectue une génération de l'algorithme génétique.

        Renvoie quelques valeurs qui sont utiles pour l'affichage."""

        # SELECTION
        if not Genetique.SILENCE:
            print("Selection")
        self.population, scores = self.selection()

        # On crée une copie du meilleur individu de la génération
        # (il risque d'être modifié par mutation).
        meilleurArbre = self.population[-1].racine.sousArbre()
        meilleurIndividu = Arbre(
            self.Cint,
            self.T,
            self.Text,
            self.Tint,
            self.Pint,
            racine=meilleurArbre,
        )

        # AMELIORATION
        if self.autoencodeur is not None:
            if not Genetique.SILENCE:
                print("Amelioration")
            self.autoencodeur.ameliorerArbres(self.population)

        # MUTATION
        if not Genetique.SILENCE:
            print("Mutation")
        self.mutation()

        # FUSION
        if not Genetique.SILENCE:
            print("Fusion")
        self.population += self.fusion()

        # On renvoie des valeurs qui pourront être utiles pour l'affichage
        # (le meilleur individu et son score).
        return meilleurIndividu, scores[-1]
示例#10
0
    def individuAleatoire(self):
        """Génère un individu aléatoire.

        Notes
        -----
        graineAlternance : float
            `graineAlternance` est une graine qui détermine si l'alternance
            devrait commencer par des liaisons séries ou parallèles.
            `graineAlternance` peut prendre les valeurs
            -Genetique.BIAIS_ALTERNANCE ou Genetique.BIAIS_ALTERNANCE.
        hasard : bool
            `hasard` a 50% de chances d'être vrai et 50% d'être faux et nous
            permet de choisir entre ajouter un fils en série et en parallèle.
            `graineAlternance` permet de favoriser tantôt les liaisons séries,
            tantôt les liaisons parallèles.
        largeurAutorisee : int
            Pour éviter des configurations absurdes, on force l'arbre à avoir
            une forme un peu conique (c'est-à-dire à n'avoir pas trop de fils
            sur les premières générations).
        """
        graineAlternance = (
            GenerateurArbres.BIAIS_ALTERNANCE + 2 *
            (random.random() > 0.5) * GenerateurArbres.BIAIS_ALTERNANCE)

        # On initialise l'individu que l'on va créer.
        individu = Arbre(self.Cint, self.T, self.Text, self.Tint, self.Pint)
        # On tire aléatoirement la profondeur qu'aura notre individu.
        profondeur = random.randint(1, GenerateurArbres.PROFONDEUR_MAX_ARBRE)

        # On crée itérativement tous les niveaux de notre arbre.
        for i in range(profondeur - 1):
            # cf. docstring pour `largeurAutorisee`.
            # Notez que la largeur réelle d'une couche de l'arbre dépasse
            # souvent la largeur maximale autorisée. En effet, lorsque l'on
            # ajoute un fils a une feuille, cette dernière descend dans la
            # nouvelle profondeur. On se retrouve donc avec deux noeuds de plus
            # à la nouvelle profondeur au lieu d'un.
            largeurAutorisee = min(GenerateurArbres.LARGEUR_MAX_ARBRE,
                                   3 * (i + 1))
            # On détermine au hasard la largeur de la profondeur i+1.
            largeur = random.randint(1, largeurAutorisee)

            # On choisit (avec remise) les noeuds de la génération i qui
            # accueilleront des enfants à la génération i+1.
            indicesChoisis = random.choices(population=range(
                individu.forme[i]),
                                            k=largeur)

            # On ajoute les enfants aux parents désignés.
            for k in indicesChoisis:
                # Le noeud auquel on doit ajouter un enfant. Un même indice peut
                # être tiré plusieurs fois.
                parent = individu.inspecter(i, k)
                enfant = Feuille()
                if type(parent) is Feuille:
                    # cf. docstring pour `hasard`.
                    hasard = random.random() > (0.5 + graineAlternance)
                    if hasard:
                        parent.ajoutFils(enfant, forme="serie")
                    else:
                        parent.ajoutFils(enfant, forme="parallele")
                else:
                    # On tire aléatoirement l'index où l'on va insérer le nouvel
                    # enfant parmi les enfants préexistants du parent. Le +1
                    # correspond au fait que l'on peut insérer un enfant tout à
                    # la fin de la liste des descendants du parent.
                    indexAleatoire = random.randrange(len(parent.fils) + 1)
                    # On insère le nouvel enfant.
                    parent.ajoutFils(enfant, index=indexAleatoire)
            # On alterne le biais entre liaisons séries et parallèle.
            graineAlternance *= -1

        # Si on a demandé un élaguage automatique, alors on tronque l'individu
        # pour qu'il soit représentable sous forme d'image.
        if self.elaguageForce:
            individu.elaguer(largeur=self.imageLargeur,
                             hauteur=self.imageHauteur)
        # On renvoie la liste ainsi formée.
        return individu
示例#11
0
    def fusion(self):
        """Fusionne les individus.

        On ajoutera tous les enfants d'un seul coup à la fin pour éviter de
        faire une fusion sur un enfant qui vient d'être créé.
        """
        enfants = []
        # On calcule le nombre d'individus qu'il nous reste à produire pour
        # compléter la génération suivante.
        populationManquante = self.taillePopulation - len(self.population)

        for i in range(populationManquante):
            # On tire deux individus dans la population sans faire de remise.
            pere, mere = random.sample(self.population, k=2)

            # Il nous faut à présent déterminer la profondeur maximale jusqu'à
            # laquelle les deux parents ont une forme commune.
            profondeurSemblable = 0
            # On teste toutes les profondeurs et on s'arrète à la première non
            # commune.
            for j in range(min(len(pere.forme), len(mere.forme))):
                # print(f"{j} {pere.forme[j]} {mere.forme[j]}")
                if pere.forme[j] != mere.forme[j]:
                    if j == 0:
                        print(pere.forme)
                        print(mere.forme)
                    profondeurSemblable = j - 1
                    break

            # Le sommet qui va nous servir à créer le nouvel enfant
            sommet = None
            # On tire au hasard le parent dont on va récupérer le sommet.
            choixSommet = random.random() > 0.5
            if choixSommet:
                sommet = mere.racine.sousArbre()
            else:
                sommet = pere.racine.sousArbre()

            # On crée l'objet `Arbre` qui acueille le sommet. Le constructeur
            # de `Arbre` dispose d'une syntaxe spéciale concue pour attacher
            # une racine direcetement.
            enfant = Arbre(
                self.Cint,
                self.T,
                self.Text,
                self.Tint,
                self.Pint,
                racine=sommet,
            )

            # Le nombre de noeuds qui vont devoir être fusionnés entre parent et
            # enfant.
            largeur = enfant.forme[profondeurSemblable]
            # On réalise l'étape de fusion pour tous les noeuds de
            # `profondeurSemblable`.
            for j in range(largeur):
                # On récupère le noeud correspondant pour la mere, le pere et
                # l'enfant.
                noeudPere = pere.inspecter(profondeurSemblable, j)
                noeudMere = mere.inspecter(profondeurSemblable, j)
                noeudEnfant = enfant.inspecter(profondeurSemblable, j)
                # On crée la liste de tous les nouveaux enfants possibles.
                # Un détail d'implémentation : en théorie on devrait faire un
                # choix parmi les `sousArbre` crées à partir des enfants de pere
                # et mere, mais créer un `sousArbre` peut être un peu long, donc
                # en créer qui ne seront pas utilisés est une perte de temps.
                # Au lieu de cela, on va faire notre choix sur les enfants
                # directs de pere et mere, puis calculer le `sousArbre` des
                # enfants élus, ce qui est plus efficace mais amène au même
                # résultat.
                if type(noeudEnfant) is Feuille:
                    # Si on tombe sur une feuille, on ne peut évidemment pas y
                    # ajouter de fils.
                    continue
                filsPotentiels = noeudPere.fils + noeudMere.fils
                # On détermine le nombre d'enfants à donner à l'enfant.
                nombreFils = len(filsPotentiels) // 2 + 1
                # On choisit nombreFils éléments parmi filsPotentiels sans
                # remise.
                filsChoisis = random.sample(filsPotentiels, k=nombreFils)
                # On calcule le sousArbre des enfants choisis avant de l'ajouter
                # à l'enfant.
                sousArbresChoisis = [fils.sousArbre() for fils in filsChoisis]
                # Enfin, on ajoute les nouveaux sous arbres créés sous le noeud
                # choisi de enfant.
                noeudEnfant.substituerEnfants(sousArbresChoisis)

            if Genetique.ELAGUAGE_FORCE:
                # Si besoin, on élague l'enfant obtenu pour qu'il soit
                # représentable sous forme d'image.
                enfant.elaguer(
                    largeur=self.imageLargeur, hauteur=self.imageHauteur
                )

            # On ajoute l'arbre créé à la population de descendants.
            enfants.append(enfant)
        # On renvoie la liste des enfants créés pour qu'ils soient ajoutés à la
        # population.
        return enfants
示例#12
0
def test_representation_image_complexe():
    len = 30
    Cint = Coefficients.muC
    T = list(range(len))
    Text = list(range(len))
    Tint = [-1.4 * (i / len) for i in range(len)]
    Pint = [0 for i in range(len)]
    # scores = []
    iterations = 100
    # compteur = 0
    # for i in range(iterations):
    #     try:
    #         g = Arbre(Cint, T, Text, Tint, Pint)
    #         f1 = g.racine
    #         f2 = Feuille()
    #         sA = f1.ajoutFils(f2, forme="serie")
    #         f3 = Feuille()
    #         sA.ajoutFils(f3, index=0)
    #         f4 = Feuille()
    #         pB = f1.ajoutFils(f4, forme="parallele")
    #         f5 = Feuille()
    #         pB.ajoutFils(f5, index=1)
    #         f6 = Feuille()
    #         sC = f2.ajoutFils(f6, forme="serie")
    #         scores.append(g.score())
    #         compteur+=1
    #         print("score=", scores[-1])
    #     except SimulationException as e:
    #         print(str(e))
    # plt.plot(range(50), sorted(scores)[-50:])
    # plt.show()
    # dist = []
    for i in range(iterations):
        g = Arbre(Cint, T, Text, Tint, Pint)
        f1 = g.racine
        f2 = Feuille()
        sA = f1.ajoutFils(f2, forme="serie")
        f3 = Feuille()
        sA.ajoutFils(f3, index=0)
        f4 = Feuille()
        pB = f1.ajoutFils(f4, forme="parallele")
        f5 = Feuille()
        pB.ajoutFils(f5, index=1)
        f6 = Feuille()
        sC = f2.ajoutFils(f6, forme="serie")
        image = g.ecritureImage(largeur=100, hauteur=100)
        print("(1) score=", g.score())
        ancienneImage = image.copy()
        # R, V, B = image[:,:,0], image[:,:,1], image[:,:,2]
        # plt.imshow(image)
        # plt.show()
        # plt.imshow(R)
        # plt.colorbar()
        # plt.show()
        # plt.imshow(V)
        # plt.colorbar()
        # plt.show()
        # plt.imshow(B)
        # plt.colorbar()
        # plt.show()
        g.lectureImage(image)
        # print(i)
        print("(2) score=", g.score())
        print()