예제 #1
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
예제 #2
0
def test_ajout_parallele_existant():
    g, p = test_ajout_fils_feuille_parallele()
    f1, f2 = p.fils
    f3 = Feuille()
    p.ajoutFils(f3, index=1)
    assert g.forme == [1, 3]
    assert f3.arbre is g
    assert f3.parent is p
    assert p.fils == [f1, f3, f2]
    return g, p
예제 #3
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
예제 #4
0
def test_ajout_serie_existant():
    g, p = test_ajout_fils_feuille_serie()
    f1, f2 = p.fils
    f3 = Feuille()
    p.ajoutFils(f3, index=1)
    assert g.forme == [1, 3]
    assert f3.arbre is g
    assert f3.parent is p
    assert p.fils == [f1, f3, f2]
    assert len(p.capacites) == 2
    assert g.nbCondensateurs == 3
    return g, p
예제 #5
0
def test_ajout_parallele_existant_rang_superieur():
    g, p = test_ajout_parallele_existant()
    f1, f2, f3 = p.fils
    f4 = Feuille()
    p2 = f3.ajoutFils(f4, forme="parallele")
    assert type(p2) == Parallele
    assert p2.fils == [f3, f4]
    assert p2.arbre is g
    assert f3.parent is p2
    assert f4.parent is p2
    assert p2.parent is p
    assert g.forme == [1, 3, 2]
    return g, p, p2
예제 #6
0
def test_ajout_fils_feuille_parallele():
    g, f1 = test_creation_arbre_minimal()
    f2 = Feuille()
    p = f1.ajoutFils(f2, forme="parallele")
    assert p.fils == [f1, f2]
    assert p.parent is None
    assert f1.parent == p
    assert f2.parent == p
    assert p.profondeur == 0
    assert f1.profondeur == 1
    assert f2.profondeur == 1
    assert g.forme == [1, 2]
    assert g.racine is p
    return g, p
예제 #7
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
예제 #8
0
def test_ajout_parallele_sur_serie():
    g, p = test_ajout_serie_existant()
    f1, f2, f3 = p.fils
    f4 = Feuille()
    p2 = f3.ajoutFils(f4, forme="parallele")
    assert type(p2) == Parallele
    assert p2.fils == [f3, f4]
    assert p2.arbre is g
    assert len(p.capacites) == 2
    assert type(p) is Serie
    assert g.nbCondensateurs == 3
    assert f3.parent is p2
    assert f4.parent is p2
    assert p2.parent is p
    assert g.forme == [1, 3, 2]
    return g, p, p2
예제 #9
0
def test_ajout_serie_existant_rang_superieur():
    g, p = test_ajout_serie_existant()
    f1, f2, f3 = p.fils
    f4 = Feuille()
    p2 = f3.ajoutFils(f4, forme="serie")
    assert type(p2) == Serie
    assert p2.fils == [f3, f4]
    assert p2.arbre is g
    assert len(p2.capacites) == 1
    assert len(p.capacites) == 2
    assert g.nbCondensateurs == 4
    assert f3.parent is p2
    assert f4.parent is p2
    assert p2.parent is p
    assert g.forme == [1, 3, 2]
    return g, p, p2
예제 #10
0
def test_ajout_fils_feuille_serie():
    g, f1 = test_creation_arbre_minimal()
    f2 = Feuille()
    p = f1.ajoutFils(f2, forme="serie")
    assert type(p) is Serie
    assert p.fils == [f1, f2]
    assert p.parent is None
    assert f1.parent == p
    assert f2.parent == p
    assert len(p.capacites) == 1
    assert g.nbCondensateurs == 2
    assert p.profondeur == 0
    assert f1.profondeur == 1
    assert f2.profondeur == 1
    assert g.forme == [1, 2]
    assert g.racine is p
    return g, p
예제 #11
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
예제 #12
0
    def mutation(self):
        """Affecte des mutations à certains individus de la population.

        Pour l'instant, on utilise un taux de mutation constant.
        """
        for individu in self.population:
            # On note si l'individu a été muté, auquel cas il faudra l'élaguer
            # si cela est demandé pour qu'il reste représentable sous forme
            # d'image.
            besoinElaguage = False
            # On peut muter un même individu plusieurs fois si le hasard le veut
            while random.random() < Genetique.CHANCE_DE_MUTATION:
                besoinElaguage = True
                profondeur = len(individu.forme)
                # On tire une profondeur à laquelle faire la mutation.
                choixProfondeur = random.randrange(profondeur)
                # Le nombre de noeuds à la profondeur donnée.
                largeur = individu.forme[choixProfondeur]
                # On choisit un individu au hasard parmi ceux à cette profondeur.
                choixLargeur = random.randrange(largeur)
                # On récupère l'individu tiré au hasard.
                noeud = individu.inspecter(choixProfondeur, choixLargeur)

                # On tire aléatoirement entre True et False avec équiprobabilité.
                action = random.random() > 0.5

                # L'action sera différente si le noeud tiré est une `Feuille` ou
                # non.
                if type(noeud) is Feuille:
                    # On va ajouter une feuille à ce noeud.
                    fils = Feuille()
                    if action:
                        # 50% de chances d'ajouter en série
                        noeud.ajoutFils(fils, forme="serie")
                    else:
                        # 50% de chances d'ajouter en parallèle
                        noeud.ajoutFils(fils, forme="parallele")
                else:
                    nombreFils = len(noeud.fils)

                    if action:
                        # 50% de chances d'ajouter un enfant.
                        # On tire un indice sur le lequel faire notre action
                        # dans 0, `nombreFils` inclu.
                        choixIndex = random.randrange(nombreFils + 1)
                        fils = Feuille()
                        noeud.ajoutFils(fils, index=choixIndex)
                    else:
                        # 50% de chances de supprimer un fils.
                        # On tire un indice sur le lequel faire notre action
                        # dans 0, `nombreFils` exclu.
                        choixIndex = random.randrange(nombreFils)
                        noeud.suppressionFils(index=choixIndex)

            if besoinElaguage:
                # On remet l'indicateur à 0 pour le prochain individu.
                besoinElaguage = False
                if Genetique.ELAGUAGE_FORCE:
                    # Si besoin, on élague l'individu obtenu
                    individu.elaguer(
                        largeur=self.imageLargeur, hauteur=self.imageHauteur
                    )
예제 #13
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
예제 #14
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
예제 #15
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
예제 #16
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()