Esempio n. 1
0
    def test_create_sample_pop(self):
        logger.debug("HEFT makespan {0}".format(heft(self.wf).makespan))
        pop = generate_population(self.wf, size=25, rng=self.rng, skip_limit=5)
        for soln in pop:
            self.assertEqual(soln.execution_order[-1].task.aft, soln.makespan)
        logger.debug("GA Initial Population")
        logger.debug("########################")
        for soln in pop:
            logger.debug(("Execution order: {0}".format(soln.execution_order)))
            logger.debug("Allocations: {0}".format(
                soln.list_all_allocations()))
            logger.debug("Makespan (s): {0}".format(
                calculate_fitness(['time'], soln)))
            logger.debug("Cost ($){0}".format(calculate_fitness(['cost'],
                                                                soln)))

            soln.fitness = calculate_fitness(['time', 'cost'], soln)
        fig, ax = plt.subplots()
        ax.set_xlim([90, 200])
        ax.set_ylim([100, 250])
        x = [soln.fitness['time'] for soln in pop]
        y = [soln.fitness['cost'] for soln in pop]
        ax.scatter(x, y, c='red')
        ax.set_axisbelow(True)
        ax.legend()
        ax.grid(True)
        plt.xlabel('Solution Runtime')
        plt.ylabel('Solution execution cost')
        plt.show()
Esempio n. 2
0
def ga(workflow,
       objectives,
       seed,
       mutation_probability,
       crossover_probability,
       generations=100,
       popsize=100):
    """
    This function runs a standard genetic algorithm, with basic elitism, and
    basic diversification. The algorithm:

        * Generates a population of Solutions, based on the workflow provided
        * For a given number of generations:

            * Create a child population (newgen)
            * While the newgen < pop
                * Select parents using binary tournament seleciton
                * Crossover the parents to children
                * mutate the children
                * calculate the fitness of each child
                * add new  children to newgen

            * Keep as many children as there are that outperform the parents

    :param mutation_probability:
    :param crossover_probability:
    :param workflow:
    :param objectives:
    :param seed:
    :param generations:
    :param popsize:
    :return:
    """

    pop = generate_population(workflow, seed, generations, popsize)
    for soln in pop:
        soln.fitness = fitness.calculate_fitness(objectives, soln)
    # binary_tournament(pop)
    generation = 0
    limit = False
    while generation < generations or limit:
        newgen = []
        while len(newgen) > len(pop):
            p1 = binary_tournament(pop)
            p2 = binary_tournament(pop)
            c1, c2 = crossover(p1, p2, seed)
            for c in [c1, c2]:
                mutation(c)
                fitness.calculate_fitness(c, objectives)
                newgen.append(c)
        generation += 1
        continue
    pass
Esempio n. 3
0
    def test_crossover(self):
        pop = generate_population(self.wf, size=25, rng=self.rng, skip_limit=5)
        for soln in pop:
            soln.fitness = calculate_fitness(['time', 'cost'], soln)

        random.seed(self.rng)

        p1 = binary_tournament(pop)
        self.assertSequenceEqual([0, 5, 3, 2, 1, 4, 7, 8, 6, 9],
                                 [t.task.tid for t in p1.execution_order])
        p2 = binary_tournament(pop)
        self.assertSequenceEqual([0, 5, 4, 1, 3, 2, 8, 6, 7, 9],
                                 [t.task.tid for t in p2.execution_order])
        c1, c2 = crossover(p1, p2, self.wf)
        p1order = [t.task.tid for t in p1.execution_order]
        c1order = [t.task.tid for t in c1.execution_order]
        self.assertSequenceEqual(p1order, c1order)
        for m in c1.machines:
            for allocation in c1.list_machine_allocations(m):
                if allocation.task.tid == 4:
                    self.assertEqual('cat1_m1', allocation.machine.id)
        for m in c2.machines:
            for allocation in c2.list_machine_allocations(m):
                if allocation.task.tid == 4:
                    self.assertEqual('cat0_m0', allocation.machine.id)
        self.assertNotEqual(p2.makespan, c2.makespan)

        fig, ax = plt.subplots()
        c1.fitness = calculate_fitness(['time', 'cost'], c1)
        c2.fitness = calculate_fitness(['time', 'cost'], c2)
        crossx = [c1.fitness['time'], c2.fitness['time']]
        crossy = [c1.fitness['cost'], c2.fitness['cost']]
        ax.scatter(crossx, crossy, c='green')
        x = [soln.fitness['time'] for soln in pop]
        y = [soln.fitness['cost'] for soln in pop]
        ax.grid(True)
        ax.set_xlim([90, 200])
        ax.set_ylim([100, 170])
        ax.scatter(x, y, c='red')
        ax.set_axisbelow(True)
        selectedx = [p1.fitness['time'], p2.fitness['time']]
        selectedy = [p1.fitness['cost'], p2.fitness['cost']]
        ax.scatter(selectedx, selectedy, c='blue')
        ax.legend()
        plt.xlabel('Solution Runtime')
        plt.ylabel('Solution execution cost')
        plt.show()
