示例#1
0
 def __init__(self, size, prob, num, properties, method, generation=3):
     self.size = size
     self.properties = properties
     self.prob = prob
     self.num = num
     self.child = part1.Maze(self.size, self.prob)
     self.generation = generation
     self.new_maze = []
     self.chromsome = []
     self.children = []
     self.method = method
     self.rep = 0
示例#2
0
    def get_chromsome(self):

        for i in range(self.num):
            gen_maze = part1.Maze(self.size, self.prob)
            if self.fitness(gen_maze) > 0:
                self.chromsome.append(gen_maze)
        self.chromsome.sort(key=lambda x: x.solution[self.properties],
                            reverse=False)
        self.chromsome = self.chromsome[-20:]
        '''
        for each in chromsome:
            print(each.maze)
            print(each.solution["path_length"])
            '''
        return self.chromsome
示例#3
0
    def reproduce(self):
        self.chromsome.sort(key=lambda x: x.solution[self.properties],
                            reverse=False)
        self.chromsome = self.chromsome[-20:]
        global rep
        # child=zeros(self.size,self.size)
        parents = copy.deepcopy(self.chromsome)
        for k in range(0, len(parents) - 1, 2):
            cros = random.randint(1, self.size - 1)
            parent1 = copy.deepcopy(self.chromsome[k])
            parent2 = copy.deepcopy(self.chromsome[k + 1])
            childtemp = part1.Maze(self.size, self.prob)
            for i in range(0, cros):
                childtemp.maze[i] = parent1.maze[i]

            for i in range(cros, self.size - 1):
                childtemp.maze[i] = parent2.maze[i]

            mazetemp2 = copy.deepcopy(self.child.maze)

            for i in range(0, self.size):
                for j in range(0, random.randint(1, self.size - 1)):
                    self.child.maze[i][j] = mazetemp2[i][self.size - 1 - j]

            self.mutation(childtemp)
            fitness1 = self.fitness(childtemp)
            fitness2 = self.fitness(parent1)
            fitness3 = self.fitness(parent2)

            if (fitness1 <= fitness2 or fitness1 <= fitness3):
                if fitness2 >= fitness3:
                    self.children.append(parent1)
                else:
                    self.children.append(parent2)

            else:
                self.children.append(childtemp)
                self.chromsome.append(childtemp)

        self.children.sort(key=lambda x: x.solution[self.properties],
                           reverse=False)
        # print(self.children)
        self.child = copy.deepcopy(self.children[len(self.children) - 1])
        print("*************************************")
        print(self.child.solution[self.properties])
        return self.child
    def sa(self, temperature, cool, threshold, prob, algorithm, objective):
        # def sa(self,temperature,cool, prob,algorithms,target):
        """
        :param temperature: Temperature
        :param cool: coefficient
        :param prob: probability of an empty node to be filled or a filled node to become empty
        :param algorithm: search algorithms
        :param objective: Objective function
        :param threshold: threshold
        :return:
        """
        # count how many times that we want to take risks
        taking_risks = 0

        # number of total iterations
        i = 0

        # difference of cost between original cost and new cost
        dE = 0

        # To make sure that the maze is solvable, if not, create a new one, until the maze is solvable
        test_solver = part1.SolveMaze(self.a_maze)
        test_solver.a_star_euclidean()
        while self.a_maze.solution['path_length'] == 0:
            another_maze = part1.Maze(self.a_maze.size, self.a_maze.prob)
            self.a_maze.maze = another_maze.maze.copy()
            test_solver.a_star_euclidean()
            print('this is a new maze may be solvable!')

        new_maze = part1.Maze(self.a_maze.size, 0)

        while temperature > threshold:

            # # original maze,cost
            # a_solver = part1.SolveMaze(self.a_maze)
            # a_solver.dfs()
            # a_cost = self.a_maze.solution['path_length']
            #
            # # next step (new maze that changed from former one)
            new_maze.maze = self.new_maze_to_one_or_zero(prob)
            #
            # # make a new step (new maze) and new cost
            # new_solver = part1.SolveMaze(new_maze)
            # new_solver.dfs()
            # new_cost = new_maze.solution['path_length']

            a_cost, new_cost = self.cost_calculator(new_maze, algorithm,
                                                    objective)

            # strategy of taking next step
            if new_cost > 0:  # to make sure that new maze is solvable
                dE = a_cost - new_cost

                if dE < 0:  # which means that new maze is harder to solve
                    self.a_maze.maze = new_maze.maze.copy()

                # which means that new maze is easier to solve, but we still want to take a risk in some cases
                elif dE > 0 and math.exp(
                    (-dE) / temperature) >= random.uniform(0, 1):
                    self.a_maze.maze = new_maze.maze.copy()
                    taking_risks = taking_risks + 1
                    print('take risks time: ', taking_risks)
                    print('the possibility is', 100 * math.exp(
                        (-dE) / temperature), '% ')
                    print('Iteration:', i, ' current cost: ', a_cost)

            # to cool the temperature
            temperature = temperature - cool

            # print the maze to show the path, and the cost
            if i % 400 == 0:
                self.a_maze.print_path()
                print('Iteration:', i, ' current cost: ', a_cost)

            i = i + 1
        print('Total number of iterations:', i)
        :return: True of False
        """
        return self.a_maze.maze[node[0], node[1]] == 0

    def num_filled(self, maze):
        """
        the percentage of node that has been filled
        :return: percentage
        """
        num = 0
        for x1 in range(self.a_maze.size):
            for y1 in range(self.a_maze.size):
                if maze.maze[x1][y1] == 1:
                    num = num + 1

        return num / (self.a_maze.size * self.a_maze.size)


if __name__ == "__main__":
    maze = part1.Maze(30, 0.3)

    sa = SimulatedAnnealing(maze)
    sa.sa(0.05, 0.000002, 0.007145, 80, 'a_star_manhattan', 'max_fringe_size')

    # 0.5, 0.00002, 0.1429  dfs  number_of_nodes_visited

    # 1, 0.0001, 0.1429, 60, is a good choice for dfs and path length path_length
    """
    0.05, 0.000002, 0.007145 max_fringe_size
    """