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
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
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 """