Skip to content
Snippets Groups Projects
Commit 3c4d314d authored by Zizhe Wang's avatar Zizhe Wang
Browse files

fix set parameter to be maximized

parent e295b9fd
No related branches found
No related tags found
No related merge requests found
......@@ -16,11 +16,12 @@ import os
MODEL_NAME = "SimpleHeatingSystem"
MODEL_FILE = f"{MODEL_NAME}.mo"
MODEL_PATH = os.path.join(os.getcwd(), MODEL_FILE)
SIMULATION_STOP_TIME = 2000 # in seconds
SIMULATION_STOP_TIME = 3000 # in seconds
# Parameters and result variables
PARAMETERS = ["Q_max", "T_set"]
RESULTS = ["energy", "comfort"]
MAXIMIZE = ["comfort"] # List of objectives to maximize
# Parameter range
PARAM_BOUNDS = {
......@@ -44,8 +45,8 @@ OPTIMIZATION_LIBRARY = 'pymoo'
ALGORITHM_NAME = 'NSGA2'
# Optimization settings
POP_SIZE = 5 # Population size for NSGA2
N_GEN = 5 # Number of generations
POP_SIZE = 50 # Population size for NSGA2
N_GEN = 100 # Number of generations
# Parallel processing
N_JOBS = -1 # Options: '-1', '1', 'n', 'None'
......
......@@ -15,11 +15,13 @@ from pymoo.optimize import minimize
from optimization_libraries import initialize_algorithm
from parallel_computing import optimization_function, cleanup_temp_dirs
from config import (PARAMETERS, RESULTS, PARAM_BOUNDS, PRECISION, PLOT_CONFIG,
OPTIMIZATION_LIBRARY, ALGORITHM_NAME, POP_SIZE, N_GEN, N_JOBS) # Import all configuration variables
OPTIMIZATION_LIBRARY, ALGORITHM_NAME, POP_SIZE, N_GEN, N_JOBS, MAXIMIZE) # Import all configuration variables
class OptimizationProblem(Problem):
def __init__(self):
self.param_names = list(PARAM_BOUNDS.keys())
self.result_names = RESULTS
self.maximize_indices = [self.result_names.index(res) for res in MAXIMIZE]
n_var = len(self.param_names)
xl = np.array([PARAM_BOUNDS[param][0] for param in self.param_names])
xu = np.array([PARAM_BOUNDS[param][1] for param in self.param_names])
......@@ -31,6 +33,13 @@ class OptimizationProblem(Problem):
def _evaluate(self, X, out, *args, **kwargs):
param_values_list = [dict(zip(self.param_names, x)) for x in X]
results = Parallel(n_jobs=N_JOBS)(delayed(optimization_function)(param_values) for param_values in param_values_list)
# Apply negation to objectives that need to be maximized
for i in range(len(results)):
for idx in self.maximize_indices:
results[i] = list(results[i])
results[i][idx] = -results[i][idx]
out["F"] = np.array(results) # Ensure results are a 2D array
# Initialize the optimization algorithm
......@@ -39,15 +48,22 @@ algorithm = initialize_algorithm(OPTIMIZATION_LIBRARY, ALGORITHM_NAME, POP_SIZE)
# Define the optimization problem
problem = OptimizationProblem()
try:
# Run the optimization
res = minimize(problem, algorithm, ("n_gen", N_GEN), verbose=True)
finally:
# Cleanup temporary directories
cleanup_temp_dirs()
# Print the results
print("Optimization Results:")
for i, result in enumerate(res.F):
# Negate back the maximized objectives for display
result = list(result)
for idx in problem.maximize_indices:
result[idx] = -result[idx]
result = tuple(result)
print(f"Solution {i}: ", end="")
for name, value in zip(RESULTS, result):
print(f"{name.capitalize()} = {value:.{PRECISION}f}", end=", ")
......@@ -55,10 +71,12 @@ for i, result in enumerate(res.F):
# Plot the results
plt.figure(figsize=(8, 6))
for idx in problem.maximize_indices:
res.F[:, idx] = -res.F[:, idx]
plt.scatter(res.F[:, 0], res.F[:, 1])
plt.xlabel(PLOT_CONFIG["PLOT_X"])
plt.ylabel(PLOT_CONFIG["PLOT_Y"])
plt.title(PLOT_CONFIG["PLOT_TITLE"])
plt.xlabel(PLOT_CONFIG["PLOT_X"], fontsize=14)
plt.ylabel(PLOT_CONFIG["PLOT_Y"], fontsize=14)
plt.title(PLOT_CONFIG["PLOT_TITLE"], fontsize=16)
plt.grid(True)
plt.tight_layout()
plt.show()
\ No newline at end of file
......@@ -17,13 +17,15 @@ from config import MODEL_FILE, MODEL_NAME, SIMULATION_STOP_TIME, RESULTS, MODEL_
temp_dirs = [] # List to store paths of temporary directories
def optimization_function(param_values):
def optimization_function(param_values, retries=3, delay=2):
"""
Function to optimize the Modelica model given specific parameter values.
This function runs the simulation and retrieves the results.
"""
temp_dir = tempfile.mkdtemp() # Create a unique temporary directory for each worker
temp_dirs.append(temp_dir) # Store the path for later cleanup
for attempt in range(retries):
try:
omc = OMCSessionZMQ() # Create a new OpenModelica session
temp_dir = temp_dir.replace('\\', '/')
......@@ -43,8 +45,6 @@ def optimization_function(param_values):
# Build the model in the worker session
build_model_result = omc.sendExpression(f"buildModel({MODEL_NAME})")
# uncomment this to print
# print(f"Build model result in worker: {build_model_result}")
if not (isinstance(build_model_result, tuple) and build_model_result[0]):
messages = omc.sendExpression("getErrorString()")
print(f"OpenModelica error messages: {messages}")
......@@ -69,39 +69,52 @@ def optimization_function(param_values):
# Simulate the model
simulate_result = omc.sendExpression(f"simulate({MODEL_NAME}, stopTime={SIMULATION_STOP_TIME})")
# uncomment this to print
# print(f"Simulate result: {simulate_result}")
# Retrieve simulation results
result_values = {}
for result in RESULTS:
value_command = f"val({result}, {SIMULATION_STOP_TIME})"
# uncomment this to print
# print(f"Executing command: {value_command}")
value = omc.sendExpression(value_command)
print(f"Value for {result} at {SIMULATION_STOP_TIME}: {value}")
# Round the result
result_values[result] = round(value, PRECISION)
if value is None:
raise ValueError(f"Simulation result returned None for {result}")
if not isinstance(value, (float, int)):
raise ValueError(f"Simulation result for {result} is not in expected format (float or int)")
result_values[result] = round(value, PRECISION)
print(f"Simulation results: {result_values}")
return list(result_values.values())
except Exception as e:
print(f"Error during simulation: {e}")
print(f"Error during simulation (attempt {attempt + 1}): {e}")
sleep(delay)
finally:
if 'omc' in locals():
shutdown_omc(omc)
# If all attempts fail, return NaNs
return [np.nan] * len(RESULTS)
def shutdown_omc(omc):
try:
omc.sendExpression("quit()")
omc.__del__() # Ensure OMC instance is properly closed
print("OMC session closed successfully.")
except Exception as e:
print(f"Error during OMC shutdown: {e}")
# Cleanup temporary directories at the end of the script execution
def cleanup_temp_dirs():
for temp_dir in temp_dirs:
attempt = 0
while True:
try:
shutil.rmtree(temp_dir)
print(f"Successfully removed {temp_dir}")
break # Exit the loop if successful
except PermissionError:
print(f"PermissionError: Retrying to remove {temp_dir}")
sleep(2)
try:
shutil.rmtree(temp_dir)
except PermissionError:
print(f"Failed to remove {temp_dir} after multiple attempts")
\ No newline at end of file
attempt += 1
print(f"PermissionError: Attempt {attempt} to remove {temp_dir}")
sleep(2 ** attempt) # Incremental backoff: 2, 4, 8, 16, ... seconds
except Exception as e:
print(f"Error: {e}")
break # Exit the loop for non-permission errors
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment