From 8cd1e7a5834bbd0784c08c5a0931ffe816b46650 Mon Sep 17 00:00:00 2001
From: Zizhe Wang <zizhe.wang@tu-dresden.de>
Date: Wed, 12 Jun 2024 11:46:29 +0200
Subject: [PATCH] refactor definition of parameters to be maximized

---
 src/config.json           | 14 ++++++++-----
 src/config.py             | 44 +++++++++++++++++++++++----------------
 src/parallel_computing.py | 14 ++++++-------
 3 files changed, 42 insertions(+), 30 deletions(-)

diff --git a/src/config.json b/src/config.json
index 89a97e7..b64bc65 100644
--- a/src/config.json
+++ b/src/config.json
@@ -2,9 +2,12 @@
     "MODEL_NAME": "SimpleHeatingSystem",
     "MODEL_FILE": "SimpleHeatingSystem.mo",
     "SIMULATION_STOP_TIME": 3000,
+    "PRECISION": 2,
     "PARAMETERS": ["Q_max", "T_set"],
-    "OBJECTIVES": ["energy", "comfort"],
-    "MAXIMIZE": ["comfort"],
+    "OBJECTIVES": [
+        {"name": "energy", "maximize": false},
+        {"name": "comfort", "maximize": true}
+    ],
     "PARAM_BOUNDS": {
         "Q_max": {
             "bounds": [1000, 5000],
@@ -15,12 +18,13 @@
             "type": "int"
         }
     },
