Beispiel #1
0
def main():
    matrix = [[0 for x in range(SCREEN_WIDTH)] for y in range(SCREEN_HEIGHT)]

    visualizer = Visualizer(clock_speed=30)
    visualizer.draw_grid()
    visualizer.update()

    positions = visualizer.user_choose_start_end()
    print(positions)

    a_star_search = AStarSearch(node_matrix=matrix,
                                start=positions[0],
                                end=positions[1],
                                diagonal_allowed=True)

    visualizer.search_algo = a_star_search

    obstacles = visualizer.user_choose_obstacle()
    for pos in obstacles:
        node = AStarNode(pos, None)
        a_star_search.update_node_closed(node, Colors.dark_red)
    visualizer.draw_buffered_nodes()

    visualizer.run_algo()
Beispiel #2
0
class ACO(object):
    '''
    Perform ACO on the maze.
    '''

    iterations = 15

    evaporation = 0.1

    # Initialize Q to high value
    Q = 10000

    # update Q using the minimum path length  as value.
    update_Q = False

    ant_count = 10

    # Number of steps an ant may wander before it is terminated for that
    # iterations.
    ant_max_steps = 10000
    update_max_steps = False

    # Wether or not to optimize the trails of the ants after they found the end.
    optimize_ants = True

    visualize = True
    quiet = False

    multiprocessing = True

    do_reconnaissance = 4000

    maze_elimination = True

    def __init__(self, maze, **settings):
        self.maze = maze
        self.ants = []

        for name, value in settings.items():
            setattr(self, name, value)

        if self.visualize:
            self.visualizer = Visualizer(maze)
            self.visualizer.save('0_initial.png')

        if self.multiprocessing:
            self.pool = multiprocessing.Pool()

    def delta_matrix(self, ant):
        delta_tau = np.zeros((self.maze.height, self.maze.width))

        unique_positions = list(set(ant.position_list))
        delta_tau_k = self.Q / len(unique_positions)

        for x, y in unique_positions:
            delta_tau[y][x] += delta_tau_k

        return delta_tau

    def reconnaissance(self, iterations=1):
        maze = self.maze
        if self.do_reconnaissance < 1:
            return maze

        print 'performing reconnaissance with %d ants for %d steps in %d iterations' % (
            self.ant_count, self.do_reconnaissance, iterations)

        disabled = set()
        start_time = time.time()
        for iteration in range(iterations):
            ants = []
            for i in range(self.ant_count):
                ants.append(Ant(maze, maze.start))

            results = self.pool.map_async(
                ant_loop_apply,
                itertools.izip(ants, [self.do_reconnaissance] *
                               self.ant_count)).get(999999)

            for ant in results:
                for disable in ant.disable_positions:
                    maze.disable_at(disable)
                    disabled.add(disable)

        print 'Reconnaissance done, %d cells disabled in %0.2fs' % (
            len(disabled), time.time() - start_time)
        return maze

    def run(self):
        if not self.quiet:
            print 'starting with ACO with %d ants for %d iterations' % (
                self.ant_count, self.iterations)
        maze = self.maze

        self.iteration_best_trail = []

        # initialize ants
        for k in range(self.ant_count):
            self.ants.append(Ant(maze, maze.start))

        global_best = iteration_best = None
        for i in range(self.iterations):
            if not self.quiet:
                print '\nIteration: %d, Q: %d, max_steps: %d' % (
                    i, self.Q, self.ant_max_steps)

            if self.multiprocessing:
                # Make ants do their steps.
                self.ants = self.pool.map_async(
                    ant_loop_apply,
                    itertools.izip(self.ants, [self.ant_max_steps] *
                                   self.ant_count)).get(9999999)
            else:
                print 'Stepping...'
                for ant in self.ants:
                    i = 0
                    while not ant.done and len(ant.trail) < self.ant_max_steps:
                        ant.step()

                        i += 1
                        if i % 1000 == 1:
                            self.visualizer.update('stepping: %d' % i)

                    if not ant.done:
                        print 'moving to next ant, this one stuck in', ant.position

            done_ants = [a for a in self.ants if a is not None and a.done]

            if not self.quiet:
                print '%d out of %d ants finished within %d steps.' % (
                    len(done_ants), self.ant_count, self.ant_max_steps)

            if self.optimize_ants:
                # optimize the trails for these ants
                opts = []
                for ant in done_ants:
                    opts.append(ant.optimize_trail(quiet=self.quiet))
                if not self.quiet:
                    print 'Optimisation reduced trail langth with an average of', mean(
                        opts)

            # disable the dead ends found by the ant
            if self.maze_elimination:
                for ant in self.ants:
                    if ant is not None:
                        for p in ant.disable_positions:
                            self.maze.disable_at(p)

            # select the best ant:
            if len(done_ants) > 0:
                iteration_best = min(done_ants)

                # if global_best becomes invalid, forget it.
                # if global_best is not None:
                #     global_best.maze = self.maze
                #     if not global_best.is_valid():
                #         global_best = None
                #         if not self.quiet:
                #             print 'Forgot global best!'

                if global_best is None:
                    global_best = iteration_best.clone()
                else:
                    global_best = min([iteration_best, global_best]).clone()

            # update pheromone in the maze, for unique positions
            deltas = np.zeros((self.maze.height, self.maze.width))
            if global_best is not None:
                deltas = self.delta_matrix(global_best)

            if iteration_best is not None and global_best is not iteration_best:
                deltas += self.delta_matrix(iteration_best)

            # only update if iteration returned something.
            if iteration_best is not None:
                self.iteration_best_trail.append(len(iteration_best.trail))
            else:
                self.iteration_best_trail.append(None)

            maze.update_tau(delta_tau=deltas, evaporation=self.evaporation)

            # update ant_max_steps to the max value of this iteration
            if len(done_ants) > 3:
                if self.update_max_steps:
                    try:
                        self.ant_max_steps = min(
                            self.ant_max_steps,
                            max(
                                len(x.trail) for x in done_ants
                                if len(x.trail) < self.ant_max_steps))
                    except:
                        pass
                if self.update_Q:
                    self.Q = min(min(len(x.trail) for x in self.ants), self.Q)

            if not self.quiet:
                if iteration_best is not None and global_best is not None:
                    print 'Best ant: %d, iteration best: %d' % (len(
                        global_best.trail), len(iteration_best.trail))
                else:
                    print 'None of the ants finished stepping'

            # reset ants
            for ant in self.ants:
                ant.reset(maze)

            if self.visualize:
                self.visualizer.update('Pheromone level iteration %d' % i)
                self.visualizer.save('%dth_iteration.png' % i)

        if self.multiprocessing:
            self.interrupt()

        self.global_best = global_best
        return global_best

    def interrupt(self):
        if self.multiprocessing:
            self.pool.close()
            self.pool.join()

    def get_first_iteration_with_best_trail(self):
        trail_length = len(self.global_best.trail)

        for i, val in enumerate(self.iteration_best_trail):
            if val == trail_length:
                return i
class ACO(object):
    '''
    Perform ACO on the maze.
    '''

    iterations = 15

    evaporation = 0.1

    # Initialize Q to high value
    Q = 10000

    # update Q using the minimum path length  as value.
    update_Q = False

    ant_count = 10

    # Number of steps an ant may wander before it is terminated for that
    # iterations.
    ant_max_steps = 10000
    update_max_steps = False

    # Wether or not to optimize the trails of the ants after they found the end.
    optimize_ants = True

    visualize = True
    quiet = False

    multiprocessing = True

    do_reconnaissance = 4000

    maze_elimination = True

    def __init__(self, maze, **settings):
        self.maze = maze
        self.ants = []

        for name, value in settings.items():
            setattr(self, name, value)

        if self.visualize:
            self.visualizer = Visualizer(maze)
            self.visualizer.save('0_initial.png')

        if self.multiprocessing:
            self.pool = multiprocessing.Pool()

    def delta_matrix(self, ant):
        delta_tau = np.zeros((self.maze.height, self.maze.width))

        unique_positions = list(set(ant.position_list))
        delta_tau_k = self.Q / len(unique_positions)

        for x, y in unique_positions:
            delta_tau[y][x] += delta_tau_k

        return delta_tau

    def reconnaissance(self, iterations=1):
        maze = self.maze
        if self.do_reconnaissance < 1:
            return maze

        print 'performing reconnaissance with %d ants for %d steps in %d iterations' % (
            self.ant_count, self.do_reconnaissance, iterations
        )

        disabled = set()
        start_time = time.time()
        for iteration in range(iterations):
            ants = []
            for i in range(self.ant_count):
                ants.append(Ant(maze, maze.start))

            results = self.pool.map_async(
                ant_loop_apply, itertools.izip(ants, [self.do_reconnaissance] * self.ant_count)
            ).get(999999)

            for ant in results:
                for disable in ant.disable_positions:
                    maze.disable_at(disable)
                    disabled.add(disable)

        print 'Reconnaissance done, %d cells disabled in %0.2fs' % (
            len(disabled),
            time.time() - start_time
        )
        return maze

    def run(self):
        if not self.quiet:
            print 'starting with ACO with %d ants for %d iterations' % (
                self.ant_count, self.iterations
            )
        maze = self.maze

        self.iteration_best_trail = []

        # initialize ants
        for k in range(self.ant_count):
            self.ants.append(Ant(maze, maze.start))

        global_best = iteration_best = None
        for i in range(self.iterations):
            if not self.quiet:
                print '\nIteration: %d, Q: %d, max_steps: %d' % (i, self.Q, self.ant_max_steps)

            if self.multiprocessing:
                # Make ants do their steps.
                self.ants = self.pool.map_async(
                    ant_loop_apply, itertools.izip(self.ants, [self.ant_max_steps] * self.ant_count)
                ).get(9999999)
            else:
                print 'Stepping...'
                for ant in self.ants:
                    i = 0
                    while not ant.done and len(ant.trail) < self.ant_max_steps:
                        ant.step()

                        i += 1
                        if i % 1000 == 1:
                            self.visualizer.update('stepping: %d' % i)

                    if not ant.done:
                        print 'moving to next ant, this one stuck in', ant.position

            done_ants = [a for a in self.ants if a is not None and a.done]

            if not self.quiet:
                print '%d out of %d ants finished within %d steps.' % (
                    len(done_ants),
                    self.ant_count,
                    self.ant_max_steps
                )

            if self.optimize_ants:
                # optimize the trails for these ants
                opts = []
                for ant in done_ants:
                    opts.append(ant.optimize_trail(quiet=self.quiet))
                if not self.quiet:
                    print 'Optimisation reduced trail langth with an average of', mean(opts)

            # disable the dead ends found by the ant
            if self.maze_elimination:
                for ant in self.ants:
                    if ant is not None:
                        for p in ant.disable_positions:
                            self.maze.disable_at(p)

            # select the best ant:
            if len(done_ants) > 0:
                iteration_best = min(done_ants)

                # if global_best becomes invalid, forget it.
                # if global_best is not None:
                #     global_best.maze = self.maze
                #     if not global_best.is_valid():
                #         global_best = None
                #         if not self.quiet:
                #             print 'Forgot global best!'

                if global_best is None:
                    global_best = iteration_best.clone()
                else:
                    global_best = min([iteration_best, global_best]).clone()

            # update pheromone in the maze, for unique positions
            deltas = np.zeros((self.maze.height, self.maze.width))
            if global_best is not None:
                deltas = self.delta_matrix(global_best)

            if iteration_best is not None and global_best is not iteration_best:
                deltas += self.delta_matrix(iteration_best)

            # only update if iteration returned something.
            if iteration_best is not None:
                self.iteration_best_trail.append(len(iteration_best.trail))
            else:
                self.iteration_best_trail.append(None)

            maze.update_tau(delta_tau=deltas, evaporation=self.evaporation)

            # update ant_max_steps to the max value of this iteration
            if len(done_ants) > 3:
                if self.update_max_steps:
                    try:
                        self.ant_max_steps = min(
                            self.ant_max_steps,
                            max(len(x.trail) for x in done_ants if len(x.trail) < self.ant_max_steps)
                        )
                    except:
                        pass
                if self.update_Q:
                    self.Q = min(min(len(x.trail) for x in self.ants), self.Q)

            if not self.quiet:
                if iteration_best is not None and global_best is not None:
                    print 'Best ant: %d, iteration best: %d' % (
                        len(global_best.trail),
                        len(iteration_best.trail)
                    )
                else:
                    print 'None of the ants finished stepping'

            # reset ants
            for ant in self.ants:
                ant.reset(maze)

            if self.visualize:
                self.visualizer.update('Pheromone level iteration %d' % i)
                self.visualizer.save('%dth_iteration.png' % i)

        if self.multiprocessing:
            self.interrupt()

        self.global_best = global_best
        return global_best

    def interrupt(self):
        if self.multiprocessing:
            self.pool.close()
            self.pool.join()

    def get_first_iteration_with_best_trail(self):
        trail_length = len(self.global_best.trail)

        for i, val in enumerate(self.iteration_best_trail):
            if val == trail_length:
                return i