Formula Student Autonomous Systems
The code for the main driverless system
Loading...
Searching...
No Matches
bayesian.py
Go to the documentation of this file.
1import sys
2import os
3import signal
4import subprocess
5import importlib
6from skopt import Optimizer
7from operator import itemgetter
8
9algorithm_to_tune = "cone_coloring"
10
11# Base directory where bayesian.py is located
12base_dir = os.path.dirname(os.path.abspath(__file__))
13
14# Construct the full path to the subdirectory
15full_path = os.path.join(base_dir, algorithm_to_tune)
16
17# Check if the adapt.py exists in the specified directory
18if os.path.exists(os.path.join(full_path, "adapt.py")):
19 # Append the subdirectory to sys.path
20 sys.path.append(full_path)
21
22 # Dynamically import the "adapt" module (without the .py extension)
23 module = importlib.import_module("adapt")
24else:
25 print(f"adapt.py not found in {algorithm_to_tune}")
26
27
28executable_path = "./" + algorithm_to_tune + "/bayesian_opt"
29export_path = algorithm_to_tune + "/parameters_rank.txt"
30
31
32# Define a wrapper function to call the C++ program and pass the parameters.
33def call_cpp_program(params):
34 # Convert the parameters to a string format to send them to the C++ executable.
35 param_str_list = list(map(str, params))
36
37 try:
38 # Use subprocess to call the C++ executable and pass the parameters.
39 result = subprocess.run(
40 [
41 executable_path,
42 *param_str_list,
43 ],
44 capture_output=True,
45 text=True,
46 check=True,
47 )
48
49 # The result should be the output from your C++ program (a numeric value).
50 return float(result.stdout.strip())
51 except subprocess.CalledProcessError as e:
52 # Handle errors from the C++ execution if any.
53 print("Error while running C++ program:", e)
54 return float("inf") # Return a large value to signify failure
55
56
57# Define the objective function to minimize, which will call the C++ program.
59 # Call the C++ program with the parameter values and return the result (the value to minimize).
60 result = call_cpp_program(params)
61 return result
62
63
64# To track the top 5 sets of parameters and their values.
65top_5 = []
66
67best_value = float("inf")
68best_params = module.parameters_list[0]
69
70
71def update_top_5(params, value):
72 # Append the new parameters and value to the list.
73 top_5.append((params, value))
74
75 # Sort the list based on the objective value (second item in the tuple).
76 top_5.sort(key=itemgetter(1))
77
78 # Keep only the top 5 values.
79 if len(top_5) > 5:
80 top_5.pop()
81
82
83# Function to export the top 5 parameters to a file.
85 with open(export_path, "a") as f:
86 f.write("Top 5 parameter sets and their objective values:\n")
87 for i, (params, value) in enumerate(top_5, 1):
88 f.write(f"Rank {i}: Parameters = {params}, Objective Value = {value}\n")
89 print("\nTop 5 parameters have been saved to 'parameters_rank.txt'.")
90
91
92# Signal handler to catch KeyboardInterrupt and perform cleanup.
93def signal_handler(sig, frame):
94 print("\nTermination signal received. Exporting top 5 parameters...")
96 sys.exit(0)
97
98
99# Register the signal handler for KeyboardInterrupt (Ctrl+C).
100signal.signal(signal.SIGINT, signal_handler)
101
102
103# Initialize the Bayesian optimizer with the parameter space.
104optimizer = Optimizer(module.param_space, "GP", n_initial_points=10, random_state=None)
105
106for params in module.parameters_list:
107 result = objective_function(params)
108 optimizer.tell(params, result)
109 update_top_5(params, result)
110 if result < best_value:
111 best_value = result
112 best_params = params
113 # Print the current best parameters and result.
114 print(f"New best parameters: {best_params}")
115 print(f"New best objective value (to minimize): {best_value}")
116
117# Run indefinitely
118while True:
119 # Ask the optimizer for the next set of parameters to evaluate.
120 next_params = optimizer.ask()
121
122 # Evaluate the objective function (call the C++ program with the proposed parameters).
123 current_value = objective_function(next_params)
124
125 # Tell the optimizer about the result so it can update its model.
126 optimizer.tell(next_params, current_value)
127
128 # Update the best result found so far if this evaluation is better.
129 if current_value < best_value:
130 best_value = current_value
131 best_params = next_params
132 # Print the current best parameters and result.
133 print(f"New best parameters: {best_params}")
134 print(f"New best objective value (to minimize): {best_value}")
135
136 update_top_5(next_params, current_value)
update_top_5(params, value)
Definition bayesian.py:71
signal_handler(sig, frame)
Definition bayesian.py:93
export_top_5_to_file()
Definition bayesian.py:84
call_cpp_program(params)
Definition bayesian.py:33
objective_function(params)
Definition bayesian.py:58