# This file is part of EAP. # # EAP is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation, either version 3 of # the License, or (at your option) any later version. # # EAP is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with EAP. If not, see . import random import operator from deap import algorithms from deap import base from deap import creator from deap import tools from deap import gp def if_then_else(condition, out1, out2): return out1 if condition else out2 # Initialize Multiplexer problem input and output vectors MUX_SELECT_LINES = 3 MUX_IN_LINES = 2 ** MUX_SELECT_LINES MUX_TOTAL_LINES = MUX_SELECT_LINES + MUX_IN_LINES # input : [A0 A1 A2 D0 D1 D2 D3 D4 D5 D6 D7] for a 8-3 mux inputs = [[0] * MUX_TOTAL_LINES for i in range(2 ** MUX_TOTAL_LINES)] outputs = [None] * (2 ** MUX_TOTAL_LINES) for i in range(2 ** MUX_TOTAL_LINES): value = i divisor = 2 ** MUX_TOTAL_LINES # Fill the input bits for j in range(MUX_TOTAL_LINES): divisor /= 2 if value >= divisor: inputs[i][j] = 1 value -= divisor # Determine the corresponding output indexOutput = MUX_SELECT_LINES for j, k in enumerate(inputs[i][:MUX_SELECT_LINES]): indexOutput += k * 2**j outputs[i] = inputs[i][indexOutput] pset = gp.PrimitiveSet("MAIN", MUX_TOTAL_LINES, "IN") pset.addPrimitive(operator.and_, 2) pset.addPrimitive(operator.or_, 2) pset.addPrimitive(operator.not_, 1) pset.addPrimitive(if_then_else, 3) pset.addTerminal(1) pset.addTerminal(0) creator.create("FitnessMax", base.Fitness, weights=(1.0,)) creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMax, pset=pset) toolbox = base.Toolbox() toolbox.register("expr", gp.genFull, pset=pset, min_=2, max_=4) toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr) toolbox.register("population", tools.initRepeat, list, toolbox.individual) toolbox.register("lambdify", gp.lambdify, pset=pset) def evalMultiplexer(individual): func = toolbox.lambdify(expr=individual) return sum(func(*in_) == out for in_, out in zip(inputs, outputs)), toolbox.register("evaluate", evalMultiplexer) toolbox.register("select", tools.selTournament, tournsize=7) toolbox.register("mate", gp.cxOnePoint) toolbox.register("expr_mut", gp.genGrow, min_=0, max_=2) toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut) def main(): # random.seed(10) pop = toolbox.population(n=40) hof = tools.HallOfFame(1) stats = tools.Statistics(lambda ind: ind.fitness.values) stats.register("avg", tools.mean) stats.register("std", tools.std) stats.register("min", min) stats.register("max", max) algorithms.eaSimple(pop, toolbox, 0.8, 0.1, 40, stats, halloffame=hof) return pop, stats, hof if __name__ == "__main__": main()