-    "PRECISION": 2,
     "OPTIMIZATION_CONFIG": {
         "USE_ADAPTIVE_INSTANCE_SELECTION": true,
+        "ADAPTIVE_INSTANCE_SELECTION_FREQUENCY": 5,
         "ALGORITHM_NAME": "NSGA2",
-        "POP_SIZE": 1,
-        "N_GEN": 1
+        "POP_SIZE": 10,
+        "MIN_POP_SIZE": 1,
+        "N_GEN": 10
     },
     "PLOT_CONFIG": {
         "PLOT_X": "Energy Consumption",
diff --git a/src/config.py b/src/config.py
index 7df4e6a..a26b659 100644
--- a/src/config.py
+++ b/src/config.py
@@ -18,12 +18,13 @@ with open(CONFIG_FILE, 'r') as f:
 # Assign configuration variables
 MODEL_NAME = config['MODEL_NAME']
 MODEL_FILE = config['MODEL_FILE']
-SIMULATION_STOP_TIME = config['SIMULATION_STOP_TIME']
-PARAMETERS = config['PARAMETERS']
-OBJECTIVES = config['OBJECTIVES']
-MAXIMIZE = config['MAXIMIZE']
-PARAM_BOUNDS = config['PARAM_BOUNDS']
-PRECISION = config['PRECISION']
+SIMULATION_STOP_TIME = config['SIMULATION_STOP_TIME']  # in seconds
+PRECISION = config['PRECISION']  # Results precision (decimal places)
+PARAMETERS = config['PARAMETERS']  # Parameters to be varied
+OBJECTIVES = config['OBJECTIVES']  # Objectives to be optimize
+OBJECTIVE_NAMES = [obj['name'] for obj in OBJECTIVES]
+MAXIMIZE = [obj['maximize'] for obj in OBJECTIVES]
+PARAM_BOUNDS = config['PARAM_BOUNDS']  # Parameter range
 OPTIMIZATION_CONFIG = config['OPTIMIZATION_CONFIG']
 PLOT_CONFIG = config['PLOT_CONFIG']
 N_JOBS = config['N_JOBS']
@@ -41,16 +42,23 @@ def get_types(param_bounds):
 PARAM_BOUND_VALUES = get_bounds(PARAM_BOUNDS)
 PARAM_TYPES = get_types(PARAM_BOUNDS)
 
-# "PARAMETERS": Parameters to be varied
-# "OBJECTIVES": Objectives to be optimized
-# "MAXIMIZE": Objectives to be maximized
-# "PARAM_BOUNDS": Parameter range
-# "PRECISION": Results precision (decimal places)
+# "OPTIMIZATION_CONFIG": Configuration parameters for optimization
+    # "USE_ADAPTIVE_INSTANCE_SELECTION": Flag to enable or disable adaptive instance selection
+    # "ADAPTIVE_INSTANCE_SELECTION_FREQUENCY": 
+        # Frequency (in generations) at which adaptive instance selection is applied
+        # For example, a value of 5 means adaptive instance selection will be applied every 5 generations
+    # "ALGORITHM_NAME": Optimization algorithm
+    # "POP_SIZE": Initial population size for the optimization algorithm
+    # "MIN_POP_SIZE": 
+        # Minimum population size to maintain diversity and prevent premature convergence
+        # The population size will not be reduced below this value
+    # "N_GEN": Total number of generations (iterations) for the optimization process
+
 # "N_JOBS": Parallel processing
-#    Options: '-1', '1', 'n', 'None'
-#    ====================================================================
-#      -1  = use all available CPU cores
-#       1  = disables parallel processing and runs the tasks sequentially
-#       n  = specifies the exact number of CPU cores to use
-#     None = will run the tasks sequentially, equivalent to '1'
-#    ====================================================================
\ No newline at end of file
+    # Options: '-1', '1', 'n', 'None'
+    # ====================================================================
+    #   -1  = use all available CPU cores
+    #    1  = disables parallel processing and runs the tasks sequentially
+    #    n  = specifies the exact number of CPU cores to use
+    #  None = will run the tasks sequentially, equivalent to '1'
+    # ====================================================================
\ No newline at end of file
diff --git a/src/parallel_computing.py b/src/parallel_computing.py
index f6f38e0..4bd1ff2 100644
--- a/src/parallel_computing.py
+++ b/src/parallel_computing.py
@@ -14,7 +14,7 @@ import numpy as np
 from time import sleep
 from joblib import Parallel, delayed
 from OMPython import OMCSessionZMQ
-from config import MODEL_FILE, MODEL_NAME, SIMULATION_STOP_TIME, PARAMETERS, OBJECTIVES, PARAM_BOUNDS, PARAM_TYPES, MODEL_PATH, PRECISION, OPTIMIZATION_CONFIG, N_JOBS
+from config import MODEL_FILE, MODEL_NAME, SIMULATION_STOP_TIME, PARAMETERS, OBJECTIVE_NAMES, PARAM_BOUNDS, PARAM_TYPES, MODEL_PATH, PRECISION, OPTIMIZATION_CONFIG, N_JOBS
 from adaptive_instance_selection import initial_sampling, evaluate_samples, advanced_clustering_samples, adaptive_select_informative_instances, iterative_refinement
 
 temp_dirs = []  # List to store paths of temporary directories
@@ -77,15 +77,15 @@ def optimization_function(param_values, retries=3, delay=2):
             simulate_result = omc.sendExpression(f"simulate({MODEL_NAME}, stopTime={SIMULATION_STOP_TIME})")
             # Retrieve simulation results
             result_values = {}
-            for objective in OBJECTIVES:
-                value_command = f"val({objective}, {SIMULATION_STOP_TIME})"
+            for objective_name in OBJECTIVE_NAMES:
+                value_command = f"val({objective_name}, {SIMULATION_STOP_TIME})"
                 value = omc.sendExpression(value_command)
-                print(f"Value for {objective} at {SIMULATION_STOP_TIME}: {value}")
+                print(f"Value for {objective_name} at {SIMULATION_STOP_TIME}: {value}")
                 if value is None:
-                    raise ValueError(f"Simulation result returned None for {objective}")
+                    raise ValueError(f"Simulation result returned None for {objective_name}")
                 if not isinstance(value, (float, int)):
-                    raise ValueError(f"Simulation result for {objective} is not in expected format (float or int)")
-                result_values[objective] = round(value, PRECISION)
+                    raise ValueError(f"Simulation result for {objective_name} is not in expected format (float or int)")
+                result_values[objective_name] = round(value, PRECISION)
             
             print(f"Simulation results: {result_values}")
             return list(result_values.values())
-- 
GitLab