From cc25b749a3393799d72ec32abb27ed985c9c6368 Mon Sep 17 00:00:00 2001 From: AngryCracker Date: Thu, 1 Feb 2018 19:39:05 +0530 Subject: [PATCH 1/3] Added dropdown option to solve using genetic algorithm --- gui/tsp.py | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 7 deletions(-) diff --git a/gui/tsp.py b/gui/tsp.py index 6a460261e..7b5556c4e 100644 --- a/gui/tsp.py +++ b/gui/tsp.py @@ -3,6 +3,7 @@ import os.path sys.path.append(os.path.join(os.path.dirname(__file__), '..')) from search import * +import utils import numpy as np distances = {} @@ -56,6 +57,7 @@ def __init__(self, root, all_cities): self.calculate_canvas_size() self.button_text = StringVar() self.button_text.set("Start") + self.algo_var = StringVar() self.all_cities = all_cities self.frame_select_cities = Frame(self.root) self.frame_select_cities.grid(row=1) @@ -85,9 +87,18 @@ def create_buttons(self): """ Create start and quit button """ Button(self.frame_select_cities, textvariable=self.button_text, - command=self.run_traveling_salesman).grid(row=3, column=4, sticky=E + W) + command=self.run_traveling_salesman).grid(row=5, column=4, sticky=E + W) Button(self.frame_select_cities, text='Quit', command=self.root.destroy).grid( - row=3, column=5, sticky=E + W) + row=5, column=5, sticky=E + W) + + def create_dropdown_menu(self): + """ Create dropdown menu for algorithm selection """ + + choices = {'Simulated Annealing', 'Genetic Algorithm'} + self.algo_var.set('Simulated Annealing') + dropdown_menu = OptionMenu(self.frame_select_cities, self.algo_var, *choices) + dropdown_menu.grid(row=4, column=4, columnspan=2, sticky=E + W) + dropdown_menu.config(width=19) def run_traveling_salesman(self): """ Choose selected citites """ @@ -151,13 +162,22 @@ def create_canvas(self, problem): variable=self.speed, label="Speed ----> ", showvalue=0, font="Times 11", relief="sunken", cursor="gumby") speed_scale.grid(row=1, columnspan=5, sticky=N + S + E + W) - self.temperature = IntVar() - temperature_scale = Scale(self.frame_canvas, from_=100, to=0, orient=HORIZONTAL, + + if self.algo_var.get() == 'Simulated Annealing': + self.temperature = IntVar() + temperature_scale = Scale(self.frame_canvas, from_=100, to=0, orient=HORIZONTAL, length=200, variable=self.temperature, label="Temperature ---->", font="Times 11", relief="sunken", showvalue=0, cursor="gumby") - - temperature_scale.grid(row=1, column=5, columnspan=5, sticky=N + S + E + W) - self.simulated_annealing_with_tunable_T(problem, map_canvas) + temperature_scale.grid(row=1, column=5, columnspan=5, sticky=N + S + E + W) + self.simulated_annealing_with_tunable_T(problem, map_canvas) + elif self.algo_var.get() == 'Genetic Algorithm': + self.mutation_rate = DoubleVar() + self.mutation_rate.set(0.05) + mutation_rate_scale = Scale(self.frame_canvas, from_=0, to=1, orient=HORIZONTAL, + length=200, variable=self.mutation_rate, label='Mutation Rate ---->', + font='Times 11', relief='sunken', showvalue=0, cursor='gumby', resolution=0.001) + mutation_rate_scale.grid(row=1, column=5, columnspan=5, sticky='nsew') + self.genetic_algorithm(problem, map_canvas) def exp_schedule(k=100, lam=0.03, limit=1000): """ One possible schedule function for simulated annealing """ @@ -191,6 +211,64 @@ def simulated_annealing_with_tunable_T(self, problem, map_canvas, schedule=exp_s map_canvas.update() map_canvas.after(self.speed.get()) + def genetic_algorithm(self, problem, map_canvas): + """ Genetic Algorithm modified for the given problem """ + + def init_population(pop_number, gene_pool, state_length): + """ initialize population """ + + population = [] + for i in range(pop_number): + population.append(utils.shuffled(gene_pool)) + return population + + def recombine(state_a, state_b): + """ recombine two problem states """ + + start = random.randint(0, len(state_a) - 1) + end = random.randint(start + 1, len(state_a)) + new_state = state_a[start:end] + for city in state_b: + if city not in new_state: + new_state.append(city) + return new_state + + def mutate(state, mutation_rate): + """ mutate problem states """ + + if random.uniform(0, 1) < mutation_rate: + sample = random.sample(range(len(state)), 2) + state[sample[0]], state[sample[1]] = state[sample[1]], state[sample[0]] + return state + + def fitness_fn(state): + """ calculate fitness of a particular state """ + + fitness = problem.value(state) + return int((5600 + fitness) ** 2) + + current = Node(problem.initial) + population = init_population(100, current.state, len(current.state)) + all_time_best = current.state + while(1): + population = [mutate(recombine(*select(2, population, fitness_fn)), self.mutation_rate.get()) for i in range(len(population))] + current_best = utils.argmax(population, key=fitness_fn) + if fitness_fn(current_best) > fitness_fn(all_time_best): + all_time_best = current_best + self.cost.set("Cost = " + str('%0.3f' % (-1 * problem.value(all_time_best)))) + map_canvas.delete('poly') + points = [] + for city in current_best: + points.append(self.frame_locations[city][0]) + points.append(self.frame_locations[city][1]) + map_canvas.create_polygon(points, outline='red', width=1, fill='', tag='poly') + best_points = [] + for city in all_time_best: + best_points.append(self.frame_locations[city][0]) + best_points.append(self.frame_locations[city][1]) + map_canvas.create_polygon(best_points, outline='red', width=3, fill='', tag='poly') + map_canvas.update() + map_canvas.after(self.speed.get()) def main(): all_cities = [] @@ -212,6 +290,7 @@ def main(): cities_selection_panel = TSP_Gui(root, all_cities) cities_selection_panel.create_checkboxes() cities_selection_panel.create_buttons() + cities_selection_panel.create_dropdown_menu() root.mainloop() From ce2ba0fe43c90a09b14e3220d173d4e92aa0326e Mon Sep 17 00:00:00 2001 From: AngryCracker Date: Fri, 2 Feb 2018 14:14:17 +0530 Subject: [PATCH 2/3] Added option to solve using Hill Climbing --- gui/tsp.py | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/gui/tsp.py b/gui/tsp.py index 7b5556c4e..fbbde5f4d 100644 --- a/gui/tsp.py +++ b/gui/tsp.py @@ -94,7 +94,7 @@ def create_buttons(self): def create_dropdown_menu(self): """ Create dropdown menu for algorithm selection """ - choices = {'Simulated Annealing', 'Genetic Algorithm'} + choices = {'Simulated Annealing', 'Genetic Algorithm', 'Hill Climbing'} self.algo_var.set('Simulated Annealing') dropdown_menu = OptionMenu(self.frame_select_cities, self.algo_var, *choices) dropdown_menu.grid(row=4, column=4, columnspan=2, sticky=E + W) @@ -178,6 +178,14 @@ def create_canvas(self, problem): font='Times 11', relief='sunken', showvalue=0, cursor='gumby', resolution=0.001) mutation_rate_scale.grid(row=1, column=5, columnspan=5, sticky='nsew') self.genetic_algorithm(problem, map_canvas) + elif self.algo_var.get() == 'Hill Climbing': + self.no_of_neighbors = IntVar() + self.no_of_neighbors.set(100) + no_of_neighbors_scale = Scale(self.frame_canvas, from_=10, to=1000, orient=HORIZONTAL, + length=200, variable=self.no_of_neighbors, label='Number of neighbors ---->', + font='Times 11',relief='sunken', showvalue=0, cursor='gumby') + no_of_neighbors_scale.grid(row=1, column=5, columnspan=5, sticky='nsew') + self.hill_climbing(problem, map_canvas) def exp_schedule(k=100, lam=0.03, limit=1000): """ One possible schedule function for simulated annealing """ @@ -270,6 +278,40 @@ def fitness_fn(state): map_canvas.update() map_canvas.after(self.speed.get()) + def hill_climbing(self, problem, map_canvas): + """ hill climbing where number of neighbors is taken as user input """ + + def find_neighbors(state, number_of_neighbors=100): + """ finds neighbors using two_opt method """ + + neighbors = [] + for i in range(number_of_neighbors): + new_state = problem.two_opt(state) + neighbors.append(Node(new_state)) + state = new_state + return neighbors + + current = Node(problem.initial) + while(1): + neighbors = find_neighbors(current.state, self.no_of_neighbors.get()) + neighbor = utils.argmax_random_tie(neighbors, key=lambda node: problem.value(node.state)) + map_canvas.delete('poly') + points = [] + for city in current.state: + points.append(self.frame_locations[city][0]) + points.append(self.frame_locations[city][1]) + map_canvas.create_polygon(points, outline='red', width=3, fill='', tag='poly') + neighbor_points = [] + for city in neighbor.state: + neighbor_points.append(self.frame_locations[city][0]) + neighbor_points.append(self.frame_locations[city][1]) + map_canvas.create_polygon(neighbor_points, outline='red', width=1, fill='', tag='poly') + map_canvas.update() + map_canvas.after(self.speed.get()) + if problem.value(neighbor.state) > problem.value(current.state): + current.state = neighbor.state + self.cost.set("Cost = " + str('%0.3f' % (-1 * problem.value(current.state)))) + def main(): all_cities = [] for city in romania_map.locations.keys(): From 2d59f0744beea89dd3d0503f8c52bbb6df240fa2 Mon Sep 17 00:00:00 2001 From: AngryCracker Date: Fri, 2 Feb 2018 14:21:02 +0530 Subject: [PATCH 3/3] Added messagebox to confirm exit --- gui/tsp.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gui/tsp.py b/gui/tsp.py index fbbde5f4d..1830cba23 100644 --- a/gui/tsp.py +++ b/gui/tsp.py @@ -1,4 +1,5 @@ from tkinter import * +from tkinter import messagebox import sys import os.path sys.path.append(os.path.join(os.path.dirname(__file__), '..')) @@ -88,7 +89,7 @@ def create_buttons(self): Button(self.frame_select_cities, textvariable=self.button_text, command=self.run_traveling_salesman).grid(row=5, column=4, sticky=E + W) - Button(self.frame_select_cities, text='Quit', command=self.root.destroy).grid( + Button(self.frame_select_cities, text='Quit', command=self.on_closing).grid( row=5, column=5, sticky=E + W) def create_dropdown_menu(self): @@ -312,6 +313,10 @@ def find_neighbors(state, number_of_neighbors=100): current.state = neighbor.state self.cost.set("Cost = " + str('%0.3f' % (-1 * problem.value(current.state)))) + def on_closing(self): + if messagebox.askokcancel('Quit', 'Do you want to quit?'): + self.root.destroy() + def main(): all_cities = [] for city in romania_map.locations.keys(): @@ -333,6 +338,7 @@ def main(): cities_selection_panel.create_checkboxes() cities_selection_panel.create_buttons() cities_selection_panel.create_dropdown_menu() + root.protocol('WM_DELETE_WINDOW', cities_selection_panel.on_closing) root.mainloop() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy