[PYTHON] Deap Usage Note (OneMax)

Einführung

Dies ist ein Memo zur Verwendung von Deap. Hier wird das Memo am Beispiel von deap \ examples \ onemax_numpy.py beschrieben.

deap https://deap.readthedocs.io/en/master/

deap github https://github.com/DEAP/deap

OneMax? Es ist ein Problem, die Summe einer aus 0,1 bestehenden Zahlenfolge wie [1, 1, 1, 1, 0, 0, 0, 1, 1, 0] zu maximieren. ⇒ Die zu erhaltende Lösung ist [1, 1, 1, 1, 1, 1, 1, 1, 1, 1].

Im folgenden Code ist das Problem eine Zeichenfolge mit der Länge 100.

Code- und Ausführungsergebnisse

Fügen Sie den Code mit Notizen ein.

Code mit Notizen

my_onemax_numpy.py


import random
import numpy
from deap import algorithms
from deap import base
from deap import creator
from deap import tools

# parameter
n_gene = 100            #Anzahl der Gene pro Person
n_individuals = 300     #Anzahl der Personen pro Generation
n_generations = 1000    #Anzahl der Generationen

p_cxpb = 0.5            #Crossover-Rate (Anzahl der Crossing-Personen)
p_mutpb = 0.2           #Mutationsrate (Anzahl der zu mutierenden Personen)
p_mutate = 0.05         #Mutationswahrscheinlichkeit (Genmutationsrate)

n_tournsize = 3         #Turniergröße

def evalOneMax(individual):
    """Bewertungsfunktion onemax"""
    return sum(individual),

def init_creator():
    """Stellen Sie die Richtung der Zielfunktion ein"""
    #Eine objektive Funktion zur Bewertung, Maximierung der individuellen Anpassungsfähigkeit
    creator.create("FitnessMax", base.Fitness, weights=(1.0,))
    # numpy.Erben Sie die Ndarray-Klasse
    # fitness=creator.Erstellen Sie eine Einzelklasse mit einer Mitgliedsvariablen namens FitnessMax
    creator.create("Individual", numpy.ndarray, fitness=creator.FitnessMax)
    return creator

def my_gene_generator(min, max):
    """Gengenerierungsfunktion"""
    return random.randint(min, max)

def init_generator(creator):
    """Festlegen von Methoden zur Erzeugung von Genen, Individuen und Generationen"""
    toolbox = base.Toolbox()
    #Definition der Funktion, die das Gen produziert
    toolbox.register("attr_bool", my_gene_generator, 0, 1)
    #Definition der Funktion zur Generierung eines Individuums
    toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_bool, n_gene)
    #Definition der Funktion, die die Generierung generiert
    toolbox.register("population", tools.initRepeat, list, toolbox.individual)
    return toolbox

def operator_registration(toolbox):
    """Bewertungsfunktion / Strategieeinstellung"""
    toolbox.register("evaluate", evalOneMax)                                # evaluate =Bewertungsfunktion
    toolbox.register("mate", tools.cxTwoPoint)                              # mate =Zweipunktüberquerung
    toolbox.register("mutate", tools.mutFlipBit, indpb=p_mutate)            # mutate =Bitinversion
    toolbox.register("select", tools.selTournament, tournsize=n_tournsize)  # select = tournament(3)

def stats_register():
    """Einstellungen für die Statusdefinition"""
    stats = tools.Statistics(lambda ind: ind.fitness.values)
    stats.register("avg", numpy.mean)
    stats.register("std", numpy.std)
    stats.register("min", numpy.min)
    stats.register("max", numpy.max)
    return stats

def get_cxpoint(size):
    """2-Punkte-Einstellung für 2-Punkt-Kreuzung"""
    cxpoint1 = random.randint(1, size)
    cxpoint2 = random.randint(1, size - 1)
    if cxpoint2 >= cxpoint1:
        cxpoint2 += 1
    else: # Swap the two cx points
        cxpoint1, cxpoint2 = cxpoint2, cxpoint1
    return cxpoint1, cxpoint2

def cxTwoPointCopy(ind1, ind2):
    """2-Punkt-Frequenzweiche für Numpy"""
    size = min(len(ind1), len(ind2))
    cxpoint1, cxpoint2 = get_cxpoint(size)
    
    ind1[cxpoint1:cxpoint2], ind2[cxpoint1:cxpoint2] \
        = ind2[cxpoint1:cxpoint2].copy(), ind1[cxpoint1:cxpoint2].copy()
        
    return ind1, ind2

