feat: separate logic from display

This commit is contained in:
Krzysztof Rudnicki 2023-04-17 21:19:40 +02:00
parent d13e681cb9
commit 9c02b7e035
6 changed files with 46 additions and 34 deletions

View File

@ -7,8 +7,6 @@ import sys
import os
import time
import tempfile
# run pylint with:
# pylint --generated-members=cv2.* .\main.py
import cv2
import matplotlib.pyplot as plt
import numpy as np
@ -45,7 +43,6 @@ def generate(population,
population = children + mutation
return fitness, population
def evolution_strategy(
number_of_parents=5,
size_of_population=20,
@ -53,19 +50,19 @@ def evolution_strategy(
number_of_generations=123,
min_max=(-5.12, 5.12),
number_of_outputs = 10,
no_display = False
no_display = False,
save_results = False
):
""" Define the Evolutionary Strategy (μ, λ) algorithm """
# Initialize the population
total_time = 0
start_time = time.perf_counter()
print_info = []
population = np.random.uniform(
low=min_max[0], high=min_max[1], size=(
size_of_population, 2))
summary = []
output(population, 0, f"0:nop-{number_of_parents}:sop-{size_of_population}:ms-{mutation_strength}:nog-{number_of_generations}:min-max-{min_max}:noo-{number_of_outputs}")
if not no_display:
print_info.append((population, 0, f"0:nop-{number_of_parents}:sop-{size_of_population}:ms-{mutation_strength}:nog-{number_of_generations}:min-max-{min_max}:noo-{number_of_outputs}"))
number_of_outputs = min([number_of_outputs-1, number_of_generations])
# Iterate until we reach max number of generate and terminate
@ -79,24 +76,17 @@ def evolution_strategy(
if number_of_generations % number_of_outputs == 0 \
else number_of_generations//(number_of_outputs-1)
offset = number_of_generations % step
end_time = time.perf_counter()
total_time += end_time - start_time
if (generation_number - offset) % step == 0 and not no_display:
output(population, generation_number, f"{generation_number}:nop_{number_of_parents}:sop_{size_of_population}:ms_{mutation_strength}:nog_{number_of_generations}:min_max_{min_max}:noo_{number_of_outputs}")
print_info.append((population, generation_number, f"{generation_number}:nop_{number_of_parents}:sop_{size_of_population}:ms_{mutation_strength}:nog_{number_of_generations}:min_max_{min_max}:noo_{number_of_outputs}"))
summary.append(population)
if not no_display:
print_summary(summary, f"{generation_number}:nop-{number_of_parents}:sop-{size_of_population}:ms-{mutation_strength}:nog-{number_of_generations}:min-max-{min_max}:noo-{number_of_outputs}")
start_time = time.perf_counter()
# Evaluate the fitness of the final population
fitness = np.array([rastrigin(x_point_value, y_point_value)
for x_point_value, y_point_value in population])
# Return the best individual found
best_idx = np.argmin(fitness)
end_time = time.perf_counter()
total_time += end_time - start_time
return population[best_idx], fitness[best_idx], population, total_time
return population[best_idx], fitness[best_idx], population, total_time, print_info, summary
def print_help():
@ -126,6 +116,7 @@ def print_help():
Those arguments can be given in any order and any argument which was not entered will be replaced with default value,
Additional flags:
-nd, --no-display (does not show the plots)
-s, --save (if issued WILL save the files)
exemplary use:
python main.py -nop 5 -sop 20 -ms 0.1 -i 100 -min -5.12 -max 5.12 -noo 100
""")
@ -159,7 +150,7 @@ def get_output_bounds(x_data, y_data):
return x_bounds, y_bounds
def output(population_output, generation_number, file_name = "temp"):
def output(population_output, generation_number, file_name = "temp", save_results = False):
""" Draw result of our function """
# define the visualization params
@ -188,7 +179,8 @@ def output(population_output, generation_number, file_name = "temp"):
# show the image, provide window name first
cv2.imshow(f"Generation {generation_number}", image)
cv2.imwrite(file_name + ".jpg", image)
if save_results:
cv2.imwrite(file_name + ".jpg", image)
# add wait key. window waits until user presses a key and quits if
# the key is 'q'
if cv2.waitKey(0) == 113:
@ -201,7 +193,7 @@ def output(population_output, generation_number, file_name = "temp"):
os.unlink(file_.name)
def print_summary(populations, file_name = "temp_summary"):
def print_summary(populations, file_name = "temp_summary", save_results = False):
""" Draw result of our function for chosen generations """
# define the visualization params
@ -235,7 +227,8 @@ def print_summary(populations, file_name = "temp_summary"):
# read image
image = cv2.imread(file_.name)
cv2.imwrite("SUMMARY:" + file_name + ".jpg", image)
if save_results:
cv2.imwrite("SUMMARY:" + file_name + ".jpg", image)
# show the image, provide window name first
cv2.imshow(f"Summary", image)
@ -263,7 +256,8 @@ def user_input():
"min": -5.12,
"max": 5.12,
"number_of_outputs": 10,
"no_display": False}
"no_display": False,
"save": False}
for index, argument in enumerate(sys.argv):
if argument in ('-h', '--help'):
print_help()
@ -284,26 +278,39 @@ def user_input():
arguments["number_of_outputs"] = int(sys.argv[index + 1])
if argument in ('-nd', '--no_display'):
arguments["no_display"] = True
if argument in ('-s', '--save'):
arguments["save"] = True
return arguments
def print_output(print_info, save_results, summary):
for population, file_name, generation_number in print_info:
output(population, generation_number, file_name, save_results)
print_summary(summary)
# Ran first in the code
if __name__ == "__main__":
# Run the Evolutionary Strategy algorithm
ARGUMENTS = user_input()
best_individual, best_fitness, output_population, generation_time = evolution_strategy(
total_time = 0
start_time = time.perf_counter()
best_individual, best_fitness, output_population, generation_time, print_info, summary = evolution_strategy(
ARGUMENTS["number_of_parents"],
ARGUMENTS["size_of_population"],
ARGUMENTS["mutation_strength"],
ARGUMENTS["number_of_generations"],
(ARGUMENTS["min"], ARGUMENTS["max"]),
ARGUMENTS["number_of_outputs"],
ARGUMENTS["no_display"])
time_per_generation = generation_time / \
ARGUMENTS["no_display"],
ARGUMENTS["save"])
end_time = time.perf_counter()
if not ARGUMENTS["no_display"]:
print_output(print_info, ARGUMENTS["save"], summary)
total_time = end_time - start_time
time_per_generation = total_time / \
ARGUMENTS["number_of_generations"]
print("Best individual found:", best_individual)
print("Best fitness found:", best_fitness)
print("total_generation_time: ", generation_time)
print("total_generation_time: ", total_time)
print("time_per_generation: ", time_per_generation)

View File

@ -1,11 +1,11 @@
# Fdb version 4
["xdvipdfmx"] 1681756905 "EARIN_LAB_3_RUDNICKI_KLISZKO.xdv" "EARIN_LAB_3_RUDNICKI_KLISZKO.pdf" "EARIN_LAB_3_RUDNICKI_KLISZKO" 1681756905 0
"EARIN_LAB_3_RUDNICKI_KLISZKO.xdv" 1681756905 30192 bd831cc7fba44cf2e46d93256fd6cbfe "xelatex"
["xdvipdfmx"] 1681757884 "EARIN_LAB_3_RUDNICKI_KLISZKO.xdv" "EARIN_LAB_3_RUDNICKI_KLISZKO.pdf" "EARIN_LAB_3_RUDNICKI_KLISZKO" 1681757884 0
"EARIN_LAB_3_RUDNICKI_KLISZKO.xdv" 1681757884 33124 09e315a7c52dfa256c17b04adeecd4ac "xelatex"
(generated)
"EARIN_LAB_3_RUDNICKI_KLISZKO.pdf"
(rewritten before read)
["xelatex"] 1681756905 "/home/kuchy/earin/EARIN/lab3/report/EARIN_LAB_3_RUDNICKI_KLISZKO.tex" "EARIN_LAB_3_RUDNICKI_KLISZKO.xdv" "EARIN_LAB_3_RUDNICKI_KLISZKO" 1681756905 0
"/home/kuchy/earin/EARIN/lab3/report/EARIN_LAB_3_RUDNICKI_KLISZKO.tex" 1681756904 3239 1c19d3382eb02eca12f28f266179f0f0 ""
["xelatex"] 1681757884 "/home/kuchy/earin/EARIN/lab3/report/EARIN_LAB_3_RUDNICKI_KLISZKO.tex" "EARIN_LAB_3_RUDNICKI_KLISZKO.xdv" "EARIN_LAB_3_RUDNICKI_KLISZKO" 1681757884 0
"/home/kuchy/earin/EARIN/lab3/report/EARIN_LAB_3_RUDNICKI_KLISZKO.tex" 1681757883 3477 8ed5d7943c9fec7b536ad469925926ad ""
"/usr/share/texmf-dist/fonts/map/fontname/texfonts.map" 1679564905 3524 cb3e574dea2d1052e39280babc910dc8 ""
"/usr/share/texmf-dist/fonts/tfm/adobe/zapfding/pzdr.tfm" 1679564905 1528 f853c4d1b4e0550255e02831fdc8496f ""
"/usr/share/texmf-dist/fonts/tfm/public/cm/cmmi12.tfm" 1679564905 1524 4414a8315f39513458b80dfc63bff03a ""
@ -66,9 +66,9 @@
"/usr/share/texmf-dist/tex/latex/url/url.sty" 1679564905 12796 8edb7d69a20b857904dd0ea757c14ec9 ""
"/usr/share/texmf-dist/web2c/texmf.cnf" 1679564905 39911 2da6c67557ec033436fe5418a70a8a61 ""
"/var/lib/texmf/web2c/xetex/xelatex.fmt" 1680438638 11046058 c421129080a65de742470a82b56f326d ""
"EARIN_LAB_3_RUDNICKI_KLISZKO.aux" 1681756905 1319 29ad114a76f2d8d01aa31fa0dc1b211c "xelatex"
"EARIN_LAB_3_RUDNICKI_KLISZKO.out" 1681756905 454 50b668959753031c85a7636eb970de0c "xelatex"
"EARIN_LAB_3_RUDNICKI_KLISZKO.tex" 1681756904 3239 1c19d3382eb02eca12f28f266179f0f0 ""
"EARIN_LAB_3_RUDNICKI_KLISZKO.aux" 1681757884 1319 29ad114a76f2d8d01aa31fa0dc1b211c "xelatex"
"EARIN_LAB_3_RUDNICKI_KLISZKO.out" 1681757884 454 50b668959753031c85a7636eb970de0c "xelatex"
"EARIN_LAB_3_RUDNICKI_KLISZKO.tex" 1681757883 3477 8ed5d7943c9fec7b536ad469925926ad ""
"example_halfway.jpg" 1681756460 43787 f0809821c60091352d61146053f795f2 ""
"example_summary.jpg" 1681756506 17901 286cc778e6a6b564c8027d51b98a968f ""
(generated)

View File

@ -50,6 +50,11 @@ Exemplary use (settings all values to default values):
python main.py -nop 5 -sop 20 -s 0.1
-i 100 -min -5.12 -max 5.12 -noo 10
\end{lstlisting}
There are additional flags for quality of life with the program
\begin{lstlisting}
-nd --no_display (If used will NOT print out the plots)
-s --save (If used WILL save plot files to code folder)
\end{lstlisting}
To print help info about program user can issue help flag:
\begin{lstlisting}[language=bash]
python main.py -h
@ -66,7 +71,7 @@ At the end summary of results on plot will display with red gradient showing res
\includegraphics[width=8cm]{example_summary.jpg}
\centering
\end{figure}
Results will be displayed and saved in the same folder as code directory for further inspection, with file name containing information about input parameters
Results will be displayed and if user requested saved in the same folder as code directory for further inspection, with file name containing information about input parameters
\section{Results}
We have successfully implemented ES($\mu$, $\lambda$) to optimize Rastrigin function \\
Rastrigin function is used to test optimization algorithms as it contains a lot of local minima