Esempio n. 4
0
 def test_binary_tournament(self):
     pop = generate_population(self.wf, size=25, rng=self.rng, skip_limit=5)
     for soln in pop:
         soln.fitness = calculate_fitness(['time', 'cost'], soln)
     compare_prob = 0.5
     parent1 = binary_tournament(pop, compare_prob, self.rng)
     logger.debug(parent1.execution_order)
     compare_prob = 0.7
     parent2 = binary_tournament(pop, compare_prob, self.rng)
     # parent2 = binary_tournament(pop, self.rng)
     logger.debug(parent2.execution_order)
     self.assertSequenceEqual([0, 5, 3, 4, 2, 1, 6, 8, 7, 9],
                              [t.task.tid for t in parent1.execution_order])
     logger.debug("Fitness: {0}".format(parent1.fitness))
     self.assertSequenceEqual([0, 5, 4, 1, 3, 2, 8, 6, 7, 9],
                              [t.task.tid for t in parent2.execution_order])
     logger.debug("Fitness: {0}".format(parent2.fitness))
Esempio n. 5
0
    def test_mutation(self):
        pop = generate_population(self.wf, size=25, rng=self.rng, skip_limit=5)
        for soln in pop:
            soln.fitness = calculate_fitness(['time', 'cost'], soln)

        random.seed(self.rng)

        p1 = binary_tournament(pop, self.rng, 0.6)
        self.assertSequenceEqual([0, 5, 3, 2, 1, 4, 7, 8, 6, 9],
                                 [t.task.tid for t in p1.execution_order])

        mutated_child = mutation(p1, self.wf, 'swapping', rng=self.rng)
        mutated_order_swapped = [0, 5, 3, 1, 7, 4, 2, 8, 6, 9]
        self.assertSequenceEqual(
            mutated_order_swapped,
            [alloc.task.tid for alloc in mutated_child.execution_order])
        selected_machine = None
        for machine in mutated_child.machines:
            if machine.id == 'cat2_m2':
                selected_machine = machine
        mutated_alloc = mutated_child.list_machine_allocations(
            selected_machine)
        self.assertSequenceEqual([7, 2, 9],
                                 [alloc.task.tid for alloc in mutated_alloc])
Esempio n. 6
0
    def test_overall(self):
        total_generations = 25
        crossover_probability = 0.5
        mutation_probability = 0.4
        popsize = 25
        pop = generate_population(self.wf,
                                  size=popsize,
                                  rng=self.rng,
                                  skip_limit=5)
        for soln in pop:
            soln.fitness = calculate_fitness(['time', 'cost'], soln)

        generations = []
        x = [soln.fitness['time'] for soln in pop]
        y = [soln.fitness['cost'] for soln in pop]
        weights = [200 * i for i in Counter(x).values() for j in range(i)]

        generations.append((x, y))
        parents1 = []
        parents2 = []
        for gen in range(total_generations):
            new_pop = []
            parent1 = None
            parent2 = None
            while len(new_pop) < len(pop):
                p1 = binary_tournament(pop, 0.5, self.rng)
                p2 = binary_tournament(pop, 0.5, self.rng)
                parent1 = p1
                parent2 = p2
                if random.random() < crossover_probability:
                    c1, c2 = crossover(p1, p2, self.wf)
                    new_pop.append(c1)
                    new_pop.append(c2)
                elif random.random() < mutation_probability:
                    c1 = mutation(p1, self.wf, 'swapping', rng=self.rng)
                    if c1 is None:
                        # The mutation didn't occur due to selection issue
                        continue
                    new_pop.append(c1)
                else:
                    new_pop.append(p1)
                    new_pop.append(p2)
                    continue
            tmp_pop = pop + new_pop
            for soln in tmp_pop:
                soln.fitness = calculate_fitness(['time', 'cost'], soln)
                # soln.total_fitness = soln.calc_total_fitness()
            tmp_pop.sort(key=lambda x: (x.fitness['time'], x.fitness['cost']))
            # tmp_pop.sort(key=lambda solution: solution.total_fitness)
            pop = tmp_pop[0:popsize]
            weights = [10 * i for i in Counter(x).values() for j in range(i)]
            x = [soln.fitness['time'] for soln in pop]
            y = [soln.fitness['cost'] for soln in pop]
            parent1_x = [parent1.fitness['time']]
            parent1_y = [parent1.fitness['cost']]
            parent2_x = [parent2.fitness['time']]
            parent2_y = [parent2.fitness['cost']]
            generations.append((x, y))
            parents1.append((parent1_x, parent1_y))
            parents2.append((parent2_x, parent2_y))
            plt.draw()
            plt.show()

        for soln in pop:
            logger.info(soln.fitness)

        fig, ax = plt.subplots()
        ax.set_xlim([80, 250])
        ax.set_ylim([100, 250])
        scatter = ax.scatter(generations[0][0],
                             generations[0][1],
                             c='blue',
                             alpha=.2,
                             label='New Pop')
        parent_scatter = ax.scatter(parents1[0][0],
                                    parents1[0][1],
                                    c='red',
                                    alpha=0.8,
                                    label='Parent 1')
        parent2_scatter = ax.scatter(parents2[0][0],
                                     parents1[0][1],
                                     c='red',
                                     alpha=0.8,
                                     label='Parent 2')
        ax.legend()

        def animate(i):
            scatter.set_offsets(np.c_[generations[i][0], generations[i][1]])
            parent_scatter.set_offsets(np.c_[parents1[i][0], parents1[i][1]])
            parent2_scatter.set_offsets(np.c_[parents2[i][0], parents2[i][1]])
            ax.set_xlabel('Runtime (s) \n Generation {0}'.format(i))
            ax.set_ylabel('Cost ($)')

        anim = FuncAnimation(fig, animate, interval=100, frames=25)

        plt.draw()

        anim.save('filename.mp4', fps=1)