def set_seed(seed=42):
    random.seed(seed)

def main(toolbox):
    set_seed()

    #Generation der frühen Generation
    pop = toolbox.population(n=n_individuals)

    #Elite für Numpy=1 Strategie
    hof = tools.HallOfFame(1, similar=numpy.array_equal)

    #Statistik Definition
    stats = stats_register()

    # main loop
    algorithms.eaSimple(pop, toolbox, cxpb=p_cxpb, mutpb=p_mutpb, ngen=n_generations, stats=stats,
                        halloffame=hof)

    #Anzeige der besten Personen
    best_ind = tools.selBest(pop, 1)[0]
    print("Best individual is \n Eval:\n  %s, \n Gene:\n  %s" % (best_ind.fitness.values, best_ind))

    return pop, stats, hof


if __name__ == "__main__":
    #Stellen Sie die Richtung der Zielfunktion ein
    creator = init_creator()

    #Festlegen von Methoden zur Erzeugung von Genen, Individuen und Generationen
    toolbox = init_generator(creator)

    #Einstellung der Evolutionsmethode
    operator_registration(toolbox)

    #Hauptroutine
    main(toolbox)

Ausführungsergebnis

Ausführungsergebnis
gen     nevals  avg     std     min     max
0       300     49.88   4.82344 36      64
1       172     54.27   3.60792 45      68
2       181     57.24   3.32    47      68 
・ ・ ・
987     183     98.9767 2.3642  89      100
988     171     99.1467 2.02941 89      100
989     192     99.0567 2.26424 90      100
990     176     99.1167 2.12047 88      100
991     183     99.2733 1.94901 90      100
992     164     98.97   2.30704 90      100
993     178     99.03   2.0581  90      100
994     188     98.9767 2.24264 89      100
995     174     98.95   2.3211  86      100
996     177     98.83   2.33833 90      100
997     186     99.0367 2.15453 89      100
998     177     98.9833 2.16095 91      100
999     175     98.9933 2.25683 90      100
1000    181     98.8967 2.23443 89      100
Best individual is
 Eval:
  (100.0,),
 Gene:
  [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]

Wo man stecken bleibt

① Ich weiß nicht, wie ich die Richtung (Maximierung / Minimierung) der Bewertungsfunktion bestimmen soll.

creator.py


#Eine objektive Funktion zur Bewertung, Maximierung der individuellen Anpassungsfähigkeit
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
#Es sind zwei Zielfunktionen zu bewerten: Die erste besteht darin, die Anpassungsfähigkeit zu minimieren und die zweite darin, die Anpassungsfähigkeit zu maximieren.
creator.create("FitnessMulti", base.Fitness, weights=(-1.0, 1.0))

② Wie generieren und bewerten Sie Gene? -Registrieren Sie die generierte Funktion in der Toolbox Hier wird eine Funktion namens my_gene_generator verwendet, die zufällig 0 oder 1 generiert. Registrieren Sie sich mit dem Namen "attr_bool" in der Toolbox

gene_generator.py


def my_gene_generator(min, max):
    """Gengenerierungsfunktion"""
    return random.randint(min, max)

def init_generator(creator):
    """Festlegen von Methoden zur Erzeugung von Genen, Individuen und Generationen"""
    toolbox = base.Toolbox()
    #Definition der Funktion, die das Gen produziert
    toolbox.register("attr_bool", my_gene_generator, 0, 1)

・ Registrieren Sie die Auswertungsfunktion in der Toolbox Hier eine Funktion namens evalOneMax Registrieren Sie sich mit dem Namen "evaluieren" in der Toolbox

gene_eval.py


def evalOneMax(individual):
    """Bewertungsfunktion onemax"""
    return sum(individual),

def operator_registration(toolbox):
    """Bewertungsfunktion / Strategieeinstellung"""
    toolbox.register("evaluate", evalOneMax) # evaluate =Bewertungsfunktion

③ Wo ist die Hauptschleife? · Hier

algorithms.eaSimple(pop, toolbox, cxpb=p_cxpb, mutpb=p_mutpb, ngen=n_generations, stats=stats, halloffame=hof)

Recommended Posts

Deap Usage Note (OneMax)
Verwendungshinweise für virtualenv Basic-Befehle
Benutzerfreundliche Hinweise für Anaconda (conda)
BESS Development Memo Teil 01: BESS-Installation und grundlegende Verwendung