-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgui.py
329 lines (278 loc) · 13 KB
/
gui.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
import tkinter as tk
from tkinter import ttk, filedialog
import pickle
import matplotlib.pyplot as plt
import os
from genalg import Generational_Data, Clique
import networkx as nx
# Define global variables
base_graph = None
generations = None
all_cliques = None
all_cliques_fitness = None
woc_clique = None
plot_image = None
num_highlighted_nodes = None
selected_generation = None
# Function to select a data file using a file dialog
def select_data_file():
global data_filename
new_data_filename = filedialog.askopenfilename(
filetypes=[("Pickle Files", "*.pkl")]
)
if new_data_filename:
print(f"Selected data file: {new_data_filename}")
data_filename = new_data_filename # Update the data_filename
# Function to create and display the GUI
def display_gui():
global base_graph, generations, all_cliques, all_cliques_fitness, woc_clique, plot_image, num_highlighted_nodes, selected_generation
# Load data from a data file
try:
with open(data_filename, "rb") as import_file:
imported_data = pickle.load(import_file)
base_graph = imported_data["base_graph"]
all_cliques = imported_data["all_cliques"]
all_cliques_fitness = [None] * len(all_cliques)
generations = imported_data["generations"]
woc_clique = imported_data["woc_clique"]
for i in range(len(all_cliques)):
all_cliques_fitness[i] = len(all_cliques[i].nodes)
# Create the main Tkinter window
root = tk.Tk()
root.title("Genetic Algorithm TSP")
root.geometry("1200x800") # Set the window size
# Create a menu bar
menubar = tk.Menu(root)
root.config(menu=menubar)
# Create a "File" menu
file_menu = tk.Menu(menubar, tearoff=0)
menubar.add_cascade(label="File", menu=file_menu)
# Add an "Open Data File" option to the "File" menu
file_menu.add_command(label="Open Data File", command=select_data_file)
# Add a separator
file_menu.add_separator()
# Add an "Exit" option to the "File" menu
file_menu.add_command(label="Exit", command=root.quit)
# Create a canvas for displaying graphs
canvas = tk.Canvas(root)
canvas.pack(fill=tk.BOTH, expand=True) # Dynamically scale the canvas
num_highlighted_nodes = 0
default_gen = 0
# Create a generation selection dropdown
generation_var = tk.IntVar()
generation_label = ttk.Label(root, text="Select Generation:")
generation_label.pack()
generation_dropdown = ttk.Combobox(
root, textvariable=generation_var, state="readonly"
)
generation_dropdown.pack()
generation_dropdown.set(default_gen) # Default to the best generation
# Function to update the generation dropdown based on the selected thread
def update_generation_dropdown(*args):
generation_dropdown["values"] = generations
# Function to update the data displayed in the GUI
def update_data():
global base_graph, generations, all_cliques, all_cliques_fitness, woc_clique, plot_image, num_highlighted_nodes, selected_generation
try:
with open(data_filename, "rb") as import_file:
imported_data = pickle.load(import_file)
base_graph = imported_data["base_graph"]
all_cliques = imported_data["all_cliques"]
all_cliques_fitness = [None]*len(all_cliques)
generations = imported_data["generations"]
woc_clique = imported_data["woc_clique"]
for i in range(len(all_cliques)):
all_cliques_fitness[i] = len(all_cliques[i].nodes)
default_gen = 0
default_cost = 0
generation_var.set(
default_gen
) # Update the existing generation dropdown
update_cost_label(default_cost)
update_best_gen_label(generations, all_cliques_fitness)
update_graph()
except FileNotFoundError:
print(
"Data file not found. Please run the genetic algorithm script to generate data."
)
# Function to update the displayed graph based on user selections
def update_graph():
selected_generation = int(generation_var.get())
if base_graph:
if all_cliques is not None and all_cliques_fitness is not None:
# Update the graph based on user selections
if plot_var.get() == "Path":
# Plot the path graph
canvas.delete("all")
plt.figure(figsize=(8, 6))
pos = nx.spring_layout(base_graph)
nx.draw(
base_graph,
pos,
with_labels=True,
node_color="lightblue",
edge_color="gray",
)
clique_nodes = all_cliques[selected_generation].nodes
if clique_nodes:
# Convert set to list for drawing
clique_nodes_list = list(clique_nodes)
nx.draw_networkx_nodes(
base_graph,
pos,
nodelist=clique_nodes_list,
node_color="orange",
)
plt.title(
f"{os.path.basename(data_filename)}, Gen: {selected_generation} Nodes"
)
cost = all_cliques_fitness[selected_generation]
plt.suptitle(f"Performance: {cost}")
plt.xlabel("X")
plt.ylabel("Y")
plt.grid(True)
plt.savefig(
"temp_plot.png"
) # Save the plot to a temporary file
plot_image = tk.PhotoImage(file="temp_plot.png")
canvas.create_image(0, 0, anchor=tk.NW, image=plot_image)
canvas.image = plot_image
update_cost_label(cost)
elif plot_var.get() == "Performance":
# Plot the cost vs. generation graph
all_cliques_fitness_sorted = all_cliques_fitness
all_cliques_fitness_sorted.sort()
canvas.delete("all")
plt.figure(figsize=(8, 6))
plt.plot(generations, all_cliques_fitness_sorted)
plt.title(
f"{os.path.basename(data_filename)}, Performance vs. Generation"
)
plt.xlabel("Generation")
plt.ylabel("Performance")
plt.grid(True)
plt.savefig(
"temp_plot.png"
) # Save the plot to a temporary file
plot_image = tk.PhotoImage(file="temp_plot.png")
canvas.create_image(0, 0, anchor=tk.NW, image=plot_image)
canvas.image = plot_image
generation_dropdown.set(0)
update_cost_label(max(all_cliques_fitness))
elif plot_var.get() == "WoC":
# Plot the path graph
canvas.delete("all")
plt.figure(figsize=(8, 6))
pos = nx.spring_layout(base_graph)
nx.draw(
base_graph,
pos,
with_labels=True,
node_color="lightblue",
edge_color="gray",
)
clique_nodes = woc_clique.nodes
if clique_nodes:
# Convert set to list for drawing
clique_nodes_list = list(clique_nodes)
nx.draw_networkx_nodes(
base_graph,
pos,
nodelist=clique_nodes_list,
node_color="orange",
)
plt.title(
f"{os.path.basename(data_filename)}, WoC Nodes"
)
cost = len(woc_clique.nodes)
plt.suptitle(f"Performance: {cost}")
plt.xlabel("X")
plt.ylabel("Y")
plt.grid(True)
plt.savefig(
"temp_plot.png"
) # Save the plot to a temporary file
plot_image = tk.PhotoImage(file="temp_plot.png")
canvas.create_image(0, 0, anchor=tk.NW, image=plot_image)
canvas.image = plot_image
update_cost_label(cost)
elif plot_var.get() == "Base_Graph":
# Plot the path graph
canvas.delete("all")
plt.figure(figsize=(8, 6))
pos = nx.spring_layout(base_graph)
nx.draw(
base_graph,
pos,
with_labels=True,
node_color="lightblue",
edge_color="gray",
)
plt.title(
f"{os.path.basename(data_filename)}, Base Graph"
)
cost = 0
plt.xlabel("X")
plt.ylabel("Y")
plt.grid(True)
plt.savefig(
"temp_plot.png"
) # Save the plot to a temporary file
plot_image = tk.PhotoImage(file="temp_plot.png")
canvas.create_image(0, 0, anchor=tk.NW, image=plot_image)
canvas.image = plot_image
update_cost_label(cost)
# Function to update the cost label based on user selections
def update_cost_label(cost):
cost_label.config(text=f"Performance: {cost}")
def update_best_gen_label(generations, all_cliques_fitness):
gen_num = 0
best_fit = 0
for generation in generations:
if all_cliques_fitness[generation] > best_fit:
gen_num = generation
best_fit = all_cliques_fitness[generation]
best_gen_label.config(text=f"Best Generation: {gen_num} Performance: {best_fit}")
# Create a label for displaying the cost
cost_label = ttk.Label(root, text="")
cost_label.pack()
best_gen_label = ttk.Label(root, text="")
best_gen_label.pack()
# Create radio buttons for selecting the plot type
plot_var = tk.StringVar()
plot_var.set("Base_Graph") # Default to Path plot
base_button = ttk.Radiobutton(
root, text="Base_Graph", variable=plot_var, value="Base_Graph"
)
base_button.pack()
path_button = ttk.Radiobutton(
root, text="Path", variable=plot_var, value="Path"
)
path_button.pack()
cost_button = ttk.Radiobutton(
root, text="Performance vs. Generation", variable=plot_var, value="Performance"
)
cost_button.pack()
woc_button = ttk.Radiobutton(
root, text="Wisdom of the Crowds", variable=plot_var, value="WoC"
)
woc_button.pack()
# Create a button to update the graph
update_button = ttk.Button(root, text="Update Graph", command=update_graph)
update_button.pack()
# Create a button to update the data
update_button = ttk.Button(root, text="Update Data", command=update_data)
update_button.pack()
# Initial update of the graph
update_graph()
update_generation_dropdown()
update_best_gen_label(generations, all_cliques_fitness)
# Start the Tkinter main loop
root.mainloop()
except FileNotFoundError:
print(
"Data file not found. Please run the genetic algorithm script to generate data."
)
if __name__ == "__main__":
data_filename = f"data_files{os.path.sep}random_graph_20_datapack.pkl" # Set the initial data file here
display_gui()